我有一个半复杂的SBT流程,因为我需要根据需要的构建类型有条件地包含不同的配置文件。我通过子项目解决了这个问题:
lazy val app = project
.in(file("."))
.enablePlugins(JavaAppPackaging)
.settings(
commonSettings // Seq() of settings to be shared between projects
,sourceGenerators in Compile += (avroScalaGenerateSpecific in Compile).taskValue
,(avroSpecificSourceDirectory in Compile) := new java.io.File("src/main/resources/com/coolCompany/folderName/avro")
)
lazy val localPackage = project
.in(file("build/local"))
.enablePlugins(JavaAppPackaging)
.settings(
organization := "com.coolCompany",
version := "0.1.0-SNAPSHOT",
scalaVersion := "2.11.8",
name := "my-neat-project",
scalacOptions := compilerOptions, //Seq() of compiler flags
sourceDirectory in Compile := (sourceDirectory in (app, Compile)).value,
mappings in Universal += {
((sourceDirectory in Compile).value / "../../conf/local/config.properties") -> "lib/config.properties"
}
)
.dependsOn(app)
val buildNumber = inputKey[String]("The version number of the artifact.")
lazy val deployedPackage = project
.in(file("build/deployed"))
.enablePlugins(JavaAppPackaging)
.settings(
organization := "com.coolCompany",
buildNumber := {
val args : Seq[String] = spaceDelimited("<arg>").parsed
println(s"Input version number is ${args.head}")
args.head
},
version := buildNumber.inputTaskValue + "-SNAPSHOT", //"0.1.0-SNAPSHOT",
scalaVersion := "2.11.8",
name := "my-cool-project",
scalacOptions := compilerOptions,
sourceDirectory in Compile := (sourceDirectory in (app, Compile)).value,
mappings in Universal += {
((sourceDirectory in Compile).value / "../../conf/deployed/config.properties") -> "lib/config.properties"
}
)
.dependsOn(app)
现在我需要允许在构建时通过构建工具传递版本号。您可以看到我已尝试执行的操作:我创建了一个名为inputKey
的{{1}}任务,然后尝试在buildNumber
定义中访问该任务。我可以运行version :=
任务本身就好了:
buildNumber
所以我至少可以验证输入任务是否按预期工作。问题是,在运行我想要的实际$ sbt 'deployedPackage/buildNumber 0.1.2'
Input version number is 0.1.2
步骤时,我无法弄清楚我是如何实际获得该输入值的。
我尝试了以下内容:
packageBin
所以它显然不明白如何处理版本号。我尝试了很多不同的输入变体,例如$ sbt 'deployedPackage/universal:packageBin 0.1.2'
[error] Expected key
[error] Expected '::'
[error] Expected end of input.
[error] deployedPackage/universal:packageBin 0.1.2
,[...]packageBin buildNumber::0.1.2
或[...]packageBin -- buildNumber 0.1.2
,所有这些变量都会出现错误或类似内容,表明它不明白我是什么我试图传入。
现在,最终,这些错误是有道理的。 [...]packageBin -- 0.1.2
,任务,知道如何处理命令行值,但buildNumber
没有。如何设置此任务或这些任务以允许传递版本号?
我已经看过this question,但答案链接到一个sbt插件,似乎比我想做的事情多做了100多件事,包括我需要找到一种明确禁用的方法。我只希望版本号能够传入&amp;在神器中使用。
编辑/更新:我通过切换回Maven解决了这个问题。
答案 0 :(得分:1)
我认为您对sbt设置的工作方式感到有点困惑。设置在sbt加载时设置,然后在重新加载会话之前无法更改。因此,无论你设置什么版本,它都将被修复,它不能是动态的,取决于用户输入或任务(对比度是动态的,每次调用时都会评估)。
这是事实。但是,您仍然可以首先计算 SettingKey
值。我们使用环境变量来设置我们的构建版本。
version := "1." + sys.env.getOrElse("BUILD_NUMBER", "0-SNAPSHOT")
<强>解释强>
1.
是主要版本。根据需要手动增加BUILD_NUMBER
是一个环境变量,通常由CI设置,例如詹金斯。如果未设置,请使用0-SNAPSHOT
作为版本后缀。我们在公司中使用它来进行持续部署管道。
希望有所帮助, 缪奇
答案 1 :(得分:0)
我认为你对sbt设置的工作方式有点困惑。设置在sbt加载时设置,然后在重新加载会话之前无法更改。因此,无论你设置version
,它都将被修复,它不能是动态的,取决于用户输入或任务(对比度是动态的,每次调用时都会评估)。
您有一个输入任务buildNumber
,它取决于用户输入,并在每次调用时进行评估:
> show buildNumber 123
Input version number is 123
[info] 123
[success] Total time: 0 s, completed Dec 24, 2017 3:41:43 PM
> show buildNumber 456
Input version number is 456
[info] 456
[success] Total time: 0 s, completed Dec 24, 2017 3:41:45 PM
它会返回您提供的任何内容,并且不执行任何操作(除println
之外)。更重要的是,无论如何都不会影响version
设置(甚至在理论上也是如此)。
当您使用buildNumber.inputTaskValue
时,您指的是输入任务本身,而不是其值(由于它取决于用户输入,因此未知)。您可以通过查看version
设置值
> show version
[info] sbt.InputTask@6c996907-SNAPSHOT
所以这绝对不是你想要的。
我建议您一般性地检查一下您的方法并阅读更多的sbt文档,例如关于Task graph(以及整个入门章节)。
如果您仍然需要根据输入在sbt load上设置版本,则可以使用command进行设置。它看起来像这样:
commands += Command.single("pkg") { (state0, buildNumber) =>
val state1 = Project.extract(state0).append(Seq(version := buildNumber + "-SNAPSHOT"), state0)
val (state2, result) = Project.extract(state1).runTask(packageBin in (deployedPackage, universal), state1)
state2
}
但你应该非常小心手动处理状态。我再次建议您检查一下您的方法,并将其更改为更具惯用性的方法。
答案 2 :(得分:0)
我建议您只在调用需要该版本的任务之前为deployPackage项目设置版本设置。这是设置版本的最简单方法,并且由于设置键具有范围,因此应按预期工作。
我在这个大型多模块项目中使用了类似的东西,其中一个项目的版本历史比其他项目多。