From 5badefea73271042658daf0ee923f82fc32b1382 Mon Sep 17 00:00:00 2001 From: Li Haoyi <haoyi.sg@gmail.com> Date: Tue, 10 Sep 2024 12:52:14 +0800 Subject: [PATCH] Fix `ScalaModule#console` by properly inheriting streams (#3500) `SystemStreamswithStreams(SystemStreams.original)` didn't quite do the right thing because it continued to use the `PumpedProcess*put`s for subprocesses rather than directly inheriting the streams. This fixes it. Tested manually via `./mill dist.launcher && (cd example/scalalib/basic/1-simple && ../../../../out/dist/launcher.dest/run -i console)`, which previously would print `Unable to create system terminal` and not allow keyboard navigation in the REPL, and with this PR it no longer warns and keyboard navigation works correctly Fixes https://github.com/com-lihaoyi/mill/issues/3491 --- main/api/src/mill/api/SystemStreams.scala | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/main/api/src/mill/api/SystemStreams.scala b/main/api/src/mill/api/SystemStreams.scala index 55ed8598ca9..5b687d18191 100644 --- a/main/api/src/mill/api/SystemStreams.scala +++ b/main/api/src/mill/api/SystemStreams.scala @@ -66,15 +66,32 @@ object SystemStreams { val out = System.out val err = System.err try { + // If we are setting a stream back to its original value, make sure we reset + // `os.Inherit` to `os.InheritRaw` for that stream. This direct inheritance + // ensures that interactive applications involving console IO work, as the + // presence of a `PumpedProcess` would cause most interactive CLIs (e.g. + // scala console, REPL, etc.) to misbehave + val inheritIn = + if (systemStreams.in eq original.in) os.InheritRaw + else new PumpedProcessInput + + val inheritOut = + if (systemStreams.out eq original.out) os.InheritRaw + else new PumpedProcessOutput(systemStreams.out) + + val inheritErr = + if (systemStreams.err eq original.err) os.InheritRaw + else new PumpedProcessOutput(systemStreams.err) + System.setIn(systemStreams.in) System.setOut(systemStreams.out) System.setErr(systemStreams.err) Console.withIn(systemStreams.in) { Console.withOut(systemStreams.out) { Console.withErr(systemStreams.err) { - os.Inherit.in.withValue(new PumpedProcessInput) { - os.Inherit.out.withValue(new PumpedProcessOutput(System.out)) { - os.Inherit.err.withValue(new PumpedProcessOutput(System.err)) { + os.Inherit.in.withValue(inheritIn) { + os.Inherit.out.withValue(inheritOut) { + os.Inherit.err.withValue(inheritErr) { t } }