SBT使用插件将git依赖项克隆到自定义路径



我正在创建一个聚合SBT项目,该项目依赖于其他几个Git项目。我知道我可以使用RootProject(uri("..."))将它们称为依赖项,SBT将它们克隆到SBT管理的路径中。

但是,我需要将这些下载到一个自定义路径中。这个想法是创建一个工作区,自动下载可以处理的相关Git项目。

我能够创建一个插件,任务是使用sbt git插件克隆git repos:

BundleResolver.scale

def resolve: Def.Initialize[Task[Seq[String]]] = Def.task {
val log = streams.value.log
log.info("starting bundle resolution")
val bundles = WorkspacePlugin.autoImport.workspaceBundles.value
val bundlePaths = bundles.map(x => {
val bundleName = extractBundleName(x)
val localPath = file(".").toPath.toAbsolutePath.getParent.resolveSibling(bundleName)
log.info(s"Cloning bundle : $bundleName")
val (resultCode, outStr, errStr) = runCommand(Seq("git", "clone", x, localPath.toString))
resultCode match {
case 0 =>
log.info(outStr)
log.info(s"cloned $bundleName to path $localPath")
case _ =>
log.err(s"failed to clone $bundleName")
log.err(errStr)
}
localPath.toString
})
bundlePaths
}

WorkspacePlugin.scala

object WorkspacePlugin extends AutoPlugin {
override def trigger = allRequirements
override def requires: Plugins = JvmPlugin && GitPlugin
object autoImport {
// settings
val workspaceBundles   = settingKey[Seq[String]]("Dependency bundles for this Workspace")
val stagingPath        = settingKey[File]("Staging path")
// tasks
val workspaceClean     = taskKey[Unit]("Remove existing Workspace depedencies")
val workspaceImport    = taskKey[Seq[String]]("Download the dependency bundles and setup builds")
}
import autoImport._
override lazy val projectSettings = Seq(
workspaceBundles   := Seq(), // default to no dependencies
stagingPath        := Keys.target.value,
workspaceClean     := BundleResolver.clean.value,
workspaceImport    := BundleResolver.resolve.value,
)
override lazy val buildSettings = Seq()
override lazy val globalSettings = Seq()
}

但是,这不会将克隆的repo作为子项目添加到主项目中。我怎样才能做到这一点?

更新::我有一个扩展RootProject逻辑的想法,这样我就可以创建接受git url的自定义项目,在自定义路径中克隆它,并从中返回一个Project。

object WorkspaceProject {
def apply(uri: URI): Project = {
val bundleName = GitResolver.extractBundleName(uri.toString)
val localPath = file(".").toPath.toAbsolutePath.getParent.resolveSibling(bundleName)
// clone the project
GitResolver.clone(uri, localPath)
Project.apply(bundleName.replaceAll(".", "-"), localPath.toFile)
}
}

我在一个插件项目中声明了这一点,但在我使用它的地方无法访问它。你认为它能工作吗?如何在我的目标项目中访问它?

真不敢相信事情这么简单。

在我的插件项目中,我创建了一个新对象来代替RootProject

object WorkspaceProject {
def apply(uri: URI): RootProject = {
val bundleName = GitResolver.extractBundleName(uri.toString)
val localPath = file(".").toPath.toAbsolutePath.getParent.resolve(bundleName)
if(!localPath.toFile.exists()) {
// clone the project
GitResolver.clone(uri, localPath)
}
RootProject(file(localPath.toString))
}
}

然后这样使用:

build.sbt

lazy val depProject = WorkspaceProject(uri("your-git-repo.git"))
lazy val root = (project in file("."))
.settings(
name := "workspace_1",
).dependsOn(depProject)

最新更新