Skip to content

Commit 5a70426

Browse files
[autofix.ci] apply automated fixes
1 parent 353efb6 commit 5a70426

File tree

5 files changed

+141
-138
lines changed

5 files changed

+141
-138
lines changed

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

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package mill.codesig
22

33
import mill.codesig.JvmModel.*
44
import mill.internal.{SpanningForest, Tarjans}
5-
import ujson.{Arr, Obj}
5+
import ujson.Obj
66
import upickle.default.{Writer, writer}
77

88
import scala.collection.immutable.SortedMap
@@ -266,24 +266,6 @@ object CallGraphAnalysis {
266266
}
267267
}
268268

269-
private def invalidClassNameSet(
270-
spanningForest: SpanningForest.Node,
271-
indexToClassName: Array[String]
272-
): Set[String] = {
273-
val queue = mutable.ArrayBuffer.empty[(Int, SpanningForest.Node)]
274-
val result = mutable.Set.empty[String]
275-
276-
queue.appendAll(spanningForest.values)
277-
278-
while (queue.nonEmpty) {
279-
val (index, node) = queue.remove(0)
280-
result += indexToClassName(index)
281-
queue.appendAll(node.values)
282-
}
283-
284-
result.toSet
285-
}
286-
287269
/**
288270
* Represents the three types of nodes in our call graph. These are kept heterogeneous
289271
* because flattening them out into a homogenous graph of MethodDef -> MethodDef edges

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,16 +121,18 @@ 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 }, persistent = '{ false }) }
125-
124+
): Command[T] =
125+
${ TaskMacros.commandImpl[T]('t)('w, 'ctx, exclusive = '{ false }, persistent = '{ false }) }
126126

127127
/**
128128
* This version allow [[Command]] to be persistent
129129
*/
130130
inline def Command[T](inline persistent: Boolean)(inline t: Result[T])(implicit
131131
inline w: W[T],
132132
inline ctx: mill.define.Ctx
133-
): Command[T] = ${ TaskMacros.commandImpl[T]('t)('w, 'ctx, exclusive = '{ false }, persistent = '{ persistent }) }
133+
): Command[T] = ${
134+
TaskMacros.commandImpl[T]('t)('w, 'ctx, exclusive = '{ false }, persistent = '{ persistent })
135+
}
134136

135137
/**
136138
* @param exclusive Exclusive commands run serially at the end of an evaluation,
@@ -553,7 +555,15 @@ private object TaskMacros {
553555
appImpl[Command, T](
554556
(in, ev) =>
555557
'{
556-
new Command[T]($in, $ev, $ctx, $w, ${ taskIsPrivate() }, exclusive = $exclusive, persistent = $persistent)
558+
new Command[T](
559+
$in,
560+
$ev,
561+
$ctx,
562+
$w,
563+
${ taskIsPrivate() },
564+
exclusive = $exclusive,
565+
persistent = $persistent
566+
)
557567
},
558568
t
559569
)

runner/src/mill/runner/MillBuildRootModule.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,10 @@ abstract class MillBuildRootModule()(implicit
141141
}
142142

143143
@internal
144-
override protected def callGraphAnalysisIgnoreCalls(callSiteOpt: Option[MethodDef], calledSig: MethodSig): Boolean = {
144+
override protected def callGraphAnalysisIgnoreCalls(
145+
callSiteOpt: Option[MethodDef],
146+
calledSig: MethodSig
147+
): Boolean = {
145148
// We ignore Commands for the same reason as we ignore Targets, and also because
146149
// their implementations get gathered up all the via the `Discover` macro, but this
147150
// is primarily for use as external entrypoints and shouldn't really be counted as
@@ -159,7 +162,7 @@ abstract class MillBuildRootModule()(implicit
159162
calledSig.name == "millDiscover$lzyINIT1" ||
160163
calledSig.name == "millDiscover" ||
161164
callSiteOpt.exists(_.sig.name == "millDiscover")
162-
165+
163166
super.callGraphAnalysisIgnoreCalls(callSiteOpt, calledSig) || isCommand || isMillDiscover
164167
}
165168

scalalib/src/mill/scalalib/JavaModule.scala

Lines changed: 117 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import mill.util.Jvm
2121
import os.Path
2222
import scala.util.Try
2323
import scala.collection.mutable
24+
2425
/**
2526
* Core configuration required to compile a single Java compilation target
2627
*/
@@ -95,116 +96,122 @@ trait JavaModule
9596
}
9697
}
9798

