Skip to content

Commit 353efb6

Browse files
committed
update
1 parent b292fb3 commit 353efb6

File tree

6 files changed

+262
-158
lines changed

6 files changed

+262
-158
lines changed

core/codesig/src/mill/codesig/ReachabilityAnalysis.scala

+5-17
Original file line numberDiff line numberDiff line change
@@ -82,19 +82,18 @@ class CallGraphAnalysis(
8282
logger.mandatoryLog(transitiveCallGraphHashes0)
8383
logger.log(transitiveCallGraphHashes)
8484

85-
lazy val (spanningInvalidationTree: Obj, invalidClassNames: Arr) = prevTransitiveCallGraphHashesOpt() match {
85+
lazy val (spanningInvalidationTree: Obj) = prevTransitiveCallGraphHashesOpt() match {
8686
case Some(prevTransitiveCallGraphHashes) =>
8787
CallGraphAnalysis.spanningInvalidationTree(
8888
prevTransitiveCallGraphHashes,
8989
transitiveCallGraphHashes0,
9090
indexToNodes,
9191
indexGraphEdges
9292
)
93-
case None => ujson.Obj() -> ujson.Arr()
93+
case None => ujson.Obj()
9494
}
9595

9696
logger.mandatoryLog(spanningInvalidationTree)
97-
logger.mandatoryLog(invalidClassNames)
9897
}
9998

10099
object CallGraphAnalysis {
@@ -117,7 +116,7 @@ object CallGraphAnalysis {
117116
transitiveCallGraphHashes0: Array[(CallGraphAnalysis.Node, Int)],
118117
indexToNodes: Array[Node],
119118
indexGraphEdges: Array[Array[Int]]
120-
): (ujson.Obj, ujson.Arr) = {
119+
): ujson.Obj = {
121120
val transitiveCallGraphHashes0Map = transitiveCallGraphHashes0.toMap
122121

123122
val nodesWithChangedHashes = indexGraphEdges
@@ -137,23 +136,12 @@ object CallGraphAnalysis {
137136
val reverseGraphEdges =
138137
indexGraphEdges.indices.map(reverseGraphMap.getOrElse(_, Array[Int]())).toArray
139138

140-
val spanningForest = SpanningForest.apply(reverseGraphEdges, nodesWithChangedHashes, false)
141-
142139
val spanningInvalidationTree = SpanningForest.spanningTreeToJsonTree(
143-
spanningForest,
140+
SpanningForest.apply(reverseGraphEdges, nodesWithChangedHashes, false),
144141
k => indexToNodes(k).toString
145142
)
146143

147-
val invalidSet = invalidClassNameSet(
148-
spanningForest,
149-
indexToNodes.map {
150-
case LocalDef(call) => call.cls.name
151-
case Call(call) => call.cls.name
152-
case ExternalClsCall(cls) => cls.name
153-
}
154-
)
155-
156-
(spanningInvalidationTree, invalidSet)
144+
spanningInvalidationTree
157145
}
158146

159147
def indexGraphEdges(

core/define/src/mill/define/Task.scala

+16-5
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,16 @@ object Task extends TaskBase {
121121
inline def Command[T](inline t: Result[T])(implicit
122122
inline w: W[T],
123123
inline ctx: mill.define.Ctx
124-
): Command[T] = ${ TaskMacros.commandImpl[T]('t)('w, 'ctx, exclusive = '{ false }) }
124+
): Command[T] = ${ TaskMacros.commandImpl[T]('t)('w, 'ctx, exclusive = '{ false }, persistent = '{ false }) }
125+
126+
127+
/**
128+
* This version allow [[Command]] to be persistent
129+
*/
130+
inline def Command[T](inline persistent: Boolean)(inline t: Result[T])(implicit
131+
inline w: W[T],
132+
inline ctx: mill.define.Ctx
133+
): Command[T] = ${ TaskMacros.commandImpl[T]('t)('w, 'ctx, exclusive = '{ false }, persistent = '{ persistent }) }
125134

126135
/**
127136
* @param exclusive Exclusive commands run serially at the end of an evaluation,
@@ -139,7 +148,7 @@ object Task extends TaskBase {
139148
inline def apply[T](inline t: Result[T])(implicit
140149
inline w: W[T],
141150
inline ctx: mill.define.Ctx
142-
): Command[T] = ${ TaskMacros.commandImpl[T]('t)('w, 'ctx, '{ this.exclusive }) }
151+
): Command[T] = ${ TaskMacros.commandImpl[T]('t)('w, 'ctx, '{ this.exclusive }, '{ false }) }
143152
}
144153

145154
/**
@@ -390,7 +399,8 @@ class Command[+T](
390399
val ctx0: mill.define.Ctx,
391400
val writer: W[?],
392401
val isPrivate: Option[Boolean],
393-
val exclusive: Boolean
402+
val exclusive: Boolean,
403+
override val persistent: Boolean
394404
) extends NamedTask[T] {
395405

396406
override def asCommand: Some[Command[T]] = Some(this)
@@ -537,12 +547,13 @@ private object TaskMacros {
537547
)(t: Expr[Result[T]])(
538548
w: Expr[W[T]],
539549
ctx: Expr[mill.define.Ctx],
540-
exclusive: Expr[Boolean]
550+
exclusive: Expr[Boolean],
551+
persistent: Expr[Boolean]
541552
): Expr[Command[T]] = {
542553
appImpl[Command, T](
543554
(in, ev) =>
544555
'{
545-
new Command[T]($in, $ev, $ctx, $w, ${ taskIsPrivate() }, exclusive = $exclusive)
556+
new Command[T]($in, $ev, $ctx, $w, ${ taskIsPrivate() }, exclusive = $exclusive, persistent = $persistent)
546557
},
547558
t
548559
)

runner/src/mill/runner/MillBuildRootModule.scala

+25
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import scala.util.Try
1919

2020
import mill.define.Target
2121
import mill.runner.worker.api.MillScalaParser
22+
import mill.codesig.JvmModel.MethodDef
23+
import mill.codesig.JvmModel.MethodSig
2224

2325
/**
2426
* Mill module for pre-processing a Mill `build.mill` and related files and then
@@ -138,6 +140,29 @@ abstract class MillBuildRootModule()(implicit
138140
}
139141
}
140142

143+
@internal
144+
override protected def callGraphAnalysisIgnoreCalls(callSiteOpt: Option[MethodDef], calledSig: MethodSig): Boolean = {
145+
// We ignore Commands for the same reason as we ignore Targets, and also because
146+
// their implementations get gathered up all the via the `Discover` macro, but this
147+
// is primarily for use as external entrypoints and shouldn't really be counted as
148+
// part of the `millbuild.build#<init>` transitive call graph they would normally
149+
// be counted as
150+
def isCommand =
151+
calledSig.desc.ret.pretty == classOf[mill.define.Command[?]].getName
152+
153+
// Skip calls to `millDiscover`. `millDiscover` is bundled as part of `RootModule` for
154+
// convenience, but it should really never be called by any normal Mill module/task code,
155+
// and is only used by downstream code in `mill.eval`/`mill.resolve`. Thus although CodeSig's
156+
// conservative analysis considers potential calls from `build_.package_$#<init>` to
157+
// `millDiscover()`, we can safely ignore that possibility
158+
def isMillDiscover =
159+
calledSig.name == "millDiscover$lzyINIT1" ||
160+
calledSig.name == "millDiscover" ||
161+
callSiteOpt.exists(_.sig.name == "millDiscover")
162+
163+
super.callGraphAnalysisIgnoreCalls(callSiteOpt, calledSig) || isCommand || isMillDiscover
164+
}
165+
141166
def codeSignatures: T[Map[String, Int]] = Task {
142167
val (analysisFolder, _) = callGraphAnalysis()
143168
val transitiveCallGraphHashes0 = upickle.default.read[Map[String, Int]](

0 commit comments

Comments
 (0)