SBT src_managed not availabe for compilation - scala

In my project I have a special SBT plugin to generate some configuration specific settings (like sbt-buildinfo). A special task generates a Scala class and stores it in 'src_managed' folder.
The problem is, that after this file is successfully generated, the following 'compile' can't find this class and I get compilation error.
I have several configurations defined with:
compile in conf <<= (compile in conf).dependsOn(mytask)
I call this plugin like so:
;clean;proj/myconf:compile

You should setup special setting for code generator:
sourceGenerators in Compile <+= (myCodeGeneratorTask in Compile)
SBT generate code using project defined generator

Related

In SBT, how do you override compile to run arbitrary code afterwards?

I'm trying to use SBT to build a project that depends on bytecode enhancement. Basically, I need to run some code after compile using the classpath in the current scope (so the command can find the classes to modify), and then make sure that compile doesn't run again afterwards to undo the enhancement.
I'm using SBT 0.13.12, if that matters.
I believe you would want to make a new sbt task and have it depend on compile. Then use that rather than compile.
lazy val bytecodeEnhancedCompile = taskKey[Unit]("bytecode Enhance")
bytecodeEnhancedCompile <<= bytecodeEnhancedCompile dependsOn (compile in Compile)
bytecodeEnhancedCompile := {
....
}

how to disable slick codegen from creating dbModels on each compile?

I tried to comment automatic code gen on each compile in Build.scala as below,but then it my code shows error as it is unable to reference any autogen table models from previous compilations.
slick <<= slickCodeGenTask // register manual sbt command
//sourceGenerators in Compile <+= slickCodeGenTask // register automatic code generation on every compile, remove for only manual use
this worked for me: after running the task in sbt (gen-tables) just copy the generated Tables.scala into your source tree, so it will be picked up \as "normal" source file.
Or you can also modify the output directory in slickCodeGenTask to point into your sources, something like:
val outputDir = "src/main/scala"
hope this helps!

Real SBT Classpath at Runtime

I have some test cases that need to look at the classpath to extract the paths of some files/directories in there. This works fine in the IDE.
The problem is that, when running SBT test, Properties.javaClassPath gives me /usr/share/sbt-launcher-packaging/bin/sbt-launch.jar.
The classpath is fine when I run show test:dependency-classpath. Is there a way to obtain that information from inside the running Scala/Java program? Or is there a way to toss it into a system property or environment variable?
By default the tests are run inside of the SBT process, so the classpath will look like it did when you started sbt (I guess sbt does some trixery to dynamicly load the classes for the tests, not sure). One way to do what you want is to run your tests in a forked jvm, that way sbt will start a new jvm to run the test suite and that should have the expected class path:
fork in Test := true
I have been working on understanding how the EmbeddedCassandra works in the spark-cassandra-connector project which uses the classpath to start up and control a Cassandra instance. Here is a line from their configuration that gets the correct classpath.
(compile in IntegrationTest) <<= (compile in Test, compile in IntegrationTest) map { (_, c) => c }
The entire source can be found here: https://github.com/datastax/spark-cassandra-connector/blob/master/project/Settings.scala
Information on the <<= operator can be found here: http://www.scala-sbt.org/0.12.2/docs/Getting-Started/More-About-Settings.html#computing-a-value-based-on-other-keys-values. I'm aware that this is not the current version of sbt, but the definition still holds.

How to define a custom build setting?

I want my users to be able to define a value in their project/ definition that will be used as a URL for fetching a remote configuration file, which an sbt plugin will in turn use. I can't figure out how to define such a value though. When I try to add it to build.sbt I get this error:
/Users/2rs2ts/src/my-cool-plugin/build.sbt:74: error: not found: value myConfigUrl
myConfigUrl := "http://mycoolwebsite.com/config.xml"
^
[error] Type error in expression
Probably because it's not part of Keys. But I don't know how I'm supposed to add something like this. Even after that point, I don't know how to access the setting in my plugin's Scala source.
Use settingKey macro to define the myConfigUrl key.
A sample build.sbt could be as follows:
lazy val myConfigUrl = settingKey[String]("URL for fetching a remote configuration file")
myConfigUrl := "http://mycoolwebsite.com/config.xml"
A sample session:
➜ my-cool-plugin xsbt
[info] Loading global plugins from /Users/jacek/.sbt/0.13/plugins
[info] Set current project to my-cool-plugin (in build file:/Users/jacek/sandbox/my-cool-plugin/)
> show myConfigUrl
[info] http://mycoolwebsite.com/config.xml
Given the comment where the OP asked:
How can I refer to this in my project code now? I want to be able to
access the value I assigned to myConfigUrl in one of my .scala files,
not related to the build process.
the key should be defined in build.scala build object as no keys in *.sbt files are visible in project/*.scala files.
Here is a sample project/build.scala build definition with the key:
import sbt._
import Keys._
object build extends Build {
lazy val myConfigUrl = settingKey[String]("URL for fetching a remote configuration file")
lazy val mySettings = inConfig(Compile) { Seq(
myConfigUrl := "http://mycoolwebsite.com/config.xml"
)}
}
With the Scala build, change build.sbt to be as follows:
mySettings
You could do it since every build file is automatically imported in *.sbt files and hence accessing vals becomes simple like that. To have the settings - the single myConfigUrl key - available in the project you need to add the Seq[Setting] val.
Do reload and the key should be available as if it was before:
> show myConfigUrl
[info] http://mycoolwebsite.com/config.xml
Given the comment:
I'm particularly interested in a way to let end users of
my-cool-plugin define their own myConfigUrl which will be used instead
of the default one in my-cool-plugin's build.sbt
it's clear on the intent of the key. This is a key of the plugin so just add sbtPlugin := true to the build, publishLocal the project and use addSbtPlugin to declare a plugin dependency on the plugin in another build.
You may want to read about the new feature of sbt 0.13.5 - auto plugins - that further ease setting up the plugin of yours:
As of sbt 0.13.5, there is a new auto plugins feature that enables
plugins to automatically, and safely, ensure their settings and
dependencies are on a project.

Using sbt 0.13.1, tests won't compile using the generated externalIvyFile

For our Scala development we currently use ivy + ant, but we are also trying to use sbt for our development workflow. This would be for the continuous incremental compilation when not using an IDE.
sbt uses ivy, so in theory this should work. But when using an ivy external file the tests won't compile.
To reproduce this you can even use the generated ivy.xml file from any sbt project.
Here are the steps to reproduce the error on a sbt project with tests,
from the sbt console run deliverLocal (deliver-local in previous versions of sbt)
copy the generated ivy file into your project home and rename it to 'ivy.xml'. From my understanding using this file should be equivalent to declaring the dependencies in build.sbt.
edit the build.sbt, add externalIvyFile() on one line and then comment all dependencies declarations
in the console, run reload, then test
compile will run just fine, but test will fail at compile time. None of the dependencies will be honoured, not even the production code of the current project.
What am I missing?
In my case it worked with the following build.sbt:
externalIvyFile()
classpathConfiguration in Compile := Compile
classpathConfiguration in Test := Test
classpathConfiguration in Runtime := Runtime
You just need the extra three lines in the end. Here is a link for more info: http://www.scala-sbt.org/release/docs/Detailed-Topics/Library-Management.html#ivy-file-dependency-configuration
Look for the Full Ivy Example. I hope it helps!
EDIT: Just to be complete - here is what pointed me to the above link: https://github.com/sbt/sbt/issues/849.