@@ -149,17 +149,22 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers {
149
149
val onExitProcess = process.onExit().thenApply { p1 =>
150
150
val retCode = p1.exitValue()
151
151
onExitOpt.foreach(_())
152
- if (retCode != 0 )
153
- if (allowTerminate)
152
+ (retCode, allowTerminate) match {
153
+ case (0 , true ) =>
154
+ case (0 , false ) =>
155
+ val gray = " \u001b [90m"
156
+ val reset = Console .RESET
157
+ System .err.println(s " ${gray}Program exited with return code $retCode. $reset" )
158
+ case (_, true ) =>
154
159
sys.exit(retCode)
155
- else {
160
+ case (_, false ) =>
156
161
val red = Console .RED
157
162
val lightRed = " \u001b [91m"
158
163
val reset = Console .RESET
159
164
System .err.println(
160
165
s " ${red}Program exited with return code $lightRed$retCode$red. $reset"
161
166
)
162
- }
167
+ }
163
168
}
164
169
165
170
Some ((process, onExitProcess))
@@ -191,7 +196,9 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers {
191
196
)
192
197
193
198
if (options.sharedRun.watch.watchMode) {
194
- var processOpt = Option .empty[(Process , CompletableFuture [_])]
199
+ var processOpt = Option .empty[(Process , CompletableFuture [_])]
200
+ var shouldReadInput = false
201
+ var mainThreadOpt = Option .empty[Thread ]
195
202
val watcher = Build .watch(
196
203
inputs,
197
204
initialBuildOptions,
@@ -202,16 +209,23 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers {
202
209
buildTests = false ,
203
210
partial = None ,
204
211
actionableDiagnostics = actionableDiagnostics,
205
- postAction = () => WatchUtil .printWatchMessage()
212
+ postAction = () =>
213
+ if (processOpt.exists(_._1.isAlive()))
214
+ WatchUtil .printWatchWhileRunningMessage()
215
+ else
216
+ WatchUtil .printWatchMessage()
206
217
) { res =>
207
218
for ((process, onExitProcess) <- processOpt) {
208
219
onExitProcess.cancel(true )
209
220
ProcUtil .interruptProcess(process, logger)
210
221
}
211
222
res.orReport(logger).map(_.main).foreach {
212
223
case s : Build .Successful =>
213
- for ((proc, _) <- processOpt) // If the process doesn't exit, send SIGKILL
214
- if (proc.isAlive) ProcUtil .forceKillProcess(proc, logger)
224
+ for ((proc, _) <- processOpt if proc.isAlive)
225
+ // If the process doesn't exit, send SIGKILL
226
+ ProcUtil .forceKillProcess(proc, logger)
227
+ shouldReadInput = false
228
+ mainThreadOpt.foreach(_.interrupt())
215
229
val maybeProcess = maybeRun(
216
230
s,
217
231
allowTerminate = false ,
@@ -221,18 +235,34 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers {
221
235
)
222
236
.orReport(logger)
223
237
.flatten
238
+ .map {
239
+ case (proc, onExit) =>
240
+ if (options.sharedRun.watch.restart)
241
+ onExit.thenApply { _ =>
242
+ shouldReadInput = true
243
+ mainThreadOpt.foreach(_.interrupt())
244
+ }
245
+ (proc, onExit)
246
+ }
224
247
s.copyOutput(options.shared)
225
248
if (options.sharedRun.watch.restart)
226
249
processOpt = maybeProcess
227
- else
250
+ else {
228
251
for ((proc, onExit) <- maybeProcess)
229
252
ProcUtil .waitForProcess(proc, onExit)
253
+ shouldReadInput = true
254
+ mainThreadOpt.foreach(_.interrupt())
255
+ }
230
256
case _ : Build .Failed =>
231
257
System .err.println(" Compilation failed" )
232
258
}
233
259
}
234
- try WatchUtil .waitForCtrlC(() => watcher.schedule())
235
- finally watcher.dispose()
260
+ mainThreadOpt = Some (Thread .currentThread())
261
+ try WatchUtil .waitForCtrlC(() => watcher.schedule(), () => shouldReadInput)
262
+ finally {
263
+ mainThreadOpt = None
264
+ watcher.dispose()
265
+ }
236
266
}
237
267
else {
238
268
val builds =
0 commit comments