Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Include generated resources in a jar (SBT)

Tags:

jar

scala

sbt

I've been writing an SBT plugin that generates resources into resource_managed. I'm now looking to include these generated resources in the generated jar as the SBT docs detail:

Generating resources:

By default, generated resources are not included in the packaged source artifact. To do so, add them as you would other mappings. See Adding files to a package

I've read the docs but honestly how to do this I can't figure out. Can anyone explain it or point me to another project that does this so I can see how they do it?

like image 200
Michael Allen Avatar asked Aug 14 '14 14:08

Michael Allen


1 Answers

First just to clarify, they are included in jars containing compiled classes. They are not included in jars containing sources.

By default, generated resources are not included in the packaged source artifact.

For packageBin the generated files should already be included - just make sure you return all generated files from the generator method. Assuming you want to package them in the sources artifact, this is what you have to do.

Let's assume you have a generator that generates a property file.

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

To include that in the generated sources you have to tell sbt to where the res.properties must be copied in the generated sources artefact. The task, which generates the packaged sources is called packageSrc, therefore you have to set mappings scoped to that task.

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

Because your generator can generate many tasks, and mapping each by hand would be a tedious task, sbt gives you an utility to map multiple paths at once.

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

The first line finds all generated files using path finders and second line maps them to their path in the target jar.

like image 194
lpiepiora Avatar answered Oct 10 '22 20:10

lpiepiora