summaryrefslogtreecommitdiff
path: root/src/main/scala/hbt/Main.scala
blob: 6dc934e447322aff0c81d4e2c5127926e94fca6d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package hbt
import java.io.FileOutputStream

import collection.JavaConverters._
import java.nio.file.{Path => JPath}
import java.util.jar.JarEntry
import sourcecode.Enclosing
sealed trait Target[T]{
  def path: String
  def map[V](f: T => V)(implicit path: Enclosing) = {
    Target.Mapped(this, f, path.value)
  }
  def zip[V](other: Target[V])(implicit path: Enclosing) = {
    Target.Zipped(this, other, path.value)
  }
  def ~[V, R](other: Target[V])
             (implicit s: Implicits.Sequencer[T, V, R]): Target[R] = {
    this.zip(other).map(s.apply _ tupled)
  }

}

object Target{
  def traverse[T](source: Seq[Target[T]])(implicit path: Enclosing) = {
    Traverse(source, path.value)
  }
  case class Traverse[T](source: Seq[Target[T]], path: String) extends Target[Seq[T]]
  case class Mapped[T, V](source: Target[T], f: T => V,
                          path: String) extends Target[V]
  case class Zipped[T, V](source: Target[T],
                          source2: Target[V],
                          path: String) extends Target[(T, V)]
  case class Path(path: String) extends Target[JPath]
  case class Command(inputs: Seq[Target[JPath]],
                     output: Seq[Target[JPath]],
                     path: String) extends Target[Command.Result]
  object Command{
    case class Result(stdout: String,
                      stderr: String,
                      writtenFiles: Seq[JPath])
  }
}
object Main{
  def compileAll(sources: Target[Seq[JPath]])
                (implicit path: Enclosing): Target[JPath] = {
    for(sources0 <- sources) yield {
      val output = java.nio.file.Paths.get(path.value)
      java.nio.file.Files.createDirectories(output)
      val command =
        Seq("scalac") ++
        sources0.map(_.toString) ++
        Seq("-d", path.value)



      new java.lang.ProcessBuilder()
        .command(command: _*)
        .start()
        .waitFor()

      output
    }
  }

  def list(root: Target[JPath]): Target[Seq[JPath]] = {
    root.map(java.nio.file.Files.list(_).iterator().asScala.toArray[JPath])
  }
  def jarUp(roots: Target[JPath]*)(implicit path: Enclosing): Target[JPath] = {
    for(rootsValue <- Target.traverse(roots)) yield {
      val output = new java.util.jar.JarOutputStream(new FileOutputStream(path.value))
      for{
        root <- rootsValue
        path <- java.nio.file.Files.list(root).iterator().asScala
      }{
        val relative = root.relativize(path)
        output.putNextEntry(new JarEntry(relative.toString))
        output.write(java.nio.file.Files.readAllBytes(path))
      }
      java.nio.file.Paths.get(path.value)
    }
  }
  def main(args: Array[String]): Unit = {
    val sourceRoot: Target[JPath] = ???
    val resourceRoot: Target[JPath] = ???
    val classFiles: Target[JPath] = compileAll(list(sourceRoot))
    val jar: Target[JPath] = jarUp(resourceRoot, classFiles)
  }
}