确定Git依赖关系的本地目录

时间:2017-04-06 00:23:03

标签: scala sbt

我正在使用ssh URI引用将远程git存储库视为我build.sbt中的项目引用,就像这样(使用ssh允许我访问私有存储库):

lazy val dep = RootProject(uri("ssh://git@github.com/..."))

lazy val root = project(file.in(".").dependsOn(dep)

如何在构建文件的任务或命令中确定SBT存储项目的本地目录?

2 个答案:

答案 0 :(得分:1)

根据How do I get SBT staging directory at build time?发现的信息,我能够提出一个有效的解决方案。 (SBT 0.13.13)

您需要定义一个任务(或命令),以便State可用,因为这样可以检索staging`目录:

lazy val printRepos = taskKey[Unit]("Print path to dependencies that are hosted in git repositories.")
printRepos := {
  import sbt.BuildPaths._

  val s = state.value
  val staging = getStagingDirectory(s, getGlobalBase(s))
  // root is a reference to your top-level project, which has
  // git-hosted dependencies.

  val repos = gitRepos(staging, root.dependencies)
  println("${repos.mkString(",")}")
}

gitRepos方法(下面)获取登台目录和依赖关系,过滤那些看起来像git repos的方法,并返回一系列元组配对项目,原始URI和持有源的本地路径。

用于在本地存储源的实际目录由Resolvers.git返回,这需要ResolveInfo个对象。 gitRepos构建格式错误的ResolveInfo以重新使用Resolvers.git,但我认为您无法解决这个问题:

def gitRepos(staging: File, cps: Seq[ClasspathDep[ProjectReference]]): Seq[(ProjectReference, URI, File)] = {
  import sbt.BuildLoader._
  import sbt.RichURI._

  val x = cps.flatMap(cp => Reference.uri(cp.project).map(uri => (cp.project, uri)))
  x.flatMap({ case (project, uri) => {
    // Stolen from sbt.RetrieveUnit
    if(uri.getScheme == "git" || uri.withoutMarkerScheme.getPath.endsWith(".git")) {
      val y = Resolvers.git(new ResolveInfo(uri, staging, null, null))
      y.map(path => (project, uri, path()))
    }
    else
      None
  }})
}

由于getRepos重新使用Resolvers.gitprintRepos将始终打印sbt将用于存储项目引用的确切目录。

答案 1 :(得分:1)

信息隐藏在构建单元的localBase字段中。您可以创建一个任务来获取当前项目:

val localBase: TaskKey[File] = taskKey[File]("the local base of project")
localBase := {
  val extracted = Project.extract(state.value)
  extracted.currentUnit.localBase
}

对于您添加为ProjectRef的项目,需要将其添加为该项目的设置:

localBase in yourProjectRef := ...

只需获取所有当地基地的地图:

val allYourBase = taskKey[Map[URI,File]]("project bases")
allYourBase := {
  val extracted = Project extract state.value
  extracted.structure.units.map { case (uri, unit) => (uri,unit.localBase)}
}