diff --git a/Readme.adoc b/Readme.adoc index 4c36e35b..125fe60e 100644 --- a/Readme.adoc +++ b/Readme.adoc @@ -1828,8 +1828,8 @@ wd / os.up wd / os.up / os.up ---- -Note that there are no in-built operations to change the `os.pwd`. In general, -you should not need to: simply defining a new path, e.g. +`os.pwd` can be modified in certain scopes via the `os.dynamicPwd` dynamic variable, but +best practice is not to change it. Instead simply define a new path, e.g. [source,scala] ---- diff --git a/os/src-jvm/package.scala b/os/src-jvm/package.scala index e5053657..d11a54d6 100644 --- a/os/src-jvm/package.scala +++ b/os/src-jvm/package.scala @@ -2,6 +2,7 @@ import scala.language.implicitConversions import java.nio.file.FileSystem import java.nio.file.FileSystems import java.nio.file.Paths +import scala.util.DynamicVariable package object os { type Generator[+T] = geny.Generator[T] @@ -38,7 +39,9 @@ package object os { /** * The current working directory for this process. */ - val pwd: Path = os.Path(java.nio.file.Paths.get(".").toAbsolutePath) + def pwd: Path = dynamicPwd.value + val dynamicPwd: DynamicVariable[Path] = + new DynamicVariable(os.Path(java.nio.file.Paths.get(".").toAbsolutePath)) val up: RelPath = RelPath.up diff --git a/os/src-native/package.scala b/os/src-native/package.scala index ea021c90..e71aac1a 100644 --- a/os/src-native/package.scala +++ b/os/src-native/package.scala @@ -1,5 +1,6 @@ import java.nio.file.FileSystem import java.nio.file.FileSystems +import scala.util.DynamicVariable package object os { type Generator[+T] = geny.Generator[T] val Generator = geny.Generator @@ -31,7 +32,9 @@ package object os { /** * The current working directory for this process. */ - val pwd: Path = os.Path(java.nio.file.Paths.get(".").toAbsolutePath) + def pwd: Path = dynamicPwd.value + val dynamicPwd: DynamicVariable[Path] = + new DynamicVariable(os.Path(java.nio.file.Paths.get(".").toAbsolutePath)) val up: RelPath = RelPath.up diff --git a/os/test/src/PathTests.scala b/os/test/src/PathTests.scala index 98aa6ae4..365b1647 100644 --- a/os/test/src/PathTests.scala +++ b/os/test/src/PathTests.scala @@ -434,6 +434,14 @@ object PathTests extends TestSuite { System.err.printf("p[%s]\n", posix(p)) assert(posix(p) contains "/omg") } + test("dynamicPwd") { + val x = os.pwd + val y = os.dynamicPwd.withValue(os.pwd / "hello") { + os.pwd + } + + assert(x / "hello" == y) + } } // compare absolute paths def sameFile(a: java.nio.file.Path, b: java.nio.file.Path): Boolean = { diff --git a/os/test/src/SubprocessTests.scala b/os/test/src/SubprocessTests.scala index ac01bd41..0a240ba2 100644 --- a/os/test/src/SubprocessTests.scala +++ b/os/test/src/SubprocessTests.scala @@ -225,5 +225,24 @@ object SubprocessTests extends TestSuite { assert(output.out.lines() == Seq("HELLO /usr")) } } + test("dynamicPwd") { + // Windows doesnt have bash installed so a bit inconvenient + // to run these subprocesses for testing + if (!scala.util.Properties.isWin) { + val outsidePwd = os.pwd + val tmp0 = os.temp.dir() + val tmp = os.followLink(tmp0).getOrElse(tmp0) + val x = proc("bash", "-c", "pwd").call() + val y = os.dynamicPwd.withValue(tmp) { + proc("bash", "-c", "pwd").call() + } + + val z = proc("bash", "-c", "pwd").call() + assert(outsidePwd.toString != tmp.toString) + assert(x.out.trim() == outsidePwd.toString) + assert(y.out.trim() == tmp.toString) + assert(z.out.trim() == outsidePwd.toString) + } + } } }