为什么 sbt 试图拉我的项目间依赖?

Why does sbt try to pull my interproject dependency?

我有一个 build.sbt 的多项目构建,如下所示:

import lmcoursier.CoursierConfiguration
import lmcoursier.definitions.Authentication

ThisBuild / version := "0.1.0-SNAPSHOT"

ThisBuild / scalaVersion := "2.12.12"

val adoMavenUsername = "."
val adoMavenPassword = "ADO_PAT"
val adoRepoIdWithView = "ADO-id"

val adoMavenRepos = Vector(
  MavenRepository(adoRepoIdWithView, s"https://adoMavenHost/adoOrganization/adoProject/_packaging/${adoRepoIdWithView.replace("@", "%40")}/maven/v1")
)

val adoAuthentication =
  Authentication(user = adoMavenUsername, password = adoMavenPassword)
    .withOptional(false)
    .withHttpsOnly(true)
    .withPassOnRedirect(false)

val coursierConfiguration = {
  val initial =
      CoursierConfiguration()
        .withResolvers(adoMavenRepos)
        .withClassifiers(Vector("", "sources"))
        .withHasClassifiers(true)

  adoMavenRepos.foldLeft(initial) {
    case (conf, repo) ⇒
      conf.addRepositoryAuthentication(repo.name, adoAuthentication)
  }
}

lazy val mainSettings = Seq(
  organization := "org.some",
  csrConfiguration := coursierConfiguration,
  updateClassifiers / csrConfiguration := coursierConfiguration
)

lazy val root = (project in file("."))
  .settings(mainSettings: _*)
  .settings(
    name := "sbt-test",
  ).aggregate(core, util)

lazy val core = (project in file("core"))
  .settings(mainSettings: _*)
  .settings(
    name := "core",
  ).dependsOn(util)

lazy val util = (project in file("util"))
  .settings(mainSettings: _*)
  .settings(
    name := "util"
  )

出于某种原因,coursier 尝试在 core/update 任务期间从外部下载 util 包。这不是我想要的,因为它应该作为项目的一部分在内部解决。该包未添加到 libraryDependencies,所以我很困惑为什么它会尝试下载。 上面的示例将失败,因为 Azure DevOps 凭据和 Maven 存储库不正确,但它显示尝试下载 util.

似乎与此有关Github issue

默认的 CoursierConfiguration 构造函数将 interProjectDependencies 属性 设置为空 Vector。要解决此问题,请使用 .withResolvers.

sbtcsrConfiguration taskKey 上手动添加解析器

这是适用于我的问题的解决方案,largely based on this Github comment:

val adoMavenUsername = "."
val adoMavenPassword = "ADO_PAT"
val adoRepoIdWithView = "ADO-id"
val adoMavenHost      = "pkgs.dev.azure.com"

val adoMavenRepos = Vector(
  MavenRepository(adoRepoIdWithView, s"https://$adoMavenHost/adoOrganization/adoProject/_packaging/$adoRepoIdWithView/maven/v1")
)

lazy val mainSettings = Seq(
  organization := "org.some",
  csrConfiguration := {
    val resolvers = csrResolvers.value ++ adoMavenRepos
    val conf = csrConfiguration.value.withResolvers(resolvers.toVector)
    val adoCredentialsOpt = credentials.value.collectFirst { case creds: DirectCredentials if creds.host == adoMavenHost => creds }
    val newConfOpt = adoCredentialsOpt.map { adoCredentials =>
      val auths =
        resolvers
          .collect {
            case repo: MavenRepository if repo.root.startsWith(s"https://$adoMavenHost/") => {
              repo.name ->
                Authentication(adoCredentials.userName, adoCredentials.passwd)
            }
          }
      auths.foldLeft(conf) { case (conf, (repoId, auth)) => conf.addRepositoryAuthentication(repoId, auth) }
    }
    newConfOpt.getOrElse(conf)
},
  updateClassifiers / csrConfiguration := coursierConfiguration
)