From f5af2e5971fbeb5ed55321f9405b847f486f07e9 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Fri, 19 Jul 2024 12:41:08 +0800 Subject: [PATCH 01/10] . --- os/src/ProcessOps.scala | 12 ++++++++++++ os/src/SubProcess.scala | 21 ++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/os/src/ProcessOps.scala b/os/src/ProcessOps.scala index 1ba98468..1e11371b 100644 --- a/os/src/ProcessOps.scala +++ b/os/src/ProcessOps.scala @@ -119,6 +119,18 @@ case class proc(command: Shellable*) { val cmdChunks = commandChunks val commandStr = cmdChunks.mkString(" ") + val resolvedStdin = stdin match { + case os.Inherit => os.Inherit.in + case v => v + } + val resolvedStdout = stdout match { + case os.Inherit => os.Inherit.out + case v => v + } + val resolvedStderr = stderr match { + case os.Inherit => os.Inherit.err + case v => v + } lazy val proc: SubProcess = new SubProcess( builder.start(), stdin.processInput(proc.stdin).map(new Thread(_, commandStr + " stdin thread")), diff --git a/os/src/SubProcess.scala b/os/src/SubProcess.scala index 72f8d7ec..41aca41d 100644 --- a/os/src/SubProcess.scala +++ b/os/src/SubProcess.scala @@ -440,15 +440,34 @@ object ProcessOutput { } /** - * Inherit the input/output stream from the current process + * Inherit the input/output stream from the current process. + * + * Can be overriden on a thread local basis for the various + * kinds of streams (stdin, stdout, stderr) via [[in]], [[out]], and [[err]] */ object Inherit extends ProcessInput with ProcessOutput { def redirectTo = ProcessBuilder.Redirect.INHERIT def redirectFrom = ProcessBuilder.Redirect.INHERIT def processInput(stdin: => SubProcess.InputStream) = None def processOutput(stdin: => SubProcess.OutputStream) = None + + val in = new scala.util.DynamicVariable[ProcessInput](Inherit) + val out = new scala.util.DynamicVariable[ProcessOutput](Inherit) + val err = new scala.util.DynamicVariable[ProcessOutput](Inherit) +} + +/** + * Inherit the input/output stream from the current process. + * Identical of [[os.Inherit]], except it cannot be redirected globally + */ +object Inherit0 extends ProcessInput with ProcessOutput { + def redirectTo = ProcessBuilder.Redirect.INHERIT + def redirectFrom = ProcessBuilder.Redirect.INHERIT + def processInput(stdin: => SubProcess.InputStream) = None + def processOutput(stdin: => SubProcess.OutputStream) = None } + /** * Pipe the input/output stream to the current process to be used via * `java.lang.Process#{getInputStream,getOutputStream,getErrorStream}` From 7492bb2e1f142e60b0b67b8004b4e3a71e3546ee Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Fri, 19 Jul 2024 13:08:30 +0800 Subject: [PATCH 02/10] reformat --- os/src/SubProcess.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/os/src/SubProcess.scala b/os/src/SubProcess.scala index 41aca41d..df75dd27 100644 --- a/os/src/SubProcess.scala +++ b/os/src/SubProcess.scala @@ -467,7 +467,6 @@ object Inherit0 extends ProcessInput with ProcessOutput { def processOutput(stdin: => SubProcess.OutputStream) = None } - /** * Pipe the input/output stream to the current process to be used via * `java.lang.Process#{getInputStream,getOutputStream,getErrorStream}` From d401ecd7fa93b244230e93241fd7cbf6d7681209 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Fri, 19 Jul 2024 15:57:24 +0800 Subject: [PATCH 03/10] . --- os/src/ProcessOps.scala | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/os/src/ProcessOps.scala b/os/src/ProcessOps.scala index 1e11371b..2d2608fa 100644 --- a/os/src/ProcessOps.scala +++ b/os/src/ProcessOps.scala @@ -114,28 +114,31 @@ case class proc(command: Shellable*) { mergeErrIntoOut: Boolean = false, propagateEnv: Boolean = true ): SubProcess = { - val builder = - buildProcess(commandChunks, cwd, env, stdin, stdout, stderr, mergeErrIntoOut, propagateEnv) val cmdChunks = commandChunks val commandStr = cmdChunks.mkString(" ") - val resolvedStdin = stdin match { - case os.Inherit => os.Inherit.in - case v => v - } - val resolvedStdout = stdout match { - case os.Inherit => os.Inherit.out - case v => v - } - val resolvedStderr = stderr match { - case os.Inherit => os.Inherit.err - case v => v - } + + def resolve[T](x: T, y: T) = if (x == os.Inherit) y else x + val resolvedStdin = resolve(stdin, os.Inherit.in.value) + val resolvedStdout = resolve(stdout, os.Inherit.out.value) + val resolvedStderr = resolve(stderr, os.Inherit.err.value) + + val builder = buildProcess( + commandChunks, + cwd, + env, + resolvedStdin, + resolvedStdout, + resolvedStderr, + mergeErrIntoOut, + propagateEnv + ) + lazy val proc: SubProcess = new SubProcess( builder.start(), - stdin.processInput(proc.stdin).map(new Thread(_, commandStr + " stdin thread")), - stdout.processOutput(proc.stdout).map(new Thread(_, commandStr + " stdout thread")), - stderr.processOutput(proc.stderr).map(new Thread(_, commandStr + " stderr thread")) + resolvedStdin.processInput(proc.stdin).map(new Thread(_, commandStr + " stdin thread")), + resolvedStdout.processOutput(proc.stdout).map(new Thread(_, commandStr + " stdout thread")), + resolvedStderr.processOutput(proc.stderr).map(new Thread(_, commandStr + " stderr thread")) ) proc.inputPumperThread.foreach(_.start()) From 719f8b3c19accadffa3aa4e343f292f967263e94 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Fri, 19 Jul 2024 16:24:27 +0800 Subject: [PATCH 04/10] . --- os/test/src/SubprocessTests.scala | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/os/test/src/SubprocessTests.scala b/os/test/src/SubprocessTests.scala index 16eefe93..462febc1 100644 --- a/os/test/src/SubprocessTests.scala +++ b/os/test/src/SubprocessTests.scala @@ -203,5 +203,12 @@ object SubprocessTests extends TestSuite { assert(output.out.lines() == Seq("HELLO /usr")) } } + test("redirectSubprocessInheritedOutput") { + val lines = collection.mutable.Buffer.empty[String] + os.Inherit.out.withValue(os.ProcessOutput.Readlines(lines.append)){ + proc(scriptFolder / "misc" / "echo_with_wd", "HELLO\nWorld").call(cwd = root / "usr", stdout = os.Inherit) + } + assert(lines == Seq("HELLO", "World /usr")) + } } } From 636a4cb5ec3d15c6b762ae1154af6842d69f88bf Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Fri, 19 Jul 2024 16:38:51 +0800 Subject: [PATCH 05/10] . --- os/test/src-jvm/OpTestsJvmOnly.scala | 9 +++++++++ os/test/src/SubprocessTests.scala | 7 ------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/os/test/src-jvm/OpTestsJvmOnly.scala b/os/test/src-jvm/OpTestsJvmOnly.scala index e75e6d07..20ce365b 100644 --- a/os/test/src-jvm/OpTestsJvmOnly.scala +++ b/os/test/src-jvm/OpTestsJvmOnly.scala @@ -70,5 +70,14 @@ object OpTestsJvmOnly extends TestSuite { val d = testFolder / "readWrite" intercept[nio.NoSuchFileException](os.list(d / "nonexistent")) } + + // Not sure why this doesn't work on native + test("redirectSubprocessInheritedOutput") { + val lines = collection.mutable.Buffer.empty[String] + os.Inherit.out.withValue(os.ProcessOutput.Readlines(lines.append(_))) { + proc(scriptFolder / "misc" / "echo_with_wd", "HELLO\nWorld").call(cwd = root / "usr", stdout = os.Inherit) + } + assert(lines == Seq("HELLO", "World /usr")) + } } } diff --git a/os/test/src/SubprocessTests.scala b/os/test/src/SubprocessTests.scala index 462febc1..16eefe93 100644 --- a/os/test/src/SubprocessTests.scala +++ b/os/test/src/SubprocessTests.scala @@ -203,12 +203,5 @@ object SubprocessTests extends TestSuite { assert(output.out.lines() == Seq("HELLO /usr")) } } - test("redirectSubprocessInheritedOutput") { - val lines = collection.mutable.Buffer.empty[String] - os.Inherit.out.withValue(os.ProcessOutput.Readlines(lines.append)){ - proc(scriptFolder / "misc" / "echo_with_wd", "HELLO\nWorld").call(cwd = root / "usr", stdout = os.Inherit) - } - assert(lines == Seq("HELLO", "World /usr")) - } } } From 6f1c697157cc77a2a1ba4e749f33e73b817ac46b Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Fri, 19 Jul 2024 17:06:44 +0800 Subject: [PATCH 06/10] . --- os/test/src-jvm/OpTestsJvmOnly.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/os/test/src-jvm/OpTestsJvmOnly.scala b/os/test/src-jvm/OpTestsJvmOnly.scala index 20ce365b..0f45c27f 100644 --- a/os/test/src-jvm/OpTestsJvmOnly.scala +++ b/os/test/src-jvm/OpTestsJvmOnly.scala @@ -73,9 +73,10 @@ object OpTestsJvmOnly extends TestSuite { // Not sure why this doesn't work on native test("redirectSubprocessInheritedOutput") { + val scriptFolder = os.pwd / "os" / "test" / "resources" / "test" val lines = collection.mutable.Buffer.empty[String] os.Inherit.out.withValue(os.ProcessOutput.Readlines(lines.append(_))) { - proc(scriptFolder / "misc" / "echo_with_wd", "HELLO\nWorld").call(cwd = root / "usr", stdout = os.Inherit) + os.proc(scriptFolder / "misc" / "echo_with_wd", "HELLO\nWorld").call(cwd = root / "usr", stdout = os.Inherit) } assert(lines == Seq("HELLO", "World /usr")) } From f7cdc1ef4b0023ed537532a977e0170a15022b56 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Fri, 19 Jul 2024 17:10:39 +0800 Subject: [PATCH 07/10] . --- os/src/ProcessOps.scala | 2 +- os/test/src-jvm/OpTestsJvmOnly.scala | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/os/src/ProcessOps.scala b/os/src/ProcessOps.scala index 2d2608fa..5983aaa8 100644 --- a/os/src/ProcessOps.scala +++ b/os/src/ProcessOps.scala @@ -121,7 +121,7 @@ case class proc(command: Shellable*) { def resolve[T](x: T, y: T) = if (x == os.Inherit) y else x val resolvedStdin = resolve(stdin, os.Inherit.in.value) val resolvedStdout = resolve(stdout, os.Inherit.out.value) - val resolvedStderr = resolve(stderr, os.Inherit.err.value) + val resolvedStderr = resolve(stderr, os.Inherit.err.value) val builder = buildProcess( commandChunks, diff --git a/os/test/src-jvm/OpTestsJvmOnly.scala b/os/test/src-jvm/OpTestsJvmOnly.scala index 0f45c27f..ce94fbe7 100644 --- a/os/test/src-jvm/OpTestsJvmOnly.scala +++ b/os/test/src-jvm/OpTestsJvmOnly.scala @@ -76,7 +76,10 @@ object OpTestsJvmOnly extends TestSuite { val scriptFolder = os.pwd / "os" / "test" / "resources" / "test" val lines = collection.mutable.Buffer.empty[String] os.Inherit.out.withValue(os.ProcessOutput.Readlines(lines.append(_))) { - os.proc(scriptFolder / "misc" / "echo_with_wd", "HELLO\nWorld").call(cwd = root / "usr", stdout = os.Inherit) + os.proc(scriptFolder / "misc" / "echo_with_wd", "HELLO\nWorld").call( + cwd = os.root / "usr", + stdout = os.Inherit + ) } assert(lines == Seq("HELLO", "World /usr")) } From 92b8f8e9821b7ee89d85a780f2db04025b3fbbf4 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Fri, 19 Jul 2024 17:27:32 +0800 Subject: [PATCH 08/10] . --- os/test/src-jvm/OpTestsJvmOnly.scala | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/os/test/src-jvm/OpTestsJvmOnly.scala b/os/test/src-jvm/OpTestsJvmOnly.scala index ce94fbe7..d42ebf22 100644 --- a/os/test/src-jvm/OpTestsJvmOnly.scala +++ b/os/test/src-jvm/OpTestsJvmOnly.scala @@ -73,15 +73,17 @@ object OpTestsJvmOnly extends TestSuite { // Not sure why this doesn't work on native test("redirectSubprocessInheritedOutput") { - val scriptFolder = os.pwd / "os" / "test" / "resources" / "test" - val lines = collection.mutable.Buffer.empty[String] - os.Inherit.out.withValue(os.ProcessOutput.Readlines(lines.append(_))) { - os.proc(scriptFolder / "misc" / "echo_with_wd", "HELLO\nWorld").call( - cwd = os.root / "usr", - stdout = os.Inherit - ) + if (Unix()) { // relies on bash scripts that don't run on windows + val scriptFolder = os.pwd / "os" / "test" / "resources" / "test" + val lines = collection.mutable.Buffer.empty[String] + os.Inherit.out.withValue(os.ProcessOutput.Readlines(lines.append(_))) { + os.proc(scriptFolder / "misc" / "echo_with_wd", "HELLO\nWorld").call( + cwd = os.root / "usr", + stdout = os.Inherit + ) + } + assert(lines == Seq("HELLO", "World /usr")) } - assert(lines == Seq("HELLO", "World /usr")) } } } From 61e7feba272b4b3f5778f48a45778b64d8876d6a Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Sat, 20 Jul 2024 08:07:53 +0800 Subject: [PATCH 09/10] . --- Readme.adoc | 5 +++++ os/src/SubProcess.scala | 2 +- os/test/src-jvm/OpTestsJvmOnly.scala | 6 ++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Readme.adoc b/Readme.adoc index 888c1727..7a08dbc0 100644 --- a/Readme.adoc +++ b/Readme.adoc @@ -2224,6 +2224,11 @@ string, int or set representations of the `os.PermSet` via: == Changelog +[#0-10-3] +=== 0.10.3 + +* `os.Inherit` + [#0-10-2] === 0.10.2 diff --git a/os/src/SubProcess.scala b/os/src/SubProcess.scala index df75dd27..61961619 100644 --- a/os/src/SubProcess.scala +++ b/os/src/SubProcess.scala @@ -460,7 +460,7 @@ object Inherit extends ProcessInput with ProcessOutput { * Inherit the input/output stream from the current process. * Identical of [[os.Inherit]], except it cannot be redirected globally */ -object Inherit0 extends ProcessInput with ProcessOutput { +object InheritRaw extends ProcessInput with ProcessOutput { def redirectTo = ProcessBuilder.Redirect.INHERIT def redirectFrom = ProcessBuilder.Redirect.INHERIT def processInput(stdin: => SubProcess.InputStream) = None diff --git a/os/test/src-jvm/OpTestsJvmOnly.scala b/os/test/src-jvm/OpTestsJvmOnly.scala index d42ebf22..f5c950bb 100644 --- a/os/test/src-jvm/OpTestsJvmOnly.scala +++ b/os/test/src-jvm/OpTestsJvmOnly.scala @@ -77,10 +77,16 @@ object OpTestsJvmOnly extends TestSuite { val scriptFolder = os.pwd / "os" / "test" / "resources" / "test" val lines = collection.mutable.Buffer.empty[String] os.Inherit.out.withValue(os.ProcessOutput.Readlines(lines.append(_))) { + // Redirected os.proc(scriptFolder / "misc" / "echo_with_wd", "HELLO\nWorld").call( cwd = os.root / "usr", stdout = os.Inherit ) + // Not Redirected + os.proc(scriptFolder / "misc" / "echo_with_wd", "hello\nWORLD").call( + cwd = os.root / "usr", + stdout = os.InheritRaw + ) } assert(lines == Seq("HELLO", "World /usr")) } From 22c94a37228f003c9a6ba01279d3b7f1d2a684f5 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Sat, 20 Jul 2024 08:08:10 +0800 Subject: [PATCH 10/10] . --- Readme.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Readme.adoc b/Readme.adoc index 7a08dbc0..925304ce 100644 --- a/Readme.adoc +++ b/Readme.adoc @@ -2224,8 +2224,8 @@ string, int or set representations of the `os.PermSet` via: == Changelog -[#0-10-3] -=== 0.10.3 +[#main] +=== main * `os.Inherit`