summaryrefslogtreecommitdiff
path: root/src/main/scala/hbt/Evaluator.scala
blob: 442ec63394c9a5faba0782fb5c3737c24fdf4253 (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
package hbt

import java.nio.{file => jnio}

import sourcecode.Enclosing

import scala.collection.mutable

object Evaluator{


  def apply[T](t: Target[T],
               workspacePath: jnio.Path)
              (implicit enclosing: Enclosing): T = {
    jnio.Files.createDirectories(workspacePath)
    val targetPaths = mutable.Map.empty[Target[_], List[String]]
    def rec(t: Target[_], path: List[String]): Unit = {
      if (targetPaths.contains(t)) () // do nothing
      else {
        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, Nil)
    val targets = targetPaths.keys.toIndexedSeq
    val targetIndices = targets.zipWithIndex.toMap

    val numberedEdges =
      for(i <- targets.indices)
      yield targets(i).inputs.map(targetIndices)

    val sortedClusters = Tarjans(numberedEdges)
    val nonTrivialClusters = sortedClusters.filter(_.length > 1)
    assert(nonTrivialClusters.isEmpty, nonTrivialClusters)

    val results = mutable.Map.empty[Target[_], Any]
    for (cluster <- sortedClusters){
      val Seq(singletonIndex) = cluster
      val target = targets(singletonIndex)
      val inputResults = target.inputs.map(results)
      val targetDestPath = workspacePath.resolve(
        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]
  }
}