在 SBT 中为 sbt-native-packager 的 packageMappings 构建路径

Posted

技术标签:

【中文标题】在 SBT 中为 sbt-native-packager 的 packageMappings 构建路径【英文标题】:Building paths in SBT for the packageMappings of the sbt-native-packager 【发布时间】:2013-12-24 03:48:48 【问题描述】:

我对 SBT 非常陌生,需要为我的一个项目创建一个 RPM 包。 RPM 仅包含 1 个文件,这是一个由 sbt-onejar 插件创建的 one-jar)。我想使用 sbt-native-packager 插件并在 /project 目录下创建了一个 Packagin.scala 文件,如下所示:

object Packaging 
  val settings: Seq[Setting[_]] = packagerSettings ++ deploymentSettings ++ mapGenericFilesToLinux ++ Seq(

    maintainer := "Team",
    packageSummary := "Summary",
    packageDescription := """Description""",

    mappings in Universal += 
      file("target/scala-2.10/projectname_2.10-0.1-one-jar.jar") -> "/opt/projectname/projectname-0.1.jar"
    ,

    linuxPackageMappings in Rpm <+= (baseDirectory) map  _:File =>
      (packageMapping(file("target/scala-2.10/projectname_2.10-0.1-one-jar.jar") -> "/opt/projectname/projectname-0.1.jar")
        withUser "someusr" withGroup "somegroup" withPerms "0755")
    ,

    name in Rpm := "projectname",
    version in Rpm <<= version apply  sv => sv split "[^\\d]" filterNot (_.isEmpty) mkString "." ,
    rpmRelease := "1",
    rpmVendor := "Vendor",
    rpmUrl := Some("url"),
    rpmGroup := Some("group"),
    rpmLicense := Some("BSD")
  )

1) 我不想硬编码文件名。我需要一种方法来使用现有的 SettingKey,而不是 "target/scala-2.10/projectname_2.10-0.1-one-jar.jar",即 target + "scala-" + scalaVersion + "/" + name + "_" + scalaVersion + "-" + version + "-one-jar.jar" - 你怎么做=

2) 对于值rpmRelease := "1",我想使用系统属性,即在 Maven 中我会使用$rpm.buildNumber,这在 SBT 中如何工作?

3) 关于 sbt-native-packager 插件,有什么我应该做的更好的吗?

【问题讨论】:

【参考方案1】:

1) 您应该始终在 sbt 中使用 task output 而不是原始文件系统查找。因为 sbt 具有并行执行功能,如果您不明确依赖任务的输出,则无法保证在运行任务之前会创建文件。

在这种情况下,您希望将包映射行更改为如下所示:

mappings in Universal += 
  oneJar.value -> "/opt/projectname/projectname-0.1.jar"
,

oneJar 键在 onejar plugin 中定义。

2) Sbt 只是使用 scala 作为构建语言,因此您可以类似地获取系统属性(但也请提供默认值):

rpmRelease := Option(sys.props("rpm.buildNumber")) getOrElse "1"

3) 现在,您正在定义一个通用包用不同的用户在 Rpm 中重新定义同一个文件。 mapGenericFilesToLinux 设置仍然缺少一些自定义,但如果您不创建通用发行版,您应该能够删除这些设置,而是直接配置您的 linux 包:

linuxPackageMappings in Rpm <+= (oneJar) map  jar:File =>
  (packageMapping(jar -> "/opt/projectname/projectname-0.1.jar")
    withUser "someusr" withGroup "somegroup" withPerms "0755")
,

【讨论】:

嗯,至于rpmRelease,我意识到我们的构建服务器 Bamboo 使用环境变量。所以我尝试在 project/Packaging.scala 中将其更改为rpmRelease := Option(sys.env("rpm.buildNumber")) getOrElse "1",但由于某种原因,我总是返回“1”。当我在 build.sbt 中访问 sys.env("rpm.buildNumber") 时,它可以工作。由于某种原因,环境变量似乎没有传播到 Packaging.scala 中。 嗯,应该是这样。设置排序很重要。您是否在其他地方有rpmRelease := ...,或者您是否在您自己的rpmRelease 设置之后设置本机打包程序设置?同样project/*.scala 设置在build.sbt 设置之前被拉取。

以上是关于在 SBT 中为 sbt-native-packager 的 packageMappings 构建路径的主要内容,如果未能解决你的问题,请参考以下文章

如何在sbt shell中为所有子项目设置一个值?

我可以在 build.sbt 中为 spark 3 和 scala 2.12 获取 neo4j 的命令(依赖项)吗?

为啥我的 sbt 项目依赖项不起作用? (坚持尝试远程获取它)

没有完整 sbt 构建的 IDEA Play 2.4 junit 测试

如何在 intellij 中为播放框架应用程序运行单元测试

在“sbt-native-packager”脚本中使用除“sbt run”之外的其他 sbt 命令。例如:“sbt flywayMigrate”