SBT:排除资源子目录

Ben*_*Lee 5 scala gradle sbt

我的大部分 Scala 项目都在使用 Gradle,但我想评估 SBT 作为替代品的适用性。我在 Gradle 中所做的一件事是从最终构建中排除某个资源目录(例如,使用 CoffeeScript 编写将作为最终资源包含在内的 JavaScript 文件)。

在 Gradle 中,我会这样做:

sourceSets {
    main {
        resources {
            exclude 'com/example/export/dev' // exclude development resources
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这将从com.example.export.dev最终构建中排除资源包包。

我将如何在 SBT 中做同样的事情?我试过了

unmanagedResourceDirectories in Compile -= (resourceDirectory in Compile).value / "com/example/export/dev"
Run Code Online (Sandbox Code Playgroud)

但这没有任何作用(我明白为什么,但这并没有真正的帮助)。SBT 网站上的文档只讨论了排除文件模式(在Classpaths、sources 和 resources 中)。

作为更具描述性的图像,假设我们有以下资源目录结构:

com
\---example
     \---export
         \---dev
         \---something
Run Code Online (Sandbox Code Playgroud)

在最终输出中,我想要:

com
\---example
    \---export
        \---something
Run Code Online (Sandbox Code Playgroud)

mar*_*ios 5

SBT 的思维方式有点不同,我知道一开始可能很难。

在您的示例中,您需要修改生成资源文件的任务(或选择文件夹以查找资源文件的任务)。

这是我如何仅选择以字符“a”开头的资源文件的示例。

(unmanagedResources in Compile) := (unmanagedResources in Compile).value.filter(_.getName.startsWith("a"))
Run Code Online (Sandbox Code Playgroud)

同样,如果你想修改资源文件的整个目录,你可以这样做:

(unmanagedResourceDirectories in Compile) := (unmanagedResourceDirectories in Compile).value.filter(_.getName.startsWith("a"))
Run Code Online (Sandbox Code Playgroud)

显然,我这里的过滤器只是一个例子,您可以使用 Scala 支持的任何复杂模式。

SBT 的好处在于它是交互式的。因此,您只需在项目的 REPL 中键入以下内容即可检查任务的结果:

> show compile:unmanagedResources
> show compile: unmanagedResourceDirectories
Run Code Online (Sandbox Code Playgroud)

要检查任务的所有依赖项,请从 REPL 执行此操作:

> inspect tree compile:unmanagedResources
Run Code Online (Sandbox Code Playgroud)

假设:

SBT 使用标准的Maven 构建目录布局知道在哪里可以找到所有资源。上述解决方案假设所有资源都在该/resources目录下。然后,您可以使用 Scala 代码访问它们getClass.getResource("/folderInsideResources/file.txt")

以下是具有资源的混合 Java/Scala 项目的示例目录布局:

 .
    ??? main
    ?   ??? java
    ?   ?   ??? com
    ?   ?       ??? a
    ?   ?           ??? b
    ?   ?               ??? Hello.java
    ?   ??? resources
    ?   ?   ??? a.tx
    ?   ?   ??? b.tx
    ?   ??? scala
    ?       ??? com
    ?           ??? a
    ?               ??? b
    ?                   ??? ScalaHello.scala
    ??? test
        ??? resources
        ??? scala
            ??? com
                ??? a
                    ??? b
                        ??? ScalaHello.scala
Run Code Online (Sandbox Code Playgroud)

要访问资源文件,只需使用:

 getClass.getResource("/a.txt")
 getClass.getResource("/b.txt")
Run Code Online (Sandbox Code Playgroud)


Ale*_*nov 5

来自https://github.com/sbt/sbt-jshint/issues/14

excludeFilter in unmanagedResources := {
  val public = ((resourceDirectory in Compile).value / "com" / "example" / "export" / "dev").getCanonicalPath
  new SimpleFileFilter(_.getCanonicalPath startsWith public)
}
Run Code Online (Sandbox Code Playgroud)

  • 这非常有效!诚然不理想,因为我真的更喜欢简单地在 excludeFilter 上声明一个路径(类似于 unmanagedResources 中的`excludeFilter := "com/example/export/dev/"`)。所以情况确实是没有直接的方法可以从编译中排除目录。令人失望的是,考虑到 SBT 在我投入的大多数其他事情上做得很好,而且目录排除似乎是您想要轻松表达的事情之一。 (5认同)