Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering resources in SBT

Tags:

scala

sbt

I am trying to setup SBT to compile an existing project which does not use the maven directory structure. I am using the full configuration and have set my javaSource & resourceDirectory settings as follows:

def settings = Defaults.defaultSettings ++ Seq(
    resourceDirectory in Compile <<= baseDirectory( _ / "java" ),
    javaSource in Compile <<= baseDirectory( _ / "java" )
)

Now I want to be able to filter the resources we include in the jar artifact, as we currently do with ant, plus exclude .java files as our resources are mixed in with source code. For example:

<fileset dir="java" includes="**/*.txt, **/*.csv" excludes="**/*.java" />

Is there any way to do this?

like image 446
Jon Freedman Avatar asked Jul 08 '11 16:07

Jon Freedman


1 Answers

Use defaultExcludes scoped for the unmanagedResources task and optionally the configuration. For example, this setting excludes .java files from the main resources:

defaultExcludes in Compile in unmanagedResources := "*.java"

in Compile restricts this setting to only apply to main resources. By using in Test instead, it would apply only to test resources. By omitting a configuration (that is, no in Compile or in Test), the setting would apply to both main and test resources.

in unmanagedResources applies these excludes for resources only. To apply excludes to sources, for example, the scope would be in unmanagedSources. The reason for the unmanaged part is to emphasize that these apply to unmanaged (or manually edited) sources only.

The defaultExcludes key has type sbt.FileFilter, so the setting value must be of this type. In the example above, "*.java" is implicitly converted to a FileFilter. * is interpreted as a wildcard and so the filter accepts files with a name that ends in '.java'. To combine filters, you use || and &&. For example, if .scala files needed to be excluded as well, the argument to := would be:

"*.java" || "*.scala"

In the original Ant fileset, the include and exclude filters select mutually exclusive sets of files, so only one is necessary.

It is also possible to directly build the Seq[File] for unmanagedResources. For example:

unmanagedResources in Compile <<=
  unmanagedResourceDirectories in Compile map { (dirs: Seq[File]) =>
    ( dirs ** ("*.txt" || "*.csv" -- "*.java") ).get
  }

The ** method selects all descendents that match the FileFilter argument. You can verify that the files are selected as you expect by running show unmanaged-resources.

like image 84
Mark Harrah Avatar answered Oct 21 '22 15:10

Mark Harrah