It would probably help if you explained your use scenario for this, since there are some different possible solution paths here and choosing between them might involve considerations that you haven't told us.
You won't be able to just write down an ordinary method call into the compiled code. That would be impossible since at the time your build definition is compiled, sbt hasn't looked at your project code yet.
Warning: rambling and thinking out loud ahead.
One trick I can suggest is to access testLoader in Test
to get a classloader in which your compiled classes are loaded, and then use reflection to call methods there. For example, in my own build I have:
val netlogoVersion = taskKey[String]("...")
netlogoVersion := {
(testLoader in Test).value
.loadClass("org.nlogo.api.Version")
.getMethod("version")
.invoke(null).asInstanceOf[String]
}
I'm not sure whether accessing testLoader in Test
will actually work in your case because testLoader
loads your test classes as well as your regular classes, so you might get a circular dependency between compile in Compile
and compile in Test
.
If you want to try to make a classloader that just has your regular classes loaded, well, hmm. You could look in the sbt source code at the implementation of createTestLoader
and use it for inspiration, modifying the arguments that are passed to ClasspathUtilities.makeLoader
. (You might also look at the similar code in Run.run0
. It calls makeLoader
as part of the implementation of the run
task.)
A different path you might consider is to reuse the machinery behind the run
task to run your code. You won't be able to call an arbitrary method in your compiled code this way, only a main
method, but perhaps you can live with that, if you don't need a return value back.
The fullRunTask
method exists for creating entire run
-like tasks. See "How can I create a custom run task, in addition to run?" from http://www.scala-sbt.org/0.13.1/docs/faq.html . fullRunTask
makes it very easy to create a separate task that runs something in your compiled code, but by itself it won't get you all the way to a solution because you need a way of attaching that task to the existing compile in Compile
task. If you go this route, I'd suggest asking it that last piece as a separate question.
Consider bypassing fullRunTask
and just assembling your own call to Run.run
. They use the same machinery. In my own build, I currently use fullRunTask
, but back before fullRunTask
was added by sbt, here was what my equivalent Run.run
-based code looked like:
(..., fullClasspath in Compile, runner, streams, ...) map {
(..., cp, runner, s, ...) =>
Run.run("name.of.my.MainClass",
cp.map(_.data), Seq(), s.log)(runner)
}
Pardon the sbt 0.12, pre-macro syntax; this would look nicer if redone with the 0.13 macros.
Anyway, hopefully something in this brain dump proves useful.