Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SBT: Exclude resource subdirectory

Tags:

gradle

scala

sbt

I've been using Gradle for most of my Scala projects, but I want to evaluate the suitability of SBT as a replacement. One of the things I've done in Gradle is to exclude a certain resource directory from the final build (for example, using CoffeeScript to write JavaScript files that will be included as final resources).

In Gradle, I'd do this by:

sourceSets {
    main {
        resources {
            exclude 'com/example/export/dev' // exclude development resources
        }
    }
}

And this would exclude the resource package com.example.export.dev package from the final build.

How would I do the same in SBT? I've tried

unmanagedResourceDirectories in Compile -= (resourceDirectory in Compile).value / "com/example/export/dev"

but that doesn't do a thing (I understand why, but that doesn't really help). And the documentation on the SBT web site only talks about excluding file patterns (at Classpaths, sources, and resources).

As a more descriptive image, say we have the following resource directory structure:

com
\---example
     \---export
         \---dev
         \---something

In the final output, I want:

com
\---example
    \---export
        \---something
like image 402
Benedict Lee Avatar asked Oct 24 '15 12:10

Benedict Lee


2 Answers

From 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)
}
like image 196
Alexey Romanov Avatar answered Oct 06 '22 01:10

Alexey Romanov


The way to think in SBT is a bit different and I know it can be hard at first.

In your example, you need to modify the task that generate the resource files (or the task that selects the folders to look for resource files).

Here is an example of how I can select only the resource files that start with character 'a'.

(unmanagedResources in Compile) := (unmanagedResources in Compile).value.filter(_.getName.startsWith("a"))

Similarly if you want to modify the entire directory of the resource files you can do that like this:

(unmanagedResourceDirectories in Compile) := (unmanagedResourceDirectories in Compile).value.filter(_.getName.startsWith("a"))

Obviously my filters here are just and example, you can have any complex pattern that Scala supports.

The nice thing about SBT is that it's interactive. So you can check the result of your task by simply typing these at the REPL of your project:

> show compile:unmanagedResources
> show compile: unmanagedResourceDirectories

To check all the dependencies to the task do this from the REPL:

> inspect tree compile:unmanagedResources

Assumption:

SBT knows where to find all resources using the standard maven build directory layout. The above solution assumes that all resources are under the /resources directory. You can then access them from your Scala code using getClass.getResource("/folderInsideResources/file.txt").

Here is a sample directory layout for a mixed Java/Scala project with resources:

 .
    ├── 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

To access the resource file just use:

 getClass.getResource("/a.txt")
 getClass.getResource("/b.txt")
like image 24
marios Avatar answered Oct 06 '22 00:10

marios