【问题标题】:Include generated resources in a jar (SBT)在 jar 中包含生成的资源 (SBT)
【发布时间】:2014-10-08 05:21:13
【问题描述】:

我一直在编写一个 SBT 插件,它可以将资源生成到 resource_managed 中。我现在希望将这些生成的资源作为 SBT 文档详细信息包含在生成的 jar 中:

Generating resources:

默认情况下,生成的资源不包含在打包的源工件中。为此,请像添加其他映射一样添加它们。请参阅将文件添加到包中

我已阅读文档,但老实说,我不知道该怎么做。谁能解释一下或将我指向另一个这样做的项目,以便我了解他们是如何做到的?

【问题讨论】:

    标签: scala jar sbt


    【解决方案1】:

    首先澄清一下,它们包含在包含已编译类的 jar 中。它们不包含在包含源的 jar 中。

    默认情况下,生成的资源不包含在打包中 源工件

    对于packageBin,应该已经包含了生成的文件——只要确保从生成器方法返回所有生成的文件。假设您想将它们打包到源工件中,这就是您必须做的。

    假设您有一个生成器来生成属性文件。

    lazy val generatePropertiesTask = Def.task {
      val file = (resourceManaged in Compile).value / "stack-overflow" / "res.properties"
      val contents = s"name=${name.value}\nversion=${version.value}"
      IO.write(file, contents)
      Seq(file)
    }
    
    resourceGenerators in Compile += generatePropertiesTask.taskValue
    

    要将其包含在生成的源代码中,您必须告诉 sbt 必须将 res.properties 复制到生成的源代码工件中的位置。生成打包源的任务称为packageSrc,因此您必须设置映射scoped to that task

    mappings in (Compile, packageSrc) += {
       ((resourceManaged in Compile).value / "stack-overflow" / "res.properties") -> "path/in/jar/res.properties"
    }
    

    因为您的生成器可以生成许多任务,而手动映射每个任务将是一项繁琐的任务,所以 sbt 为您提供了一个 utility 来一次映射多个路径。

    mappings in (Compile, packageSrc) ++= {
      val allGeneratedFiles = ((resourceManaged in Compile).value ** "*") filter { _.isFile }
      allGeneratedFiles.get pair relativeTo((resourceManaged in Compile).value)
    }
    

    第一行使用path finders查找所有生成的文件,第二行将它们映射到目标jar中的路径。

    【讨论】:

    • 那么(File, String) 映射中的字符串是jar 根的相对路径吗?嗯不错。我在 github 上找到了一个示例,其中一个插件使用了生成器任务并将输出通过管道传输到映射中,例如:mappings in Universal <++= myResourceGenerator.value pair relativeTo((resourceManaged in Compile).value)(我认为是 Play sbt-native-package 文档)
    • @MichaelAllen 是的,它们是相对于 jar 的根目录的。您评论的第二部分也是正确的。你可以这样做。 Sbt 将在单次运行中最多评估一次任务。
    • 如果我有多个项目依赖于具有生成资源的基础项目,则资源会生成多次。并且由于映射,它尝试将所有生成的文件复制到同一个地方,这(因为复制与生成竞争)失败​​了。我怎样才能使生成只发生一次?
    • @JamesCaccese 如果您的基础项目为子项目生成资源,它应该将这些资源生成到每个子项目的resourceManaged 位置(即在它们的目标文件夹内)。可能您的 mappings 指令配置错误。我会尝试在每个子项目而不是基础中定义映射指令,以便resourceManaged 属性引用子项目resourceManaged
    • @JamesCaccese 更好的方法是将 resourceGeneration 提取到 SBT 插件中并在每个子项目中使用它。这样,上下文将是子项目,因此resourceManaged 将引用子项目resourceManaged。使用我写的这个答案github.com/michaeldfallen/sbt-mustache,它可以作为解决问题的指南。
    猜你喜欢
    • 2017-10-17
    • 1970-01-01
    • 2013-01-20
    • 2011-01-22
    • 2016-03-08
    • 2010-10-09
    • 2013-07-07
    • 1970-01-01
    相关资源
    最近更新 更多