summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/src/main/scala/forge/define/Applicative.scala2
-rw-r--r--core/src/main/scala/forge/define/Target.scala12
-rw-r--r--core/src/main/scala/forge/discover/Router.scala7
-rw-r--r--core/src/main/scala/forge/eval/Evaluator.scala25
-rw-r--r--core/src/test/scala/forge/JavaCompileJarTests.scala51
5 files changed, 77 insertions, 20 deletions
diff --git a/core/src/main/scala/forge/define/Applicative.scala b/core/src/main/scala/forge/define/Applicative.scala
index 6a4d1d0c..dfa0cf84 100644
--- a/core/src/main/scala/forge/define/Applicative.scala
+++ b/core/src/main/scala/forge/define/Applicative.scala
@@ -7,7 +7,7 @@ import scala.collection.mutable
import scala.reflect.macros.blackbox.Context
object Applicative {
- trait Applyable[T]{
+ trait Applyable[+T]{
@compileTimeOnly("Target#apply() can only be used with a T{...} block")
def apply(): T = ???
}
diff --git a/core/src/main/scala/forge/define/Target.scala b/core/src/main/scala/forge/define/Target.scala
index 98bd1b7c..753a63e8 100644
--- a/core/src/main/scala/forge/define/Target.scala
+++ b/core/src/main/scala/forge/define/Target.scala
@@ -9,7 +9,7 @@ import play.api.libs.json.{Format, Json}
import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context
-abstract class Target[T] extends Target.Ops[T] with Applyable[T]{
+abstract class Target[+T] extends Target.Ops[T] with Applyable[T]{
/**
* What other Targets does this Target depend on?
*/
@@ -27,8 +27,10 @@ abstract class Target[T] extends Target.Ops[T] with Applyable[T]{
def sideHash: Int = 0
}
+
object Target extends Applicative.Applyer[Target, Target]{
def underlying[A](v: Target[A]) = v
+
type Cacher = forge.define.Cacher[Target[_]]
class Target0[T](t: T) extends Target[T]{
lazy val t0 = t
@@ -46,7 +48,7 @@ object Target extends Applicative.Applyer[Target, Target]{
)
}
- abstract class Ops[T]{ this: Target[T] =>
+ abstract class Ops[+T]{ this: Target[T] =>
def map[V](f: T => V) = new Target.Mapped(this, f)
def filter(f: T => Boolean) = this
@@ -58,18 +60,18 @@ object Target extends Applicative.Applyer[Target, Target]{
def traverse[T](source: Seq[Target[T]]) = {
new Traverse[T](source)
}
- class Traverse[T](val inputs: Seq[Target[T]]) extends Target[Seq[T]]{
+ class Traverse[+T](val inputs: Seq[Target[T]]) extends Target[Seq[T]]{
def evaluate(args: Args) = {
for (i <- 0 until args.length)
yield args(i).asInstanceOf[T]
}
}
- class Mapped[T, V](source: Target[T], f: T => V) extends Target[V]{
+ class Mapped[+T, +V](source: Target[T], f: T => V) extends Target[V]{
def evaluate(args: Args) = f(args(0))
val inputs = List(source)
}
- class Zipped[T, V](source1: Target[T], source2: Target[V]) extends Target[(T, V)]{
+ class Zipped[+T, +V](source1: Target[T], source2: Target[V]) extends Target[(T, V)]{
def evaluate(args: Args) = (args(0), args(1))
val inputs = List(source1, source2)
}
diff --git a/core/src/main/scala/forge/discover/Router.scala b/core/src/main/scala/forge/discover/Router.scala
index 3d054e29..afb526c7 100644
--- a/core/src/main/scala/forge/discover/Router.scala
+++ b/core/src/main/scala/forge/discover/Router.scala
@@ -1,6 +1,7 @@
package forge.discover
import ammonite.main.Compat
+import forge.define.Target
import sourcecode.Compat.Context
import scala.annotation.StaticAnnotation
@@ -56,8 +57,8 @@ object Router{
argSignatures: Seq[ArgSig[T]],
doc: Option[String],
varargs: Boolean,
- invoke0: (T, Map[String, String], Seq[String]) => Result[Any]){
- def invoke(target: T, groupedArgs: Seq[(String, Option[String])]): Result[Any] = {
+ invoke0: (T, Map[String, String], Seq[String]) => Result[Target[Any]]){
+ def invoke(target: T, groupedArgs: Seq[(String, Option[String])]): Result[Target[Any]] = {
var remainingArgSignatures = argSignatures.toList
@@ -375,7 +376,7 @@ class Router [C <: Context](val c: C) {
forge.discover.Router.validate(Seq(..$readArgs)) match{
case forge.discover.Router.Result.Success(List(..$argNames)) =>
forge.discover.Router.Result.Success($arg.${meth.name.toTermName}(..$argNameCasts))
- case x => x
+ case x: forge.discover.Router.Result.Error => x
}
)
"""
diff --git a/core/src/main/scala/forge/eval/Evaluator.scala b/core/src/main/scala/forge/eval/Evaluator.scala
index 19cd3236..590b5534 100644
--- a/core/src/main/scala/forge/eval/Evaluator.scala
+++ b/core/src/main/scala/forge/eval/Evaluator.scala
@@ -48,13 +48,16 @@ class Evaluator(workspacePath: Path,
externalInputs.toIterator.map(results).toVector.hashCode +
group.toIterator.map(_.sideHash).toVector.hashCode()
- val primeLabel = labeling(terminals.items(0)).segments
-
-
- val targetDestPath = workspacePath / primeLabel
- val metadataPath = targetDestPath / up / (targetDestPath.last + ".forge.json")
+ val (targetDestPath, metadataPath) = labeling.get(terminals.items(0)) match{
+ case Some(labeling) =>
+ val targetDestPath = workspacePath / labeling.segments
+ val metadataPath = targetDestPath / up / (targetDestPath.last + ".forge.json")
+ (targetDestPath, Some(metadataPath))
+ case None => (null, None)
+ }
val cached = for{
+ metadataPath <- metadataPath
json <- scala.util.Try(Json.parse(read.getInputStream(metadataPath))).toOption
(cachedHash, terminalResults) <- Json.fromJson[(Int, Seq[JsValue])](json).asOpt
if cachedHash == inputsHash
@@ -71,11 +74,13 @@ class Evaluator(workspacePath: Path,
case _ =>
val (newResults, newEvaluated, terminalResults) = evaluateGroup(group, results, targetDestPath)
- write.over(
- metadataPath,
- Json.prettyPrint(
- Json.toJson(inputsHash -> terminals.toList.map(terminalResults))
- ),
+ metadataPath.foreach(
+ write.over(
+ _,
+ Json.prettyPrint(
+ Json.toJson(inputsHash -> terminals.toList.map(terminalResults))
+ ),
+ )
)
(newResults, newEvaluated)
diff --git a/core/src/test/scala/forge/JavaCompileJarTests.scala b/core/src/test/scala/forge/JavaCompileJarTests.scala
index 6ce02149..92e1d0e9 100644
--- a/core/src/test/scala/forge/JavaCompileJarTests.scala
+++ b/core/src/test/scala/forge/JavaCompileJarTests.scala
@@ -1,7 +1,7 @@
package forge
-import ammonite.ops._
+import ammonite.ops._, ImplicitWd._
import forge.define.Target
import forge.discover.Discovered
import forge.eval.{Evaluator, PathRef}
@@ -44,10 +44,20 @@ object JavaCompileJarTests extends TestSuite{
def allSources = T{ ls.rec(sourceRoot().path).map(PathRef(_)) }
def classFiles = T{ compileAll(allSources) }
def jar = T{ jarUp(resourceRoot, classFiles) }
+
+ @forge.discover.Router.main
+ def run(mainClsName: String): Target[CommandResult] = T.command{
+ %%('java, "-cp", classFiles().path, mainClsName)
+ }
}
import Build._
val mapping = Discovered.mapping(Build)
+ def eval[T](t: Target[T]): (T, Int) = {
+ val evaluator = new Evaluator(workspacePath, mapping)
+ val evaluated = evaluator.evaluate(OSet(t))
+ (evaluated.values(0).asInstanceOf[T], evaluated.evaluated.size)
+ }
def check(targets: OSet[Target[_]], expected: OSet[Target[_]]) = {
val evaluator = new Evaluator(workspacePath, mapping)
@@ -113,6 +123,45 @@ object JavaCompileJarTests extends TestSuite{
val executed = %%('java, "-cp", workspacePath/'jar, "test.Foo")(workspacePath).out.string
assert(executed == (31337 + 271828) + "\n")
+
+ println("="*20 + "Run Main" + "="*20)
+ for(i <- 0 until 3){
+ // Build.run is not cached, so every time we eval it it has to
+ // re-evaluate
+ val (runOutput, evalCount) = eval(Build.run("test.Foo"))
+ assert(
+ runOutput.out.string == (31337 + 271828) + "\n",
+ evalCount == 1
+ )
+ }
+
+ val ex = intercept[ammonite.ops.ShelloutException]{
+ eval(Build.run("test.BarFour"))
+ }
+ assert(ex.getMessage.contains("Could not find or load main class"))
+
+ append(
+ sourceRootPath / "Bar.java",
+ """
+ class BarFour{
+ public static void main(String[] args){
+ System.out.println("New Cls!");
+ }
+ }
+ """
+ )
+ val (runOutput2, evalCount2) = eval(Build.run("test.BarFour"))
+ assert(
+ runOutput2.out.string == "New Cls!\n",
+ evalCount2 == 5
+ )
+ val (runOutput3, evalCount3) = eval(Build.run("test.BarFour"))
+ assert(
+ runOutput3.out.string == "New Cls!\n",
+ evalCount3 == 1
+ )
+
+
}
}
}