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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
package mill.main
import mill.define.Applicative.ApplyHandler
import mill.define.Segment.Label
import mill.define._
import mill.eval.{Evaluator, Result}
import mill.util.Strict.Agg
import scala.collection.mutable
object ReplApplyHandler{
def apply[T](colors: ammonite.util.Colors,
pprinter0: pprint.PPrinter,
rootModule: mill.Module,
discover: Discover[_]) = {
new ReplApplyHandler(
pprinter0,
new mill.eval.Evaluator(
ammonite.ops.pwd,
ammonite.ops.pwd / 'out,
ammonite.ops.pwd / 'out,
rootModule,
discover,
new mill.util.PrintLogger(
colors != ammonite.util.Colors.BlackWhite,
colors,
System.out,
System.err,
System.err
)
)
)
}
}
class ReplApplyHandler(pprinter0: pprint.PPrinter,
evaluator: Evaluator[_]) extends ApplyHandler[Task] {
// Evaluate classLoaderSig only once in the REPL to avoid busting caches
// as the user enters more REPL commands and changes the classpath
val classLoaderSig = Evaluator.classLoaderSig
override def apply[V](t: Task[V]) = {
val res = evaluator.evaluate(Agg(t))
res.values match{
case Seq(head: V) => head
case Nil =>
val msg = new mutable.StringBuilder()
msg.append(res.failing.keyCount + " targets failed\n")
for((k, vs) <- res.failing.items){
msg.append(k match{
case Left(t) => "Anonymous Task\n"
case Right(k) => k.segments.render + "\n"
})
for(v <- vs){
v match{
case Result.Failure(m) => msg.append(m + "\n")
case Result.Exception(t, outerStack) =>
msg.append(
t.toString + t.getStackTrace.dropRight(outerStack.length).map("\n " + _).mkString + "\n"
)
}
}
}
throw new Exception(msg.toString)
}
}
val generatedEval = new EvalGenerated(evaluator)
val millHandlers: PartialFunction[Any, pprint.Tree] = {
case c: Cross[_] =>
pprint.Tree.Lazy( ctx =>
Iterator(c.millOuterCtx.enclosing , ":", c.millOuterCtx.lineNum.toString, ctx.applyPrefixColor("\nChildren:").toString) ++
c.items.iterator.map(x =>
"\n (" + x._1.map(pprint.PPrinter.BlackWhite.apply(_)).mkString(", ") + ")"
)
)
case m: mill.Module if evaluator.rootModule.millInternal.modules.contains(m) =>
pprint.Tree.Lazy( ctx =>
Iterator(m.millInternal.millModuleEnclosing, ":", m.millInternal.millModuleLine.toString) ++
(if (m.millInternal.reflect[mill.Module].isEmpty) Nil
else
ctx.applyPrefixColor("\nChildren:").toString +:
m.millInternal.reflect[mill.Module].map("\n ." + _.millOuterCtx.segments.render)) ++
(evaluator.discover.value.get(m.getClass) match{
case None => Nil
case Some(commands) =>
ctx.applyPrefixColor("\nCommands:").toString +: commands.map{c =>
"\n ." + c._2.name + "(" +
c._2.argSignatures.map(s => s.name + ": " + s.typeString).mkString(", ") +
")()"
}
}) ++
(if (m.millInternal.reflect[Target[_]].isEmpty) Nil
else {
Seq(ctx.applyPrefixColor("\nTargets:").toString) ++
m.millInternal.reflect[Target[_]].sortBy(_.label).map(t =>
"\n ." + t.label + "()"
)
})
)
case t: mill.define.Target[_] if evaluator.rootModule.millInternal.targets.contains(t) =>
val seen = mutable.Set.empty[Task[_]]
def rec(t: Task[_]): Seq[Segments] = {
if (seen(t)) Nil // do nothing
else t match {
case t: Target[_] if evaluator.rootModule.millInternal.targets.contains(t) =>
Seq(t.ctx.segments)
case _ =>
seen.add(t)
t.inputs.flatMap(rec)
}
}
pprint.Tree.Lazy(ctx =>
Iterator(t.ctx.enclosing, ":", t.ctx.lineNum.toString, "\n", ctx.applyPrefixColor("Inputs:").toString) ++
t.inputs.iterator.flatMap(rec).map("\n " + _.render)
)
}
val pprinter = pprinter0.copy(
additionalHandlers = millHandlers orElse pprinter0.additionalHandlers
)
}
|