如何使用不同的配置为单个模块创建 tarball 和 zip?
How do I create a tarball and a zip for a single module using distinct configurations?
我有一个多项目构建,其中包含一个特别混乱的模块,其中包含几个 mainClasses。我想为这个混乱的模块创建几个分发包,每个分发包使用不同的文件集并使用不同的格式。想法?
参见:https://github.com/sbt/sbt-native-packager/issues/746
重要提示: 这是一个 "answer in progress"。 它还不能工作!
这是一个如何实现这一目标的示例。
基本思路是我们为不同的包生成添加配置。每个配置都会告诉哪些文件将出现在包中。 这没有按预期工作。请参阅代码后的评论。
lazy val BuilderRS = sbt.config("BuilderRS").extend(Compile,Universal)
lazy val BuilderRV = sbt.config("BuilderRV").extend(Compile,Universal)
addCommandAlias("buildRS", "MessyModule/BuilderRS:packageZipTarball")
addCommandAlias("buildRV", "MessyModule/BuilderRV:packageBin") // ideally should be named packageZip
lazy val Star5FunctionalTestSupport =
project
.in(file("MessyModule"))
.enablePlugins(JavaAppPackaging)
.settings((buildSettings): _*)
.configs(Universal,BuilderRS,BuilderRV)
.settings(inConfig(BuilderRS)(
Defaults.configSettings ++ JavaAppPackaging.projectSettings ++
Seq(
executableScriptName := "rs",
mappings in Universal :=
(mappings in Universal).value
.filter {
case (file, name) => ! file.getAbsolutePath.endsWith("/bin/rv")
},
topLevelDirectory in Universal :=
Some(
"ftreports-" +
new java.text.SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new java.util.Date())),
mainClass in ThisScope := Option(mainClassRS))): _*)
//TODO: SEE COMMENTS BELOW ===============================================
// .settings(inConfig(BuilderRV)(
// Defaults.configSettings ++ JavaAppPackaging.projectSettings ++
// Seq(
// packageBin <<= packageBin in Universal,
// executableScriptName := "rv",
// mappings in ThisScope :=
// (mappings in Universal).value
// .filter {
// case (file, name) => ! file.getAbsolutePath.endsWith("/bin/rs")
// },
// topLevelDirectory in Universal :=
// Some(
// "ftviewer-" +
// new java.text.SimpleDateFormat("yyyyMMdd_HHmmss")
// .format(new java.util.Date())),
// mainClass in ThisScope := Option(mainClassRV))): _*)
现在观察评论中的配置BuilderRV
。
它与配置 BuilderRS
基本相同,只是我们现在在 bin
文件夹中部署不同的 shell 脚本。还有一些其他的小差异,但与这个论点无关。有两个问题:
sbt-native-packager
插件总是选择 mappings in Universal
。这并不理想。它应该在概念上选择 mappings in ThisScope
.
由于 sbt-native-packager
插件总是选择 mappings in Universal
,我必须在每个配置中重新定义 mappings in Universal
。这是一个问题,因为 mappings in Universal
在所有配置中都被定义为自身的函数:结果是每次我们在每个配置中重新定义它时,我们最终将逻辑链接到 mapppings in Universal
。这在这个例子中造成了麻烦,特别是因为配置 BuilderRV
(第二个)不仅会执行它的过滤器,还会执行 BuilderRS
(第一个)中定义的过滤器,这不是我想要的想要.
这是发布了相同问题的 sbt-nativer-packager issue tracker 的答案。
我也在 gitter 聊天中添加这个:
我刚到这个聊天室,我对 sbt-native-packager 的了解几乎为零......但无论如何......在我看来 JavaAppPackaging
和其他原型实际上应该是配置从通用扩展。在这种情况下,我将创建自己的扩展自 JavaAppPackaging
的配置,并根据我的需要调整必要的位。最后,如果插件只选择 mappings in ThisScope
... 它会选择我自己的范围,而不是 JavaAppPackaging
... 也不会选择 Universal。
那么,让我们一一过一遍。
sbt-native-packager 插件总是在 Universal 中选择映射。这并不理想。它应该在概念上选择 mappings in ThisScope
SBT native packager 提供了两类 AutoPlugins:FormatPlugins 和 ArchetypePlugins。 FormatPlugins 提供了一种新的包格式,例如UniversalPlugin(zip、tarball)或 DebianPlugins (.deb)。这些插件在彼此之上构建时形成了一个层次结构:
SbtNativePackager
+
|
|
+-------+ Universal +--------+
| |
| + |
| | |
+ + +
Docker +-+ Linux +-+ Windows
| |
| |
+ +
Debian RPM
定义 file -> targetpath
关系的映射是用这种模式继承的
mappings in ParentFormatPluginScope := (mappings in FormatPluginScope).value
所以 docker 看起来像这样
mappings in Docker := (mappings in Universal).value
linux 格式插件使用专门的映射来保留文件权限,但基本相同。
由于 sbt-native-packager
插件总是在 Universal 中选择映射,我必须在我的每个配置中重新定义 Universal 中的映射
是的。如果你想定义自己的范围并继承映射并更改它们,你必须这样做,就像所有其他打包插件一样。我建议将此代码放入项目文件夹中的自定义 AutoPlugins。
例如(未测试,导入可能丢失)
import sbt._
object BuilderRSPlugin extends AutoPlugin {
def requires = JavaAppPackaging
object autoImport {
val BuilderRS = config("builderrs") extend Universal
}
import autoImport._
override lazy val projectSettings = Seq(
mappings in BuilderRS := (mappings in Universal).value
)
}
在我看来,JavaAppPackaging 和其他原型实际上应该是从 Universal 扩展而来的配置
JavaAppPackaging 是一个原型,这意味着这个插件没有带来任何新的打包格式,因此没有新的范围。它会配置所有可能的打包格式并启用它们。
您通过指定范围打包东西:
universal:packageBin
debian:packageBin
windows:packageBin
因此,如果您需要自定义输出格式,您将在相关范围内执行此操作。
mappings in Docker := (mappings in Docker).value.filter( /* what ever you want to filter */)
我有一个多项目构建,其中包含一个特别混乱的模块,其中包含几个 mainClasses。我想为这个混乱的模块创建几个分发包,每个分发包使用不同的文件集并使用不同的格式。想法?
参见:https://github.com/sbt/sbt-native-packager/issues/746
重要提示: 这是一个 "answer in progress"。 它还不能工作!
这是一个如何实现这一目标的示例。
基本思路是我们为不同的包生成添加配置。每个配置都会告诉哪些文件将出现在包中。 这没有按预期工作。请参阅代码后的评论。
lazy val BuilderRS = sbt.config("BuilderRS").extend(Compile,Universal)
lazy val BuilderRV = sbt.config("BuilderRV").extend(Compile,Universal)
addCommandAlias("buildRS", "MessyModule/BuilderRS:packageZipTarball")
addCommandAlias("buildRV", "MessyModule/BuilderRV:packageBin") // ideally should be named packageZip
lazy val Star5FunctionalTestSupport =
project
.in(file("MessyModule"))
.enablePlugins(JavaAppPackaging)
.settings((buildSettings): _*)
.configs(Universal,BuilderRS,BuilderRV)
.settings(inConfig(BuilderRS)(
Defaults.configSettings ++ JavaAppPackaging.projectSettings ++
Seq(
executableScriptName := "rs",
mappings in Universal :=
(mappings in Universal).value
.filter {
case (file, name) => ! file.getAbsolutePath.endsWith("/bin/rv")
},
topLevelDirectory in Universal :=
Some(
"ftreports-" +
new java.text.SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new java.util.Date())),
mainClass in ThisScope := Option(mainClassRS))): _*)
//TODO: SEE COMMENTS BELOW ===============================================
// .settings(inConfig(BuilderRV)(
// Defaults.configSettings ++ JavaAppPackaging.projectSettings ++
// Seq(
// packageBin <<= packageBin in Universal,
// executableScriptName := "rv",
// mappings in ThisScope :=
// (mappings in Universal).value
// .filter {
// case (file, name) => ! file.getAbsolutePath.endsWith("/bin/rs")
// },
// topLevelDirectory in Universal :=
// Some(
// "ftviewer-" +
// new java.text.SimpleDateFormat("yyyyMMdd_HHmmss")
// .format(new java.util.Date())),
// mainClass in ThisScope := Option(mainClassRV))): _*)
现在观察评论中的配置BuilderRV
。
它与配置 BuilderRS
基本相同,只是我们现在在 bin
文件夹中部署不同的 shell 脚本。还有一些其他的小差异,但与这个论点无关。有两个问题:
sbt-native-packager
插件总是选择mappings in Universal
。这并不理想。它应该在概念上选择mappings in ThisScope
.由于
sbt-native-packager
插件总是选择mappings in Universal
,我必须在每个配置中重新定义mappings in Universal
。这是一个问题,因为mappings in Universal
在所有配置中都被定义为自身的函数:结果是每次我们在每个配置中重新定义它时,我们最终将逻辑链接到mapppings in Universal
。这在这个例子中造成了麻烦,特别是因为配置BuilderRV
(第二个)不仅会执行它的过滤器,还会执行BuilderRS
(第一个)中定义的过滤器,这不是我想要的想要.
这是发布了相同问题的 sbt-nativer-packager issue tracker 的答案。
我也在 gitter 聊天中添加这个:
我刚到这个聊天室,我对 sbt-native-packager 的了解几乎为零......但无论如何......在我看来 JavaAppPackaging
和其他原型实际上应该是配置从通用扩展。在这种情况下,我将创建自己的扩展自 JavaAppPackaging
的配置,并根据我的需要调整必要的位。最后,如果插件只选择 mappings in ThisScope
... 它会选择我自己的范围,而不是 JavaAppPackaging
... 也不会选择 Universal。
那么,让我们一一过一遍。
sbt-native-packager 插件总是在 Universal 中选择映射。这并不理想。它应该在概念上选择 mappings in ThisScope
SBT native packager 提供了两类 AutoPlugins:FormatPlugins 和 ArchetypePlugins。 FormatPlugins 提供了一种新的包格式,例如UniversalPlugin(zip、tarball)或 DebianPlugins (.deb)。这些插件在彼此之上构建时形成了一个层次结构:
SbtNativePackager
+
|
|
+-------+ Universal +--------+
| |
| + |
| | |
+ + +
Docker +-+ Linux +-+ Windows
| |
| |
+ +
Debian RPM
定义 file -> targetpath
关系的映射是用这种模式继承的
mappings in ParentFormatPluginScope := (mappings in FormatPluginScope).value
所以 docker 看起来像这样
mappings in Docker := (mappings in Universal).value
linux 格式插件使用专门的映射来保留文件权限,但基本相同。
由于 sbt-native-packager
插件总是在 Universal 中选择映射,我必须在我的每个配置中重新定义 Universal 中的映射
是的。如果你想定义自己的范围并继承映射并更改它们,你必须这样做,就像所有其他打包插件一样。我建议将此代码放入项目文件夹中的自定义 AutoPlugins。
例如(未测试,导入可能丢失)
import sbt._
object BuilderRSPlugin extends AutoPlugin {
def requires = JavaAppPackaging
object autoImport {
val BuilderRS = config("builderrs") extend Universal
}
import autoImport._
override lazy val projectSettings = Seq(
mappings in BuilderRS := (mappings in Universal).value
)
}
在我看来,JavaAppPackaging 和其他原型实际上应该是从 Universal 扩展而来的配置 JavaAppPackaging 是一个原型,这意味着这个插件没有带来任何新的打包格式,因此没有新的范围。它会配置所有可能的打包格式并启用它们。
您通过指定范围打包东西:
universal:packageBin
debian:packageBin
windows:packageBin
因此,如果您需要自定义输出格式,您将在相关范围内执行此操作。
mappings in Docker := (mappings in Docker).value.filter( /* what ever you want to filter */)