Skip to content

Commit

Permalink
Introduce os.proc.env DynamicVariable to override default env
Browse files Browse the repository at this point in the history
In Mill and any client-server application, it is handy to start processes on the server passing the
client environment. This requires to pass the environment manually in all the `os.proc(...).call()`s.
An easier alternative is to override the environment as we to for `os.Inherit` `out`, `in` and `err` pipes.
So users can forget about the environment and have the right one passed automatically.
  • Loading branch information
lolgab committed Aug 29, 2024
1 parent c36de15 commit 3a39ce1
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 8 deletions.
24 changes: 16 additions & 8 deletions os/src/ProcessOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ case class proc(command: Shellable*) {
def pipeTo(next: proc): ProcGroup = ProcGroup(Seq(this, next))
}

object proc {
val env = new scala.util.DynamicVariable[Map[String, String]](sys.env)
}

/**
* A group of processes that are piped together, corresponding to e.g. `ls -l | grep .scala`.
* You can create a `ProcGroup` by calling `.pipeTo` on a [[proc]] multiple times.
Expand Down Expand Up @@ -423,18 +427,22 @@ private[os] object ProcessOps {
val builder = new java.lang.ProcessBuilder()

val environment = builder.environment()
environment.clear()

if (!propagateEnv) {
environment.clear()
}

if (env != null) {
for ((k, v) <- env) {
if (v != null) builder.environment().put(k, v)
else builder.environment().remove(k)
def addToProcessEnv(env: Map[String, String]) =
if (env != null) {
for ((k, v) <- env) {
if (v != null) builder.environment().put(k, v)
else builder.environment().remove(k)
}
}

if (propagateEnv) {
addToProcessEnv(os.proc.env.value)
}

addToProcessEnv(env)

builder.directory(Option(cwd).getOrElse(os.pwd).toIO)

builder
Expand Down
16 changes: 16 additions & 0 deletions os/test/src/SubprocessTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,22 @@ object SubprocessTests extends TestSuite {
}
}
}
test("envWithValue") {
if (Unix()) {
def envValue() = os.proc("bash", "-c", "echo \"$TEST_ENV_FOO\"").call().out.lines().head

val before = envValue()
assert(before == "")

os.proc.env.withValue(Map("TEST_ENV_FOO" -> "bar")) {
val res = envValue()
assert(res == "bar")
}

val after = envValue()
assert(after == "")
}
}
test("multiChunk") {
// Make sure that in the case where multiple chunks are being read from
// the subprocess in quick succession, we ensure that the output handler
Expand Down

0 comments on commit 3a39ce1

Please sign in to comment.