I have a project that is a scala & scalatra API. I have two distributables that I build with sbt-native-packager -
I'm currently using provided
scope dependencies for items I need to manually manage with the RPM/DEB approach - database libraries that I cannot bundle and distribute due to license restrictions.
"mysql" % "mysql-connector-java" % "5.1.30" % "provided",
"com.microsoft" % "sqlserver.jdbc" % "4.1" % "provided",
..etc..
This has been working great. I use the universal plugin and the dist
task, somewhat massaged, and then hook up some package build scripts.
Now I'm building the heroku install, and I don't know how to add back in those provided dependencies. I'm using the universal plugin and running the stage
task. However, provided dependencies are being filtered out and I'd like to actually have them included when running stage
, because I don't have the license restriction anymore in heroku.
Options that I think I have...
mapping
to add back in provided scope dependencies during the stage
task, but not during the dist
taskdist
I have some mappings already like this,
//add webapp dir to zip
mappings in Universal ++= directory("src/main/webapp")
//add db dir to zip, but move it into /lib/db instead of /db
mappings in Universal ++= (directory("src/main/resources/db").map{t =>
(t._1, "lib/"+t._2)
}
)
So I feel like I could probably figure out how to add/exclude if I really tried, but I'm having problems finding any documentation for this stuff. The examples here don't really help much, or I don't understand enough.
Thanks in advance!
This is an interesting question. Some time ago we added the possibility to add arbitrary artifacts from the build classpath. ( See scaladocs too )
Option 1 could look like this. Note, that this doesn't work as I expect, as some mappings are not exactly picked up by native-packager:
// `show universal::stage:mappings` works properly
mappings in (Universal, stage) ++= {
// calculate provided dependencies.
val compileDep = (managedClasspath in Compile).value.toSet
val runtimeDep = (managedClasspath in Runtime).value.toSet
val provided = compileDep -- runtimeDep
// create mappings
fromClasspath(provided.toSeq, "jar", artifact => true)
}
I suggest a variation of option 1 by providing a build environment and decided, which mappings to add.
mappings in Universal ++= {
// a build environment
val env = buildEnv.value
// calculate provided dependencies.
val compileDep = (managedClasspath in Compile).value.toSet
val runtimeDep = (managedClasspath in Runtime).value.toSet
val provided = compileDep -- runtimeDep
// create mappings, depending on build environment
fromClasspath(provided.toSeq, "jar", _ => env == BuildEnv.Stage)
}
// add the dependencies to the start script as well
scriptClasspath ++= { /* similar code as above */}
I hoped to be able to to something like this
libraryDependencies += "com.google.guava" % "guava" % "19.0" % "provided"
mappings in (Universal, stage) ++= fromClasspath(
(managedClasspath in Compile).value,
"jar",
artifact => artifact.scope == "provided"
)
Which wasn't possible, as the sbt Artifact has no way to access the ivy-scope (or I haven't found it).
Then I tried to do this
libraryDependencies += "com.google.guava" % "guava" % "19.0" % "provided" extra("heroku" -> "true")
mappings in (Universal, stage) ++= fromClasspath(
(managedClasspath in Compile).value,
"jar",
artifact => artifact.extra.find(_ == "heroku")
.map(_.toBoolean)
.getOrElse(false)
)
which didn't worked either, as it seems that SBT doesn't pass the extra
attributes from the ModuleID to the Artifact model. This left me with the solution described above.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With