98-
def testQuick(args: String*): Command[(String, Seq[TestResult])] = Task.Command(persistent = true) {
99-
val quicktestFailedClassesLog = Task.dest / "quickTestFailedClasses.log"
100-
val (analysisFolder, previousAnalysisFolderOpt) = callGraphAnalysis()
101-
val testClasses = testForkGrouping()
102-
val quickTestClassLists = previousAnalysisFolderOpt.fold {
103-
// no previous analysis folder, all classes need to be tested
104-
testClasses
105-
} { _ =>
106-
// get spanning invalidation tree content
107-
val spanningInvalidationTreeObj = Try {
108-
upickle.default.read[ujson.Obj](os.read.stream(analysisFolder / "spanningInvalidationTree.json"))
109-
}.getOrElse(ujson.Obj())
110-
111-
// we cannot parse the json back to its concrete type, we only know that all of them are
112-
// encoded with class name as prefix.
113-
// so we can do a prefix checking to get the affected class.
114-
// naive implementation won't work well as it has loop through all `testClasses` and check prefix
115-
// for all of them, so we employ a prefix trie to speed up the prefix checking.
116-
117-
val jsonValueQueue = mutable.ArrayDeque[(String, ujson.Value)]()
118-
val prefixTrie = new PrefixTrie[String]()
119-
jsonValueQueue.appendAll(spanningInvalidationTreeObj.value)
120-
while (jsonValueQueue.nonEmpty) {
121-
val (nodeStr, value) = jsonValueQueue.removeHead()
122-
val parts = nodeStr
123-
.stripPrefix("def ")
124-
.stripPrefix("call ")
125-
.stripPrefix("external ")
126-
.split("[\\.\\$\\!]")
127-
.map(_.trim())
128-
.toSeq
129-
prefixTrie.insert(parts)
130-
value match {
131-
case ujson.Obj(fieldMap) => jsonValueQueue.appendAll(fieldMap)
132-
case _ => ()
99+
def testQuick(args: String*): Command[(String, Seq[TestResult])] =
100+
Task.Command(persistent = true) {
101+
val quicktestFailedClassesLog = Task.dest / "quickTestFailedClasses.log"
102+
val (analysisFolder, previousAnalysisFolderOpt) = callGraphAnalysis()
103+
val testClasses = testForkGrouping()
104+
val quickTestClassLists = previousAnalysisFolderOpt.fold {
105+
// no previous analysis folder, all classes need to be tested
106+
testClasses
107+
} { _ =>
108+
// get spanning invalidation tree content
109+
val spanningInvalidationTreeObj = Try {
110+
upickle.default.read[ujson.Obj](
111+
os.read.stream(analysisFolder / "spanningInvalidationTree.json")
112+
)
113+
}.getOrElse(ujson.Obj())
114+
115+
// we cannot parse the json back to its concrete type, we only know that all of them are
116+
// encoded with class name as prefix.
117+
// so we can do a prefix checking to get the affected class.
118+
// naive implementation won't work well as it has loop through all `testClasses` and check prefix
119+
// for all of them, so we employ a prefix trie to speed up the prefix checking.
120+
121+
val jsonValueQueue = mutable.ArrayDeque[(String, ujson.Value)]()
122+
val prefixTrie = new PrefixTrie[String]()
123+
jsonValueQueue.appendAll(spanningInvalidationTreeObj.value)
124+
while (jsonValueQueue.nonEmpty) {
125+
val (nodeStr, value) = jsonValueQueue.removeHead()
126+
val parts = nodeStr
127+
.stripPrefix("def ")
128+
.stripPrefix("call ")
129+
.stripPrefix("external ")
130+
.split("[\\.\\$\\!]")
131+
.map(_.trim())
132+
.toSeq
133+
prefixTrie.insert(parts)
134+
value match {
135+
case ujson.Obj(fieldMap) => jsonValueQueue.appendAll(fieldMap)
136+
case _ => ()
137+
}
133138
}
139+
140+
val failedTestClasses =
141+
if (!os.exists(quicktestFailedClassesLog)) {
142+
Set.empty[String]
143+
} else {
144+
Try {
145+
upickle.default.read[Seq[String]](os.read.stream(quicktestFailedClassesLog))
146+
}.getOrElse(Seq.empty[String]).toSet
147+
}
148+
149+
val result = testClasses.map(_.filter { testClassName =>
150+
failedTestClasses.contains(testClassName) || {
151+
val parts = testClassName
152+
.split("\\.")
153+
.map(_.trim())
154+
.toSeq
155+
prefixTrie.contains(parts)
156+
}
157+
}).filter(_.nonEmpty)
158+
// help gc
159+
prefixTrie.clear()
160+
result
134161
}
135162

136-
val failedTestClasses =
137-
if (!os.exists(quicktestFailedClassesLog)) {
138-
Set.empty[String]
139-
} else {
140-
Try {
141-
upickle.default.read[Seq[String]](os.read.stream(quicktestFailedClassesLog))
142-
}.getOrElse(Seq.empty[String]).toSet
143-
}
163+
// Clean up the directory for test runners
164+
os.walk(Task.dest).foreach { subPath => os.remove.all(subPath) }
165+
166+
val quickTestReportXml = testReportXml()
167+
168+
val testModuleUtil = new TestModuleUtil(
169+
testUseArgsFile(),
170+
forkArgs(),
171+
Seq.empty,
172+
zincWorker().scalalibClasspath(),
173+
resources(),
174+
testFramework(),
175+
runClasspath(),
176+
testClasspath(),
177+
args.toSeq,
178+
quickTestClassLists,
179+
zincWorker().testrunnerEntrypointClasspath(),
180+
forkEnv(),
181+
testSandboxWorkingDir(),
182+
forkWorkingDir(),
183+
quickTestReportXml,
184+
zincWorker().javaHome().map(_.path),
185+
testParallelism()
186+
)
144187

145-
val result = testClasses.map(_.filter { testClassName =>
146-
failedTestClasses.contains(testClassName) || {
147-
val parts = testClassName
148-
.split("\\.")
149-
.map(_.trim())
150-
.toSeq
151-
prefixTrie.contains(parts)
152-
}
153-
}).filter(_.nonEmpty)
154-
// help gc
155-
prefixTrie.clear()
156-
result
157-
}
188+
val results = testModuleUtil.runTests()
189+
190+
val badTestClasses = results match {
191+
case Result.Failure(_) =>
192+
// Consider all quick testing classes as failed
193+
quickTestClassLists.flatten
194+
case Result.Success((_, results)) =>
195+
// Get all test classes that failed
196+
results
197+
.filter(testResult => Set("Error", "Failure").contains(testResult.status))
198+
.map(_.fullyQualifiedName)
199+
}
158200

159-
// Clean up the directory for test runners
160-
os.walk(Task.dest).foreach { subPath => os.remove.all(subPath) }
161-
162-
val quickTestReportXml = testReportXml()
163-
164-
val testModuleUtil = new TestModuleUtil(
165-
testUseArgsFile(),
166-
forkArgs(),
167-
Seq.empty,
168-
zincWorker().scalalibClasspath(),
169-
resources(),
170-
testFramework(),
171-
runClasspath(),
172-
testClasspath(),
173-
args.toSeq,
174-
quickTestClassLists,
175-
zincWorker().testrunnerEntrypointClasspath(),
176-
forkEnv(),
177-
testSandboxWorkingDir(),
178-
forkWorkingDir(),
179-
quickTestReportXml,
180-
zincWorker().javaHome().map(_.path),
181-
testParallelism()
182-
)
201+
os.write.over(
202+
quicktestFailedClassesLog,
203+
upickle.default.write[Seq[String]](badTestClasses.distinct)
204+
)
183205

184-
val results = testModuleUtil.runTests()
185-
186-
val badTestClasses = results match {
187-
case Result.Failure(_) =>
188-
// Consider all quick testing classes as failed
189-
quickTestClassLists.flatten
190-
case Result.Success((_, results)) =>
191-
// Get all test classes that failed
192-
results
193-
.filter(testResult => Set("Error", "Failure").contains(testResult.status))
194-
.map(_.fullyQualifiedName)
195-
}
196-
197-
os.write.over(quicktestFailedClassesLog, upickle.default.write[Seq[String]](badTestClasses.distinct))
198-
199-
results match {
200-
case Result.Failure(errMsg) => Result.Failure(errMsg)
201-
case Result.Success((doneMsg, results)) =>
202-
try TestModule.handleResults(doneMsg, results, Task.ctx(), quickTestReportXml)
203-
catch {
204-
case e: Throwable => Result.Failure("Test reporting failed: " + e)
205-
}
206+
results match {
207+
case Result.Failure(errMsg) => Result.Failure(errMsg)
208+
case Result.Success((doneMsg, results)) =>
209+
try TestModule.handleResults(doneMsg, results, Task.ctx(), quickTestReportXml)
210+
catch {
211+
case e: Throwable => Result.Failure("Test reporting failed: " + e)
212+
}
213+
}
206214
}
207-
}
208215
}
209216

210217
def defaultCommandName(): String = "run"
@@ -1496,8 +1503,8 @@ trait JavaModule
14961503

14971504
@internal
14981505
protected def callGraphAnalysisIgnoreCalls(
1499-
callSiteOpt: Option[mill.codesig.JvmModel.MethodDef],
1500-
calledSig: mill.codesig.JvmModel.MethodSig
1506+
callSiteOpt: Option[mill.codesig.JvmModel.MethodDef],
1507+
calledSig: mill.codesig.JvmModel.MethodSig
15011508
): Boolean = {
15021509
// We can ignore all calls to methods that look like Targets when traversing
15031510
// the call graph. We can do this because we assume `def` Targets are pure,
@@ -1534,10 +1541,10 @@ trait JavaModule
15341541
isSimpleTarget(callSiteSig.desc) && calledSig.name.contains("$anonfun")
15351542
)
15361543
}
1537-
1544+
15381545
isSimpleTarget(calledSig.desc) && !isForwarderCallsiteOrLambda
15391546
}
1540-
1547+
15411548
// Return the directory containing the current call graph analysis results, and previous one too if it exists
15421549
def callGraphAnalysis: T[(Path, Option[Path])] = Task(persistent = true) {
15431550
os.remove.all(Task.dest / "previous")
@@ -1548,7 +1555,8 @@ trait JavaModule
15481555
.compute(
15491556
classFiles = os.walk(compile().classes.path).filter(_.ext == "class"),
15501557
upstreamClasspath = compileClasspath().toSeq.map(_.path),
1551-
ignoreCall = (callSiteOpt, calledSig) => callGraphAnalysisIgnoreCalls(callSiteOpt, calledSig),
1558+
ignoreCall =
1559+
(callSiteOpt, calledSig) => callGraphAnalysisIgnoreCalls(callSiteOpt, calledSig),
15521560
logger = new mill.codesig.Logger(
15531561
Task.dest / "current",
15541562
Option.when(debugEnabled)(Task.dest / "current")
@@ -1560,7 +1568,7 @@ trait JavaModule
15601568
)
15611569
)
15621570
)
1563-
1571+
15641572
(Task.dest / "current", Option.when(os.exists(Task.dest / "previous"))(Task.dest / "previous"))
15651573
}
15661574
}

0 commit comments

Comments
 (0)