Skip to content

Commit 487e481

Browse files
authored
Make run commands exclusive (#6220)
As part of this, loosened up handling of `exclusive` commands such that downstream commands not marked as `exclusive` are automatically treated as such. This is to avoid breakage of anyone who is currently defining an `override def run() = Task.Command{ super.run()() }`, which would otherwise start failing since `super.run` has suddenly become `exclusive`. Only downstream commands are treated as such - non-command tasks are still an error - and I expect this is an uncommon enough scenario that it won't affect much Also cleaned up the messiness in `BspRunModule` and tweaked `bspRun` to avoid the `Task.Anon` that would interfere with exclusivity Fix #5208
1 parent c0a6c2e commit 487e481

File tree

7 files changed

+160
-156
lines changed

7 files changed

+160
-156
lines changed

core/exec/src/mill/exec/Execution.scala

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,16 @@ case class Execution(
144144
def formatHeaderPrefix(countMsg: String, keySuffix: String) =
145145
s"$countMsg$keySuffix${Execution.formatFailedCount(rootFailedCount.get())}"
146146

147+
val tasksTransitive = PlanImpl.transitiveTasks(Seq.from(indexToTerminal)).toSet
148+
val downstreamEdges: Map[Task[?], Set[Task[?]]] =
149+
tasksTransitive.flatMap(t => t.inputs.map(_ -> t)).groupMap(_._1)(_._2)
150+
151+
val allExclusiveCommands = tasksTransitive.filter(_.isExclusiveCommand)
152+
val downstreamOfExclusive =
153+
mill.internal.SpanningForest.breadthFirst[Task[?]](allExclusiveCommands)(t =>
154+
downstreamEdges.getOrElse(t, Set())
155+
)
156+
147157
def evaluateTerminals(
148158
terminals: Seq[Task[?]],
149159
exclusive: Boolean
@@ -163,9 +173,9 @@ case class Execution(
163173
val group = plan.sortedGroups.lookupKey(terminal)
164174
val exclusiveDeps = deps.filter(d => d.isExclusiveCommand)
165175

166-
if (!terminal.isExclusiveCommand && exclusiveDeps.nonEmpty) {
176+
if (terminal.asCommand.isEmpty && downstreamOfExclusive.contains(terminal)) {
167177
val failure = ExecResult.Failure(
168-
s"Non-exclusive task ${terminal} cannot depend on exclusive task " +
178+
s"Non-Command task ${terminal} cannot depend on exclusive command " +
169179
exclusiveDeps.mkString(", ")
170180
)
171181
val taskResults: Map[Task[?], ExecResult.Failing[Nothing]] = group
@@ -285,20 +295,14 @@ case class Execution(
285295
terminals.map(t => (t, Await.result(futures(t), duration.Duration.Inf)))
286296
}
287297

288-
val tasks0 = indexToTerminal.filter {
289-
case _: Task.Command[_] => false
290-
case _ => true
291-
}
292-
293-
val tasksTransitive = PlanImpl.transitiveTasks(Seq.from(tasks0)).toSet
294-
val (tasks, leafExclusiveCommands) = indexToTerminal.partition {
295-
case t: Task.Named[_] => tasksTransitive.contains(t) || !t.isExclusiveCommand
298+
val (nonExclusiveTasks, leafExclusiveCommands) = indexToTerminal.partition {
299+
case t: Task.Named[_] => !downstreamOfExclusive.contains(t)
296300
case _ => !serialCommandExec
297301
}
298302

299303
// Run all non-command tasks according to the threads
300304
// given but run the commands in linear order
301-
val nonExclusiveResults = evaluateTerminals(tasks, exclusive = false)
305+
val nonExclusiveResults = evaluateTerminals(nonExclusiveTasks, exclusive = false)
302306

303307
val exclusiveResults = evaluateTerminals(leafExclusiveCommands, exclusive = true)
304308

integration/failure/non-exclusive-depends-on-exclusive/resources/build.mill

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@ import mill._
33
import mill.api.Evaluator
44

55
def foo = Task { 1 }
6-
def cleanClientWrong(ev: Evaluator) = Task.Command {
7-
clean(ev, "foo")()
6+
def cleanClientWrong = Task {
7+
cleanClientRight()()
88
println("cleanClientWrong done")
99
}
1010

11-
def cleanClientRight(ev: Evaluator) = Task.Command(exclusive = true) {
12-
clean(ev, "foo")()
11+
def cleanClientRight() = Task.Command(exclusive = true) {
1312
println("cleanClientRight done")
1413
}
14+
15+
def cleanClientDownstream() = Task.Command() {
16+
cleanClientRight()()
17+
println("cleanClientDownstream done")
18+
}

integration/failure/non-exclusive-depends-on-exclusive/src/NonExclusiveDependsOnExclusive.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ object NonExclusiveDependsOnExclusive extends UtestIntegrationTestSuite {
1010
val res = tester.eval("cleanClientWrong")
1111
assert(res.isSuccess == false)
1212
assert(res.err.contains(
13-
"Non-exclusive task cleanClientWrong cannot depend on exclusive task clean"
13+
"cleanClientWrong Non-Command task cleanClientWrong cannot depend on exclusive command cleanClientRight"
1414
))
1515
assert(!res.out.contains("cleanClientWrong done"))
1616
}
@@ -20,5 +20,10 @@ object NonExclusiveDependsOnExclusive extends UtestIntegrationTestSuite {
2020
assert(res.out.contains("cleanClientRight done"))
2121

2222
}
23+
test("downstream") - integrationTest { tester =>
24+
val res = tester.eval("cleanClientDownstream")
25+
assert(res.isSuccess == true)
26+
assert(res.out.contains("cleanClientDownstream done"))
27+
}
2328
}
2429
}

integration/feature/full-run-logs/src/FullRunLogsTests.scala

Lines changed: 63 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ object FullRunLogsTests extends UtestIntegrationTestSuite {
4747

4848
assertGoldenLiteral(
4949
normalize(res.out),
50-
List("<digits>] run <h1>hello</h1>")
50+
List("<h1>hello</h1>")
5151
)
5252

5353
assertGoldenLiteral(
@@ -58,6 +58,7 @@ object FullRunLogsTests extends UtestIntegrationTestSuite {
5858
"build.mill-<digits>] done compiling",
5959
"<digits>] compile compiling 1 Java source to out/compile.dest/classes ...",
6060
"<digits>] done compiling",
61+
"<digits>] run",
6162
"63/<digits>] ============================== run --text hello =============================="
6263
)
6364
)
@@ -190,67 +191,67 @@ object FullRunLogsTests extends UtestIntegrationTestSuite {
190191
assertGoldenLiteral(
191192
normalize(res.result.out.text()),
192193
List(
193-
"<digits>] test.run (R)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_1(X)",
194-
"<digits>] (R)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_2(X)",
195-
"<digits>] (R)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_3(X)",
196-
"<digits>] (R)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_4(X)",
197-
"<digits>] (R)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_5(X)",
198-
"<digits>] (R)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_6(X)",
199-
"<digits>] (R)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_7(X)",
200-
"<digits>] (R)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_8(X)",
201-
"<digits>] (R)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_9(X)",
202-
"<digits>] (R)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_10(X)",
203-
"<digits>] (G)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_11(X)",
204-
"<digits>] (G)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_12(X)",
205-
"<digits>] (G)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_13(X)",
206-
"<digits>] (G)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_14(X)",
207-
"<digits>] (G)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_15(X)",
208-
"<digits>] (G)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_16(X)",
209-
"<digits>] (G)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_17(X)",
210-
"<digits>] (G)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_18(X)",
211-
"<digits>] (G)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_19(X)",
212-
"<digits>] (G)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_20(X)",
213-
"<digits>] (B)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_21(X)",
214-
"<digits>] (B)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_22(X)",
215-
"<digits>] (B)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_23(X)",
216-
"<digits>] (B)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_24(X)",
217-
"<digits>] (B)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_25(X)",
218-
"<digits>] (B)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_26(X)",
219-
"<digits>] (B)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_27(X)",
220-
"<digits>] (B)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_28(X)",
221-
"<digits>] (B)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_29(X)",
222-
"<digits>] (B)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_30(X)",
223-
"<digits>] (C)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_31(X)",
224-
"<digits>] (C)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_32(X)",
225-
"<digits>] (C)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_33(X)",
226-
"<digits>] (C)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_34(X)",
227-
"<digits>] (C)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_35(X)",
228-
"<digits>] (C)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_36(X)",
229-
"<digits>] (C)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_37(X)",
230-
"<digits>] (C)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_38(X)",
231-
"<digits>] (C)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_39(X)",
232-
"<digits>] (C)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_40(X)",
233-
"<digits>] (M)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_41(X)",
234-
"<digits>] (M)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_42(X)",
235-
"<digits>] (M)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_43(X)",
236-
"<digits>] (M)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_44(X)",
237-
"<digits>] (M)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_45(X)",
238-
"<digits>] (M)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_46(X)",
239-
"<digits>] (M)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_47(X)",
240-
"<digits>] (M)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_48(X)",
241-
"<digits>] (M)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_49(X)",
242-
"<digits>] (M)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_50(X)",
243-
"<digits>] (Y)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_51(X)",
244-
"<digits>] (Y)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_52(X)",
245-
"<digits>] (Y)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_53(X)",
246-
"<digits>] (Y)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_54(X)",
247-
"<digits>] (Y)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_55(X)",
248-
"<digits>] (Y)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_56(X)",
249-
"<digits>] (Y)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_57(X)",
250-
"<digits>] (Y)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_58(X)",
251-
"<digits>] (Y)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_59(X)",
252-
"<digits>] (Y)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_60(X)",
253-
"<digits>] "
194+
"(R)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_1",
195+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_2",
196+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_3",
197+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_4",
198+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_5",
199+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_6",
200+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_7",
201+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_8",
202+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_9",
203+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_10",
204+
"(G)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_11",
205+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_12",
206+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_13",
207+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_14",
208+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_15",
209+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_16",
210+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_17",
211+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_18",
212+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_19",
213+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_20",
214+
"(B)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_21",
215+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_22",
216+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_23",
217+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_24",
218+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_25",
219+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_26",
220+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_27",
221+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_28",
222+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_29",
223+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_30",
224+
"(C)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_31",
225+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_32",
226+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_33",
227+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_34",
228+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_35",
229+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_36",
230+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_37",
231+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_38",
232+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_39",
233+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_40",
234+
"(M)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_41",
235+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_42",
236+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_43",
237+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_44",
238+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_45",
239+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_46",
240+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_47",
241+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_48",
242+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_49",
243+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_50",
244+
"(Y)ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_51",
245+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_52",
246+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_53",
247+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_54",
248+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_55",
249+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_56",
250+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_57",
251+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_58",
252+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_59",
253+
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ_60",
254+
"(X)"
254255
)
255256
)
256257
// Sometimes order can be mixed up between stdout and stderr, even with mergeErrIntoOut

libs/javalib/src/mill/javalib/RunModule.scala

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,7 @@ import mill.constants.EnvVars
2424
*/
2525
trait RunModule extends WithJvmWorkerModule with RunModuleApi {
2626

27-
private lazy val bspExt = {
28-
import BspRunModule.given
29-
ModuleRef(this.internalBspRunModule)
30-
}
27+
private lazy val bspExt = ModuleRef(new BspRunModule(this) {}.internalBspRunModule)
3128

3229
private[mill] def bspRunModule: () => BspRunModuleApi = () => bspExt()
3330

@@ -114,26 +111,28 @@ trait RunModule extends WithJvmWorkerModule with RunModuleApi {
114111
/**
115112
* Runs this module's code in a subprocess and waits for it to finish
116113
*/
117-
def run(args: Task[Args] = Task.Anon(Args())): Task.Command[Unit] = Task.Command {
118-
runForkedTask(finalMainClass, args)()
119-
}
114+
def run(args: Task[Args] = Task.Anon(Args())): Task.Command[Unit] =
115+
Task.Command(exclusive = true) {
116+
runForkedTask(finalMainClass, args)()
117+
}
120118

121119
/**
122120
* Runs this module's code in-process within an isolated classloader. This is
123121
* faster than `run`, but in exchange you have less isolation between runs
124122
* since the code can dirty the parent Mill process and potentially leave it
125123
* in a bad state.
126124
*/
127-
def runLocal(args: Task[Args] = Task.Anon(Args())): Task.Command[Unit] = Task.Command {
128-
runLocalTask(finalMainClass, args)()
129-
}
125+
def runLocal(args: Task[Args] = Task.Anon(Args())): Task.Command[Unit] =
126+
Task.Command(exclusive = true) {
127+
runLocalTask(finalMainClass, args)()
128+
}
130129

131130
/**
132131
* Same as `run`, but lets you specify a main class to run
133132
*/
134133
def runMain(@arg(positional = true) mainClass: String, args: String*): Task.Command[Unit] = {
135134
val task = runForkedTask(Task.Anon { mainClass }, Task.Anon { Args(args) })
136-
Task.Command { task() }
135+
Task.Command(exclusive = true) { task() }
137136
}
138137

139138
/**
@@ -152,7 +151,7 @@ trait RunModule extends WithJvmWorkerModule with RunModuleApi {
152151
*/
153152
def runMainLocal(@arg(positional = true) mainClass: String, args: String*): Task.Command[Unit] = {
154153
val task = runLocalTask(Task.Anon { mainClass }, Task.Anon { Args(args) })
155-
Task.Command { task() }
154+
Task.Command(exclusive = true) { task() }
156155
}
157156

158157
/**

0 commit comments

Comments
 (0)