summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.sbt5
-rw-r--r--src/main/scala/hbt/Hbt.scala56
-rw-r--r--src/main/scala/hbt/Main.scala5
-rw-r--r--src/main/scala/hbt/ReadWrite.scala20
-rw-r--r--src/main/scala/hbt/Tarjans.scala11
-rw-r--r--src/main/scala/hbt/Util.scala43
-rw-r--r--test/src/Foo.scala3
7 files changed, 92 insertions, 51 deletions
diff --git a/build.sbt b/build.sbt
index 7478db4f..ecfedcef 100644
--- a/build.sbt
+++ b/build.sbt
@@ -8,7 +8,10 @@ libraryDependencies += "com.lihaoyi" %% "utest" % "0.5.4" % "test"
testFrameworks += new TestFramework("utest.runner.Framework")
-libraryDependencies += "com.lihaoyi" %% "sourcecode" % "0.1.4"
+libraryDependencies ++= Seq(
+ "com.lihaoyi" %% "sourcecode" % "0.1.4",
+ "com.lihaoyi" %% "pprint" % "0.5.3"
+)
sourceGenerators in Compile += Def.task {
val dir = (sourceManaged in Compile).value
diff --git a/src/main/scala/hbt/Hbt.scala b/src/main/scala/hbt/Hbt.scala
index c6035e55..b321920b 100644
--- a/src/main/scala/hbt/Hbt.scala
+++ b/src/main/scala/hbt/Hbt.scala
@@ -1,25 +1,21 @@
package hbt
-import java.io.FileOutputStream
-
-import collection.JavaConverters._
import java.nio.{file => jnio}
-import java.util.jar.JarEntry
import sourcecode.Enclosing
import scala.collection.mutable
-class Args(val args: IndexedSeq[_]){
+class Args(val args: IndexedSeq[_], val dest: jnio.Path){
def length = args.length
def apply[T](index: Int): T = {
if (index >= 0 && index < args.length) args(index).asInstanceOf[T]
else throw new IndexOutOfBoundsException(s"Index $index outside of range 0 - ${args.length}")
}
}
-sealed trait Target[T]{
+trait Target[T]{
val label: String
- def evaluate(args: Args): T
val inputs: Seq[Target[_]]
+ def evaluate(args: Args): T
def map[V](f: T => V)(implicit path: Enclosing) = {
Target.Mapped(this, f, path.value)
@@ -36,12 +32,12 @@ sealed trait Target[T]{
object Target{
def traverse[T](source: Seq[Target[T]])(implicit path: Enclosing) = {
- Traverse(source, path.value)
+ Traverse[T](source, path.value)
}
case class Traverse[T](inputs: Seq[Target[T]], label: String) extends Target[Seq[T]]{
def evaluate(args: Args) = {
for (i <- 0 until args.length)
- yield args(i)
+ yield args(i).asInstanceOf[T]
}
}
@@ -56,6 +52,8 @@ object Target{
def evaluate(args: Args) = (args(0), args(0))
val inputs = List(source1, source1)
}
+
+ def path(path: jnio.Path)(implicit label: Enclosing) = Path(path, label.value)
case class Path(path: jnio.Path, label: String) extends Target[jnio.Path]{
def evaluate(args: Args) = path
val inputs = Nil
@@ -72,17 +70,21 @@ object Target{
object Hbt{
- def evaluateTargetGraph[T](t: Target[T]): T = {
- val targetSet = mutable.Set.empty[Target[_]]
- def rec(t: Target[_]): Unit = {
- if (targetSet.contains(t)) () // do nothing
+ def evaluateTargetGraph[T](t: Target[T])(implicit enclosing: Enclosing): T = {
+ val targetPaths = mutable.Map.empty[Target[_], List[String]]
+ def rec(t: Target[_], path: List[String]): Unit = {
+ if (targetPaths.contains(t)) () // do nothing
else {
- targetSet.add(t)
- t.inputs.foreach(rec)
+ val currentPath =
+ if (!t.label.startsWith(enclosing.value)) path.reverse
+ else t.label.stripPrefix(enclosing.value).drop(1).split('.').toList
+
+ targetPaths(t) = currentPath
+ t.inputs.zipWithIndex.foreach{case (c, i) => rec(c, i.toString :: currentPath)}
}
}
- rec(t)
- val targets = targetSet.toIndexedSeq
+ rec(t, Nil)
+ val targets = targetPaths.keys.toIndexedSeq
val targetIndices = targets.zipWithIndex.toMap
val numberedEdges =
@@ -96,10 +98,22 @@ object Hbt{
val results = mutable.Map.empty[Target[_], Any]
for (cluster <- sortedClusters){
val Seq(singletonIndex) = cluster
- val singleton = targets(singletonIndex)
- val inputResults = singleton.inputs.map(results)
- results(singleton) = singleton.evaluate(new Args(inputResults.toIndexedSeq))
+ val target = targets(singletonIndex)
+ val inputResults = target.inputs.map(results)
+ val targetDestPath = jnio.Paths.get(targetPaths(target).mkString("/"))
+ import collection.JavaConverters._
+ if (jnio.Files.exists(targetDestPath)){
+ jnio.Files.walk(targetDestPath).iterator()
+ .asScala
+ .toArray
+ .reverseIterator
+ .map(jnio.Files.deleteIfExists)
+ }
+
+ results(target) = target.evaluate(
+ new Args(inputResults.toIndexedSeq, targetDestPath)
+ )
}
results(t).asInstanceOf[T]
}
-} \ No newline at end of file
+}
diff --git a/src/main/scala/hbt/Main.scala b/src/main/scala/hbt/Main.scala
index 2cc59cc9..3baadda1 100644
--- a/src/main/scala/hbt/Main.scala
+++ b/src/main/scala/hbt/Main.scala
@@ -3,10 +3,11 @@ import java.nio.{file => jnio}
import Util._
object Main{
def main(args: Array[String]): Unit = {
- val sourceRoot = Target.Path(jnio.Paths.get("test/src"), "sourceRoot")
- val resourceRoot = Target.Path(jnio.Paths.get("test/resources"), "resourceRoot")
+ val sourceRoot = Target.path(jnio.Paths.get("test/src"))
+ val resourceRoot = Target.path(jnio.Paths.get("test/resources"))
val allSources = list(sourceRoot)
val classFiles = compileAll(allSources)
val jar = jarUp(resourceRoot, classFiles)
+ Hbt.evaluateTargetGraph(jar)
}
} \ No newline at end of file
diff --git a/src/main/scala/hbt/ReadWrite.scala b/src/main/scala/hbt/ReadWrite.scala
new file mode 100644
index 00000000..962c0ea4
--- /dev/null
+++ b/src/main/scala/hbt/ReadWrite.scala
@@ -0,0 +1,20 @@
+package hbt
+import java.nio.{file => jnio}
+
+trait ReadWrite[T] {
+ def write(t: T, p: jnio.Path): Unit
+ def read(p: jnio.Path): T
+}
+
+object ReadWrite{
+ implicit object String extends ReadWrite[java.lang.String]{
+ def write(t: String, p: jnio.Path) = {
+ jnio.Files.createDirectories(p.getParent)
+ jnio.Files.deleteIfExists(p)
+ jnio.Files.write(p, t.getBytes)
+ }
+ def read(p: jnio.Path) = {
+ new String(jnio.Files.readAllBytes(p))
+ }
+ }
+}
diff --git a/src/main/scala/hbt/Tarjans.scala b/src/main/scala/hbt/Tarjans.scala
index dc95b02f..7518080c 100644
--- a/src/main/scala/hbt/Tarjans.scala
+++ b/src/main/scala/hbt/Tarjans.scala
@@ -4,16 +4,7 @@ import collection.mutable
// Adapted from
// https://github.com/indy256/codelibrary/blob/c52247216258e84aac442a23273b7d8306ef757b/java/src/SCCTarjan.java
object Tarjans {
- def main(args: Array[String]) = {
- val components = Tarjans(
- Vector(
- Vector(1),
- Vector(0),
- Vector(0, 1)
- )
- )
- println(components)
- }
+
def apply(graph0: Seq[Seq[Int]]): Seq[Seq[Int]] = {
val graph = graph0.map(_.toArray).toArray
diff --git a/src/main/scala/hbt/Util.scala b/src/main/scala/hbt/Util.scala
index a7456b56..fef4009b 100644
--- a/src/main/scala/hbt/Util.scala
+++ b/src/main/scala/hbt/Util.scala
@@ -10,43 +10,52 @@ import scala.collection.JavaConverters._
import scala.collection.mutable
object Util{
- def compileAll(sources: Target[Seq[jnio.Path]])
- (implicit path: Enclosing): Target[jnio.Path] = {
- for(sources0 <- sources) yield {
- val output = jnio.Paths.get(path.value)
- jnio.Files.createDirectories(output)
+ case class compileAll(sources: Target[Seq[jnio.Path]])
+ (implicit path: Enclosing) extends Target[jnio.Path]{
+ val label = path.value
+ val inputs = Seq(sources)
+ def evaluate(args: Args): jnio.Path = {
+
+ jnio.Files.createDirectories(args.dest)
val command =
Seq("scalac") ++
- sources0.map(_.toString) ++
- Seq("-d", path.value)
-
+ args[Seq[jnio.Path]](0).map(_.toString) ++
+ Seq("-d", args.dest.toString)
-
- new java.lang.ProcessBuilder()
+ val result = new java.lang.ProcessBuilder()
.command(command: _*)
.start()
.waitFor()
- output
+ args.dest
}
}
def list(root: Target[jnio.Path]): Target[Seq[jnio.Path]] = {
root.map(jnio.Files.list(_).iterator().asScala.toArray[jnio.Path])
}
- def jarUp(roots: Target[jnio.Path]*)(implicit path: Enclosing): Target[jnio.Path] = {
- for(rootsValue <- Target.traverse(roots)) yield {
- val output = new java.util.jar.JarOutputStream(new FileOutputStream(path.value))
+ case class jarUp(roots: Target[jnio.Path]*)(implicit path: Enclosing) extends Target[jnio.Path]{
+ val label = path.value
+ val inputs = roots
+ def evaluate(args: Args): jnio.Path = {
+
+ val output = new java.util.jar.JarOutputStream(new FileOutputStream(args.dest.toFile))
for{
- root <- rootsValue
- path <- jnio.Files.list(root).iterator().asScala
+ root0 <- args.args
+ root = root0.asInstanceOf[jnio.Path]
+
+ path <- jnio.Files.walk(root).iterator().asScala
+ if jnio.Files.isRegularFile(path)
}{
val relative = root.relativize(path)
output.putNextEntry(new JarEntry(relative.toString))
output.write(jnio.Files.readAllBytes(path))
}
- jnio.Paths.get(path.value)
+ output.close()
+ args.dest
}
+
+
}
diff --git a/test/src/Foo.scala b/test/src/Foo.scala
index 96b7a530..4e8e09d6 100644
--- a/test/src/Foo.scala
+++ b/test/src/Foo.scala
@@ -1,4 +1,7 @@
package test
object Foo{
def value = 31337
+ def main(args: Array[String]): Unit = {
+ println(value)
+ }
} \ No newline at end of file