Override sourceManaged in the sbt-xjc plugin - sbt

I'm using the sbt-xjc plugin to generate my xml classes.
The default value of sourceManaged is prepended with xjc. I want to remove xjc. How should I do that?

For me, adding the following to project/build.scala worked:
++ Seq(
sourceManaged in (Compile, SbtXjcPlugin.xjc) <<= sourceManaged
The whole file looks like this:
import com.github.retronym.sbtxjc.test.BaseScriptedTestBuild
import com.github.retronym.sbtxjc.SbtXjcPlugin
import sbt._
import Keys._
object build extends BaseScriptedTestBuild {
lazy val root = {
Project(
id = "main",
base = file("."),
settings = Defaults.defaultSettings ++ scriptedTestSettings ++ SbtXjcPlugin.xjcSettings ++ Seq(
resolvers += "Java Net" at "http://download.java.net/maven/2/"
)++ Seq(
sourceManaged in (Compile, SbtXjcPlugin.xjc) <<= sourceManaged
)
);
}
}

With this config in build.sbt, XJC generates the classes directly in src_managed/main.
SbtXjcPlugin.xjcSettings ++ Seq(
sources in (Compile, xjc) <<= baseDirectory map (_ / "xsd" ** "*.xsd" get),
sourceManaged in (Compile, xjc) <<= sourceManaged / "main"
)
XJC will look for xsd files in /xsd and output the generated classes in /target/scala-2.x/src_managed/main

Related

Annotation Processor output path sbt?

Is there any way to set the Annotation processor output path in sbt?
Currently it generates the files into:
target/scala-2.11/classes
However I would prefer
target/scala-2.11/src_managed
Something like
// in build.sbt:
// create managed source directory before compile
compile in Compile <<= (compile in Compile) dependsOn Def.task { (managedSourceDirectories in Compile).value.head.mkdirs() },
// tell the java compiler to output generated source files to the managed source directory
javacOptions in Compile ++= Seq("-s", (managedSourceDirectories in Compile).value.head.getAbsolutePath),
It's slightly more ergonomic to configure sourceManaged instead of managedSourceDirectories.
Add to a sbt module's settings in build.sbt:
Compile / javacOptions ++= Seq("-s", (Compile / sourceManaged).value.getAbsolutePath)
You can also drop this plugin into the project folder
package custom.sbt
import sbt.{Def, _}
import sbt.Keys._
object Compiler extends AutoPlugin {
override def trigger = allRequirements
override def buildSettings: Seq[Def.Setting[_]] = Seq(
Compile / javacOptions ++= Seq("-source", "11", "-target", "11"),
scalacOptions ++= Seq(
"-target:11" // Target JRE 11
)
)
override def projectSettings: Seq[Def.Setting[_]] = Seq(
Compile / javacOptions ++= Seq("-s", (Compile / sourceManaged).value.getAbsolutePath)
)
}
in sbt 0.13.15
compile := ((compile in Compile) dependsOn Def.task {
(sourceManaged in Compile).value.mkdirs()
}).value,
javacOptions in Compile ++= Seq("-s", s"${sourceManaged.value}/main")

How to obtain the value of scalacOptions for the meta-project in a plugin?

In the ensime-sbt plugin, we need to be able to obtain the compiler flags that the sbt process is using to compile the build definition (i.e. everything under project).
We have the State object, but I can't see any way to get the compiler flags, where are they?
Note: this is not the compile flags for the projects themselves, I mean only for the build definition.
e.g. say the project has this in the project/plugins.sbt
scalacOptions += "-Xfuture"
how can we read that from the plugin?
This is somewhat related to How to share version values between project/plugins.sbt and project/Build.scala?
You can generate a build file for the project. And, to do that, you have to add the plugin in both the meta-project and the meta-project for the meta-project.
import sbt._
import Keys._
object MyPlugin extends AutoPlugin {
object autoImport {
val scalacOptions4Meta = SettingKey[Seq[String]]("scalacOptions4Meta")
val mygenerator = TaskKey[Seq[File]]("mygenerator")
}
import autoImport._
override def trigger = allRequirements
override lazy val projectSettings = Seq(
mygenerator := {
val file = sourceManaged.value / "settings4Meta.scala"
val opts = (scalacOptions in Compile).value
.map(opt => "\"" + opt + "\"")
val content = s"""
import sbt._
import Keys._
object MyBuild extends Build {
lazy val root = Project("root", file("."))
.settings(
MyPlugin.autoImport.scalacOptions4Meta := Seq(${opts.mkString(",")})
)
}"""
IO.write(file, content)
Seq(file)
}
)
}
project/plugins.sbt:
addSbtPlugin("myplugin" % "myplugin" % "0.1-SNAPSHOT")
scalacOptions := Seq("-Xfuture")
sourceGenerators in Compile += mygenerator.taskValue
project/project/plugins.sbt:
addSbtPlugin("myplugin" % "myplugin" % "0.1-SNAPSHOT")

Conditional libraries in build.sbt

Using buildsbt. I'm trying to do something like this:
if (condition) {
libraryDependencies += ... // library from maven
}
else {
unmanagedJars in Compile += ... // local library instead
}
However, build.sbt doesn't like this at all. I've been able to accomplish this using side effects, but that's obviously undesirable. Any advice would be appreciated. Thanks.
You can do the following:
val additionalLibraryDependencies = Seq(...)
val additionalUnmanagedJars = Seq(...)
libraryDependencies ++=(
if (condition) {
additionalLibraryDependencies
}
)
unmanagedJars in Compile ++= (
if (!condition) {
additionalUnmanagedJars
}
)
To set the condition from command line you should add the following lines:
val someValueFromCommandLine = System.getProperty("key.of.the.value", "false")
if (someValueFromCommandLine.equals("true")){
...
}
You can pass it like sbt -Dkey.of.the.value=true
This might be easier to do using a Build.scala build definition.
Here is an example build.sbt file (this is optional):
import sbt._
import sbt.Keys._
libraryDependencies ++= Seq(
"org.postgresql" % "postgresql" % "9.3-1101-jdbc41",
"redis.clients" % "jedis" % "2.5.2"
)
Then create another file your_project_home/project/Build.scala
import sbt._
import Keys._
object BuildSettings {
val condition = false
val buildSettings = Defaults.defaultSettings ++ Seq(
version := "1.0.0",
if(condition) libraryDependencies ++= Seq("commons-codec" % "commons-codec" % "1.9")
else unmanagedJars in Compile += file("/tmp/nil")
)
}
object MyBuild extends Build {
import BuildSettings._
lazy val root: Project = Project("root", file("."), settings = buildSettings)
}
Your project structure should look like this:
.
├── build.sbt
├── project
│   └── Build.scala
└── target
You can make the "condition" to be whatever what you need (here I just set it to false). The libraryDependencies defined inside build.sbt will always be included. The ones defined in Build.scala will depend on the "condition."
Verify that everything works as expected from the command line using:
sbt "inspect libraryDependencies"

How to add custom lines to MANIFEST.MF?

Adding custom key-value-pairs to the MANIFEST.MF using Build.scala seems not to work. Here is my code:
import sbt._
import Keys._
import java.util.Date
object Build extends Build {
packageOptions in (Compile, packageBin) +=
Package.ManifestAttributes( "Build" -> "true" )
}
When I add:
packageOptions in (Compile, packageBin) +=
Package.ManifestAttributes( "Sign" -> "true" )
To my build.sbt then only Sign reaches my MANIFEST.MF. Any thoughts?
I think you may want something like this (note the manifestSettings added to the settings of the project).
import sbt._
import Keys._
import java.util.Date
import sbt.Package.ManifestAttributes
object MyBuild extends Build {
lazy val manifestSettings = Seq(
packageOptions in (Compile, packageBin) +=
Package.ManifestAttributes( "Build" -> "true" )
)
lazy val root = Project(id = "root", base = file(".")).settings(manifestSettings: _*)
}
Then you should be able to call package and have the a jar with the extra manifest entry.
Edit
To get the ("Buid" -> <current time>) the manifestSettings should be
lazy val manifestSettings = Seq(
packageOptions in (Compile, packageBin) +=
Package.ManifestAttributes( "Build" -> new Date().toString() )
)

How configure aspectj compilation in playframework 2.1.1

I have added to plugins.sbt this declaration
addSbtPlugin("com.typesafe.sbt" % "sbt-aspectj" % "0.9.0")
Now I would like to configure this plugin to compile my java controller classes using aspect library org.springframework:spring-aspects:3.1.4 as with aspectj-maven-plugin
I have set this configuration :
import sbt._
import Keys._
import play.Project._
import com.typesafe.sbt.SbtAspectj._
import com.typesafe.sbt.SbtAspectj.AspectjKeys._
object ApplicationBuild extends Build {
val appDependencies = Seq(javaCore)
val main = play.Project(appName, appVersion, appDependencies).settings(
AspectjKeys.verbose in Aspectj := true,
AspectjKeys.showWeaveInfo in Aspectj := true,
AspectjKeys.inputs in Aspectj <+= compiledClasses
)
}
But it does fail.
[error] Reference to undefined setting:
[error]
[error] aspectj:inputs from aspectj:inputs
I am really a newbie with the sbt thing.
The plugin github page : https://github.com/sbt/sbt-aspectj
Ok, I make it works, thanks to sbt mailing list, cf. https://groups.google.com/forum/?fromgroups=#!topic/simple-build-tool/MUXyfKigC7w
and the playframework mailing list also, cf. https://groups.google.com/forum/?fromgroups=#!topic/play-framework/RfJFEwVbUUk
It was not very hard in fact but something you can't see things.
import sbt._
import Keys._
import play.Project._
import com.typesafe.sbt.SbtAspectj._
import com.typesafe.sbt.SbtAspectj.AspectjKeys._
object ApplicationBuild extends Build {
val appDependencies = Seq(javaCore, filters)
val main = play.Project(appName, appVersion, appDependencies)
.settings(aspectjSettings: _*)
.settings(
libraryDependencies += "org.springframework" % "spring-aspects" % "3.1.4.RELEASE",
libraryDependencies += "org.springframework.security" % "spring-security-aspects" % "3.1.4.RELEASE",
sourceLevel := "-1.7",
verbose in Aspectj := false,
showWeaveInfo in Aspectj := false,
inputs in Aspectj <+= compiledClasses,
binaries in Aspectj <++= update map { report =>
report.matching(
moduleFilter(organization = "org.springframework", name = "spring-aspects")
|| moduleFilter(organization = "org.springframework.security", name = "spring-security-aspects")
)
},
products in Compile <<= products in Aspectj,
products in Runtime <<= products in Compile
)
}
Don't forget to add this in in plugins.sbt, with a new line separator between declaration
addSbtPlugin("com.typesafe.sbt" % "sbt-aspectj" % "0.9.0")

Resources