-
-
Notifications
You must be signed in to change notification settings - Fork 347
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use OS-Lib's pwdDynamicFunction
to allow sandboxing of os.pwd
, write sandboxing doc page, introduce RunModule#runner
#3479
Merged
Merged
Changes from all commits
Commits
Show all changes
38 commits
Select commit
Hold shift + click to select a range
29048c1
.
lihaoyi 1d9fb57
wip
lihaoyi 2503c31
wip
lihaoyi 8bf7299
.
lihaoyi 2b65cca
.
lihaoyi 58a059e
.
lihaoyi 68ec8e2
.
lihaoyi 5fed0e3
.
lihaoyi c5372ad
.
lihaoyi b251aeb
.
lihaoyi 229cc4d
.
lihaoyi f6304a9
.
lihaoyi 796a19e
Merge branch 'main' into dynamic-pwd
lihaoyi bcbe032
.
lihaoyi 12d6cf2
.
lihaoyi 41d6fdd
.
lihaoyi 3a67c34
.
lihaoyi 881faeb
.
lihaoyi ba01da3
.
lihaoyi 6ed6d6f
.
lihaoyi 662c209
.
lihaoyi 9ab5e3f
.
lihaoyi 651a860
.
lihaoyi 162c0b2
.
lihaoyi f85e818
.
lihaoyi 60c521f
.
lihaoyi 5166274
.
lihaoyi 31b4e6a
Update GroupEvaluator.scala
lihaoyi 55918e5
.
lihaoyi 2b56455
Merge branch 'dynamic-pwd' of github.com:lihaoyi/mill-1 into dynamic-pwd
lihaoyi 74193cc
.
lihaoyi e46a2b8
.
lihaoyi 956d247
.
lihaoyi ed5de71
.
lihaoyi 12b55db
.
lihaoyi 1fe6f70
.
lihaoyi d6da900
.
lihaoyi 7a40ae2
.
lihaoyi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
= Mill Sandboxing | ||
|
||
== Task Sandboxing | ||
|
||
include::example/depth/sandbox/1-task.adoc[] | ||
|
||
== Test Sandboxing | ||
|
||
include::example/depth/sandbox/2-test.adoc[] | ||
|
||
== Limitations | ||
|
||
Mill's approach to filesystem sandboxing is designed to avoid accidental interference | ||
between different Mill tasks. It is not designed to block intentional misbehavior, and | ||
tasks are always able to traverse the filesystem and do whatever they want. Furthermore, | ||
Mill's redirection of `os.pwd` does not apply to `java.io` or `java.nio` APIs, which are | ||
outside of Mill's control. | ||
|
||
However, by setting `os.pwd` to safe sandbox folders, we hope to minimize the cases where | ||
someone accidentally causes issues with their build by doing the wrong thing. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// In order to help manage your build, Mill performs some rudimentary filesystem | ||
// sandboxing to keep different tasks and modules from interfering with each other. | ||
// This tries to ensure your tasks only read and write from their designated `.dest/` | ||
// folders, which are unique to each task and thus guaranteed not to collide with | ||
// the filesystem operations of other tasks that may be occurring in parallel. | ||
// | ||
// | ||
// === `T.dest` | ||
// The standard way of working with a task's `.dest/` folder is through the `T.dest` | ||
// property. This is available within any task, and gives you access to the | ||
// `out/<module-names>/<task-name>.dest/` folder to use. The `.dest/` folder for | ||
// each task is lazily initialized when `T.dest` is referenced and used: | ||
|
||
package build | ||
import mill._ | ||
|
||
object foo extends Module{ | ||
def tDestTask = T { println(T.dest.toString) } | ||
} | ||
|
||
/** Usage | ||
> ./mill foo.tDestTask | ||
.../out/foo/tDestTask.dest | ||
*/ | ||
|
||
|
||
// === Task `os.pwd` redirection | ||
// Mill also redirects the `os.pwd` property from https://github.com/com-lihaoyi/os-lib[OS-Lib], | ||
// such that that also points towards a running task's own `.dest/` folder | ||
|
||
def osPwdTask = T { println(os.pwd.toString) } | ||
|
||
/** Usage | ||
> ./mill osPwdTask | ||
.../out/osPwdTask.dest | ||
*/ | ||
|
||
// The redirection of `os.pwd` applies to `os.proc`, `os.call`, and `os.spawn` methods | ||
// as well. In the example below, we can see the `python3` subprocess we spawn prints | ||
// its `os.getcwd()`, which is our `osProcTask.dest/` sandbox folder: | ||
|
||
def osProcTask = T { | ||
println(os.call(("python3", "-c", "import os; print(os.getcwd())"), cwd = T.dest).out.trim()) | ||
} | ||
|
||
/** Usage | ||
> ./mill osProcTask | ||
.../out/osProcTask.dest | ||
*/ | ||
|
||
// === Non-task `os.pwd` redirection | ||
// | ||
// Lastly, there is the possibily of calling `os.pwd` outside of a task. When outside of | ||
// a task there is no `.dest/` folder associated, so instead Mill will redirect `os.pwd` | ||
// towards an empty `sandbox/` folder in `out/mill-worker.../`: | ||
|
||
val externalPwd = os.pwd | ||
def externalPwdTask = T { println(externalPwd.toString) } | ||
|
||
/** Usage | ||
> ./mill externalPwdTask | ||
.../out/mill-worker-.../sandbox/sandbox | ||
*/ | ||
|
||
|
||
// === Limitations of Mill's Sandboxing | ||
// | ||
// Mill's approach to filesystem sandboxing is designed to avoid accidental interference | ||
// between different Mill tasks. It is not designed to block intentional misbehavior, and | ||
// tasks are always able to traverse the filesystem and do whatever they want. Furthermore, | ||
// Mill's redirection of `os.pwd` does not apply to `java.io` or `java.nio` APIs, which are | ||
// outside of Mill's control. | ||
// | ||
// However, by setting `os.pwd` to safe sandbox folders, we hope to minimize the cases where | ||
// someone accidentally causes issues with their build by doing the wrong thing. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package bar; | ||
|
||
public class Bar { | ||
public static String generateHtml(String text) { | ||
return "<p>" + text + "</p>"; | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
example/depth/sandbox/2-test/bar/test/src/bar/BarTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package bar; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import org.junit.Test; | ||
import java.nio.file.*; | ||
|
||
public class BarTests { | ||
@Test | ||
public void simple() throws Exception { | ||
String result = Bar.generateHtml("world"); | ||
Path path = Paths.get("generated.html"); | ||
Files.write(path, result.getBytes()); | ||
assertEquals("<p>world</p>", new String(Files.readAllBytes(path))); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// Mill also creates sandbox folders for test suites to run in. Consider the | ||
// following build with two modules `foo` and `bar`, and their test suites | ||
// `foo.test` and `bar.test`: | ||
|
||
package build | ||
import mill._, javalib._ | ||
|
||
trait MyModule extends JavaModule{ | ||
object test extends JavaTests with TestModule.Junit4 | ||
} | ||
|
||
object foo extends MyModule{ | ||
def moduleDeps = Seq(bar) | ||
} | ||
|
||
object bar extends MyModule | ||
|
||
// For the sake of the example, both test modules contain tests that exercise the | ||
// logic in their corresponding non-test module, but also do some basic filesystem | ||
// operations at the same time, writing out a `generated.html` file and then reading it: | ||
|
||
/** See Also: foo/src/foo/Foo.java */ | ||
/** See Also: foo/test/src/foo/FooTests.java */ | ||
/** See Also: bar/src/bar/Bar.java */ | ||
/** See Also: bar/test/src/bar/BarTests.java */ | ||
|
||
// Both test suites can be run via | ||
|
||
/** Usage | ||
> ./mill __.test | ||
*/ | ||
|
||
// Without sandboxing, due to the tests running in parallel, there is a race condition: | ||
// it's possible that `FooTests` may write the file, `BarTests` write over it, before | ||
// `FooTests` reads the output from `BarTests`. That would cause non-deterministic | ||
// flaky failures in your test suite that can be very difficult to debug and resolve. | ||
// | ||
// With Mill's test sandboxing, each test runs in a separate folder: the `.dest` folder | ||
// of the respective task and module. For example: | ||
// | ||
// - `foo.test` runs in `out/foo/test/test.dest/` | ||
// - `bar.test` runs in `out/bar/test/test.dest/` | ||
// | ||
// As a result, each test's `generated.html` file is written to its own dedicated | ||
// working directory, without colliding with each other on disk: | ||
|
||
/** Usage | ||
|
||
> find . | grep generated.html | ||
.../out/foo/test/test.dest/sandbox/generated.html | ||
.../out/bar/test/test.dest/sandbox/generated.html | ||
|
||
> cat out/foo/test/test.dest/sandbox/generated.html | ||
<h1>hello</h1> | ||
|
||
> cat out/bar/test/test.dest/sandbox/generated.html | ||
<p>world</p> | ||
|
||
*/ | ||
|
||
// As each test suite runs in a different working directory by default, naive usage | ||
// reading and writing to the filesystem does not cause tests to interefere with | ||
// one another, which helps keep tests stable and deterministic even when run in | ||
// parallel | ||
// | ||
// Like Mill's Task sandboxing, Mill's Test sandboxing does not guard against | ||
// intentional misbehavior: tests can still walk the filesystem from the | ||
// sandbox folder via `..` or from the root folder `/` or home folder `~/`. | ||
// Nevertheless, it should add some simple guardrails to prevent many common | ||
// causes of inter-test interference, letting your test suite run in parallel both | ||
// quickly and reliably |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package foo; | ||
|
||
public class Foo { | ||
public static String generateHtml(String text) { | ||
return "<h1>" + text + "</h1>"; | ||
} | ||
} | ||
|
15 changes: 15 additions & 0 deletions
15
example/depth/sandbox/2-test/foo/test/src/foo/FooTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package foo; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import org.junit.Test; | ||
import java.nio.file.*; | ||
|
||
public class FooTests { | ||
@Test | ||
public void simple() throws Exception { | ||
String result = Foo.generateHtml("hello"); | ||
Path path = Paths.get("generated.html"); | ||
Files.write(path, result.getBytes()); | ||
assertEquals("<h1>hello</h1>", new String(Files.readAllBytes(path))); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need this, to derive the version from git reliably.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We dont need it jn every job, we just need it i the jobs that do publishing, which arent affected by this change