-
-
Notifications
You must be signed in to change notification settings - Fork 371
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adjust codegen to allow custom
mainargs.TokensReader
s and exercise …
…it via example tests for `Bundle Libraries` docs (#3504) * Includes a `mainargs.TokensReader[os.Path]` by default for convenience, and added example tests for 4 of the listed bundled libraries * Removed the type parameter from `Discover[T]`, since it was not necessary and only ever caused type inference problems * Moved the `lazy val millDiscover = Discover[T]` call from the `MillMiscInfo` object to the main body of the class containing user code, so it can see anything the user writes in `build.mill`, including `TokensReader` instances. The old reasoning for having it outside (that we want it to propagate implicitly to be picked up by nested `RootModule`s) no longer applies with the codegen-time `RootModule` unpacking Fixes #2029 Fixes #2857
- Loading branch information
Showing
51 changed files
with
573 additions
and
169 deletions.
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
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
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,43 @@ | ||
// Mill uses OS-Lib for all of its file system and subprocess operations. | ||
// | ||
// === Sandbox Working Directories | ||
// | ||
// One thing to note about Mill's usage of OS-Lib is that Mill sets the `os.pwd` | ||
// and for filesystem operations and subprocesses to each task's `.dest` folder, | ||
// as part of its xref:Mill_Sandboxing.adoc[] efforts to prevent accidental | ||
// interference between tasks: | ||
|
||
import mill._ | ||
|
||
def task1 = T{ | ||
os.write(os.pwd / "file.txt", "hello") | ||
PathRef(os.pwd / "file.txt") | ||
} | ||
|
||
def task2 = T{ | ||
os.call(("bash", "-c", "echo 'world' >> file.txt")) | ||
PathRef(os.pwd / "file.txt") | ||
} | ||
|
||
def command = T{ | ||
println(task1().path) | ||
println(os.read(task1().path)) | ||
println(task2().path) | ||
println(os.read(task2().path)) | ||
} | ||
|
||
// Thus although both `task1` and `task2` above write to `os.pwd / "file.txt"` - | ||
// one via `os.write` and one via a Bash subprocess - each task gets its own | ||
// working directory that prevents the files from colliding on disk. Thus the final | ||
// `command` can depend on both tasks and read each task's `file.txt` separately | ||
// without conflict | ||
|
||
/** Usage | ||
|
||
> ./mill command # mac/linux | ||
.../out/task1.dest/file.txt | ||
hello | ||
.../out/task2.dest/file.txt | ||
world | ||
|
||
*/ |
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,102 @@ | ||
// Mill uses uPickle to cache target output to disk as JSON, and to output JSON | ||
// for third-party tools to consume. The output of every Mill target must be JSON | ||
// serializable via uPickle. | ||
// | ||
// The uPickle serialized return of every Mill task is used for multiple purposes: | ||
// | ||
// - As the format for caching things on disk | ||
// | ||
// - The output format for `show`, which can be used for manual inspection piped | ||
// to external tools | ||
// | ||
// - Decided whether downstream results can be read from the cache or whether they | ||
// need to be recomputed | ||
// | ||
// === Primitives and Collections | ||
// | ||
// Most Scala primitive types (``String``s, ``Int``s, ``Boolean``s, etc.) and | ||
// collections types (``Seq``s, ``List``s, ``Tuple``s, etc.) are serializable by default. | ||
|
||
import mill._ | ||
|
||
def taskInt = T{ 123 } | ||
def taskBoolean = T{ true } | ||
def taskString = T{ "hello " + taskInt() + " world " + taskBoolean() } | ||
|
||
|
||
/** Usage | ||
|
||
> ./mill show taskInt | ||
123 | ||
|
||
> ./mill show taskBoolean | ||
true | ||
|
||
> ./mill show taskString | ||
"hello 123 world true" | ||
|
||
> ./mill show taskTuple | ||
[ | ||
123, | ||
true, | ||
"hello 123 world true" | ||
] | ||
*/ | ||
|
||
def taskTuple = T{ (taskInt(), taskBoolean(), taskString())} | ||
def taskSeq = T{ Seq(taskInt(), taskInt() * 2, taskInt() * 3)} | ||
def taskMap = T{ Map("int" -> taskInt().toString, "boolean" -> taskBoolean().toString) } | ||
|
||
|
||
/** Usage | ||
> ./mill show taskSeq | ||
[ | ||
123, | ||
246, | ||
369 | ||
] | ||
|
||
> ./mill show taskMap | ||
{ | ||
"int": "123", | ||
"boolean": "true" | ||
} | ||
|
||
*/ | ||
|
||
// === Paths and PathRef | ||
// | ||
// ``os.Path``s from OS-Lib are also serializable as strings. | ||
|
||
def taskPath = T{ | ||
os.write(os.pwd / "file.txt", "hello") | ||
os.pwd / "file.txt" | ||
} | ||
|
||
/** Usage | ||
|
||
> ./mill show taskPath | ||
".../out/taskPath.dest/file.txt" | ||
|
||
*/ | ||
|
||
// Note that returning an `os.Path` from a task will only invalidate downstream | ||
// tasks on changes to the path itself (e.g. from returning `file.txt` to `file2.txt`), | ||
// and not to changes to the contents of any file or folder at that path. If you want | ||
// to invalidate downstream tasks depending on the contents of a file or folder, you | ||
// should return a `PathRef`: | ||
|
||
def taskPathRef = T{ | ||
os.write(os.pwd / "file.txt", "hello") | ||
PathRef(os.pwd / "file.txt") | ||
} | ||
|
||
/** Usage | ||
|
||
> ./mill show taskPathRef | ||
"ref.../out/taskPathRef.dest/file.txt" | ||
|
||
*/ | ||
|
||
// The serialized `PathRef` contains a hexadecimal hash signature of the file or | ||
// folder referenced on disk, computed from its contents. |
Oops, something went wrong.