将特定目录及其内容添加到通用目标

Posted

技术标签:

【中文标题】将特定目录及其内容添加到通用目标【英文标题】:Add specific directory and its content to Universal target 【发布时间】:2014-02-28 09:14:23 【问题描述】:

我正在为我正在处理的 Scala 项目从 maven 切换到 sbt。我曾经使用 maven 程序集插件,您可以在其中将工作区中的任何目录映射到程序集中的目标目录。我在 sbt-native-package 中没有找到任何等价物,值得为 Universe 类型提供此功能。

我知道通用子目录中存在的所有内容都被复制到包中,它就像一个魅力,但我缺少类似以下 sn-p 的东西。

mappings in Universal += 
  directory("my/local/dir") -> "static/dirInPackage"

我想知道是否已经有办法做到这一点,在这种情况下,我很乐意知道如何做到这一点,如果你愿意,我建议我帮助提交该部分的文档。 如果没有办法进行这种定制,我很乐意在讨论规范后提出一个补丁。

顺便说一句,干得好,您的打包程序运行良好,谢谢!

【问题讨论】:

我不知道 sbt-native-packager 所以...可以在打包之前复制目录吗?只是在提供最终答案之前进行探索。 您好 Jacek,感谢您的评论。我会试一试。当然,这将是我目前正在做的事情的快速解决方案。无论如何,我真的认为这是 sbt-native-packager 长期必须具备的功能。 【参考方案1】:

在与 sbt-native-manager 团队讨论和第一个“被拒绝”的拉取请求之后,这是在 build.sbt 文件中进行此目录映射的方法(请参阅拉取请求 https://github.com/sbt/sbt-native-packager/pull/160,它提供了模式详细文档) :

mappings in Universal <++= (packageBin in Compile, target ) map  (_, target) =>
    val dir = target / "scala-2.10" / "api"
    (dir.***) pair relativeTo(dir.getParentFile)
 

为了减少上述 sn-p 的冗长,有一个问题 (https://github.com/sbt/sbt-native-packager/issues/161) 提出了一种更人类可读的方式来表达这个目录映射:

mappings in Universal ++= allFilesRelativeTo(file(target / "scala-2.10" / "api"))

【讨论】:

【参考方案2】:

您可以在目录方法结果的顶部使用一个简单的映射。

==> 目录方法文档:MappingsHelper.directory

例如: // 将/src/main/resources的内容打包到conf下添加如下内容:

mappings in Universal ++= (directory("src/main/resources").map(t => (t._1, t._2.replace("resources", "conf"))))

【讨论】:

我认为应该是错字... Universal ++= (directory("src/main/resources").map(t => (t._1, t._2) 中的映射.replace("resources", "conf"))))【参考方案3】:

来自https://github.com/sbt/sbt-native-packager

如果您想将其他文件添加到安装目录,只需将它们添加到通用映射:

import com.typesafe.sbt.SbtNativePackager.Universal

mappings in Universal += 
 file("my/local/conffile") -> "conf/my.conf"

【讨论】:

目前,它不会那样复制目录的内容,只会创建一个空目录!我想递归地复制目录及其内容。 我已经提出了一个补丁(在github上拉取请求)允许使用上面的'mappings'sn-p复制目录的内容,看看是否会合并:github.com/sbt/sbt-native-packager/pull/159跨度> 【参考方案4】:

这似乎是对我有用的最简单的例子

res/scripts/中的所有文件解压后放入bin/目录。

// In build.sbt
mappings in Universal <++= (packageBin in Compile) map  jar =>
  val scriptsDir = new java.io.File("res/scripts/")
  scriptsDir.listFiles.toSeq.map  f =>
    f -> ("bin/" + f.getName)
  

如果您选择一个未创建的文件,它将为您创建,例如assets/ 将创建一个包含文件的新assets 文件夹。如果您想使用这种方法将文件包含在其中,则必须创建一个新的Seq,至少我就是这样做的。这是我的例子

assets/
├── scripts
│   └── install_dependencies.sh
└── urbangrizzly.database

以及相应的build.sbt 部分:

mappings in Universal <++= (packageBin in Compile) map  jar =>
    val assetsDir = new java.io.File("assets/")
    val scriptsDir = new java.io.File("assets/scripts")
    assetsDir.listFiles.toSeq.map  files =>
        files -> ("assets/" + files.getName)
     ++ scriptsDir.listFiles.toSeq.map  files =>
        files -> ("assets/scripts/" + files.getName)
    

如果您需要更多,只需继续使用 ++ 运算符来连接列表

【讨论】:

以上是关于将特定目录及其内容添加到通用目标的主要内容,如果未能解决你的问题,请参考以下文章

提取 tar 存档,不包括特定文件夹及其内容

如何使用 node.js 和 Promises 将特定行的行添加到文件的内容

将一个目录及其所有内容批量复制到另一个目录

使用 AutoLayout 调整 UICollectionViewCell 及其内容的大小

mac osX packageMaker:如何将目标设置为用户主目录?

sed 在匹配行前后添加内容