summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2017-12-29 23:39:23 -0800
committerLi Haoyi <haoyi.sg@gmail.com>2017-12-29 23:39:23 -0800
commit476640d8b78a2d1bc902fcdd15fcef996b73ca2c (patch)
tree41265b2e9e53bf72576e0ac9a0198c40325d907f
parent3ce3d6214b1c52c692926ab373412b71fe097c21 (diff)
downloadmill-476640d8b78a2d1bc902fcdd15fcef996b73ca2c.tar.gz
mill-476640d8b78a2d1bc902fcdd15fcef996b73ca2c.tar.bz2
mill-476640d8b78a2d1bc902fcdd15fcef996b73ca2c.zip
Re-organize `out/` directory to keep all files related to a particular `Target` within a single folder
-rw-r--r--core/src/main/scala/mill/eval/Evaluator.scala55
-rw-r--r--core/src/main/scala/mill/main/RunScript.scala2
-rw-r--r--core/src/test/scala/mill/eval/JavaCompileJarTests.scala4
-rw-r--r--readme.md12
-rw-r--r--scalaplugin/src/main/scala/mill/scalaplugin/GenIdea.scala4
-rw-r--r--scalaplugin/src/test/scala/mill/scalaplugin/HelloWorldTests.scala12
-rwxr-xr-xtest.sh8
7 files changed, 46 insertions, 51 deletions
diff --git a/core/src/main/scala/mill/eval/Evaluator.scala b/core/src/main/scala/mill/eval/Evaluator.scala
index ed8145b2..0a295ee1 100644
--- a/core/src/main/scala/mill/eval/Evaluator.scala
+++ b/core/src/main/scala/mill/eval/Evaluator.scala
@@ -41,10 +41,10 @@ class Evaluator[T](val workspacePath: Path,
}
val delta = finalTaskOverrides - t.overrides
val additional =
- if (delta == 0) Seq(segments.last)
- else Seq(Segment.Label(segments.last.asInstanceOf[Segment.Label].value + "-override-" + delta))
+ if (delta == 0) Nil
+ else Seq(Segment.Label("override" + delta))
- Right(Labelled(t, segments.init ++ additional))
+ Right(Labelled(t, segments ++ additional))
case t if goals.contains(t) => Left(t)
}
@@ -82,11 +82,12 @@ class Evaluator[T](val workspacePath: Path,
terminal match{
case Left(task) =>
- evaluateGroup(group, results, targetDestPath = None, maybeTargetLabel = None)
+ evaluateGroup(group, results, paths = None, maybeTargetLabel = None)
case Right(labelledTarget) =>
- val (destPath, metadataPath) = Evaluator.resolveDestPaths(workspacePath, labelledTarget)
+ val paths = Evaluator.resolveDestPaths(workspacePath, labelledTarget)
+ mkdir(paths.base)
val cached = for{
- json <- scala.util.Try(upickle.json.read(read(metadataPath))).toOption
+ json <- scala.util.Try(upickle.json.read(read(paths.meta))).toOption
(cachedHash, terminalResult) <- scala.util.Try(upickle.default.readJs[(Int, upickle.Js.Value)](json)).toOption
if cachedHash == inputsHash
} yield terminalResult
@@ -105,11 +106,11 @@ class Evaluator[T](val workspacePath: Path,
case Mirror.Segment.Cross(s) => "[" + s.mkString(",") + "]"
}
- if (labelledTarget.target.flushDest) rm(destPath)
+ if (labelledTarget.target.flushDest) rm(paths.dest)
val (newResults, newEvaluated) = evaluateGroup(
group,
results,
- Some(destPath),
+ Some(paths),
maybeTargetLabel = Some(msgParts.mkString))
newResults(labelledTarget.target) match{
@@ -120,14 +121,14 @@ class Evaluator[T](val workspacePath: Path,
.map(_.write(v))
for(t <- terminalResult){
- write.over(metadataPath, upickle.default.write(inputsHash -> t, indent = 4))
+ write.over(paths.meta, upickle.default.write(inputsHash -> t, indent = 4))
}
case _ =>
- // Wipe out any cached metadata.mill.json file that exists, so
+ // Wipe out any cached meta.json file that exists, so
// a following run won't look at the cached metadata file and
// assume it's associated with the possibly-borked state of the
// destPath after an evaluation failure.
- rm(metadataPath)
+ rm(paths.meta)
}
@@ -140,7 +141,7 @@ class Evaluator[T](val workspacePath: Path,
def evaluateGroup(group: OSet[Task[_]],
results: collection.Map[Task[_], Result[Any]],
- targetDestPath: Option[Path],
+ paths: Option[Evaluator.Paths],
maybeTargetLabel: Option[String]) = {
@@ -160,7 +161,7 @@ class Evaluator[T](val workspacePath: Path,
if(logRun) { log.info("Running " + targetLabel) }
}
- val multiLogger = resolveLogger(targetDestPath)
+ val multiLogger = resolveLogger(paths.map(_.log))
for (target <- nonEvaluatedTargets) {
@@ -174,7 +175,7 @@ class Evaluator[T](val workspacePath: Path,
else {
val args = new Ctx(
targetInputValues.toArray[Any],
- targetDestPath.orNull,
+ paths.map(_.dest).orNull,
multiLogger,
new Ctx.LoaderCtx{
def load[T](x: Ctx.Loader[T]): T = {
@@ -207,33 +208,27 @@ class Evaluator[T](val workspacePath: Path,
(newResults, newEvaluated)
}
- def resolveLogger(targetDestPath: Option[Path]): Logger = {
- if (targetDestPath.isEmpty) log
- else {
- val path = targetDestPath.getOrElse(pwd/ 'out / 'command)
- val dir = path / up
- mkdir(dir)
- val file = dir / (path.last + ".log")
- rm(file)
- MultiLogger(log, FileLogger(file))
- }
+ def resolveLogger(logPath: Option[Path]): Logger = logPath match{
+ case None => log
+ case Some(path) =>
+ rm(path)
+ MultiLogger(log, FileLogger(path))
}
-
}
object Evaluator{
- def resolveDestPaths(workspacePath: Path, t: Labelled[_]): (Path, Path) = {
+ case class Paths(base: Path, dest: Path, meta: Path, log: Path)
+ def resolveDestPaths(workspacePath: Path, t: Labelled[_]): Paths = {
resolveDestPaths(workspacePath, t.segments)
}
- def resolveDestPaths(workspacePath: Path, segments: Seq[Segment]): (Path, Path) = {
+ def resolveDestPaths(workspacePath: Path, segments: Seq[Segment]): Paths = {
val segmentStrings = segments.flatMap{
case Mirror.Segment.Label(s) => Seq(s)
case Mirror.Segment.Cross(values) => values.map(_.toString)
}
- val targetDestPath = workspacePath / segmentStrings
- val metadataPath = targetDestPath / up / (targetDestPath.last + ".mill.json")
- (targetDestPath, metadataPath)
+ val targetPath = workspacePath / segmentStrings
+ Paths(targetPath, targetPath / 'dest, targetPath / "meta.json", targetPath / 'log)
}
// check if the build itself has changed
diff --git a/core/src/main/scala/mill/main/RunScript.scala b/core/src/main/scala/mill/main/RunScript.scala
index 7ea96b2b..22d6fc95 100644
--- a/core/src/main/scala/mill/main/RunScript.scala
+++ b/core/src/main/scala/mill/main/RunScript.scala
@@ -143,7 +143,7 @@ object RunScript{
t match {
case t: mill.define.Target[_] =>
for (segments <- evaluator.mapping.modules.get(t.owner)) yield {
- val jsonFile = Evaluator.resolveDestPaths(evaluator.workspacePath, segments :+ Segment.Label(t.name))._2
+ val jsonFile = Evaluator.resolveDestPaths(evaluator.workspacePath, segments :+ Segment.Label(t.name)).meta
val metadata = upickle.json.read(jsonFile.toIO)
metadata(1)
}
diff --git a/core/src/test/scala/mill/eval/JavaCompileJarTests.scala b/core/src/test/scala/mill/eval/JavaCompileJarTests.scala
index 2b5bcb58..ba74dea3 100644
--- a/core/src/test/scala/mill/eval/JavaCompileJarTests.scala
+++ b/core/src/test/scala/mill/eval/JavaCompileJarTests.scala
@@ -123,7 +123,7 @@ object JavaCompileJarTests extends TestSuite{
check(targets = OSet(allSources), expected = OSet(allSources))
check(targets = OSet(jar), expected = OSet(classFiles, jar))
- val jarContents = %%('jar, "-tf", workspacePath/'jar)(workspacePath).out.string
+ val jarContents = %%('jar, "-tf", workspacePath/'jar/'dest)(workspacePath).out.string
val expectedJarContents =
"""META-INF/MANIFEST.MF
|hello.txt
@@ -135,7 +135,7 @@ object JavaCompileJarTests extends TestSuite{
|""".stripMargin
assert(jarContents == expectedJarContents)
- val executed = %%('java, "-cp", workspacePath/'jar, "test.Foo")(workspacePath).out.string
+ val executed = %%('java, "-cp", workspacePath/'jar/'dest, "test.Foo")(workspacePath).out.string
assert(executed == (31337 + 271828) + "\n")
for(i <- 0 until 3){
diff --git a/readme.md b/readme.md
index 0e179da5..30c473c4 100644
--- a/readme.md
+++ b/readme.md
@@ -135,7 +135,7 @@ sbt bin/test:assembly
bin/target/mill devAssembly
# Build Mill executable using the Mill executable generated by Mill itself
-out/devAssembly devAssembly
+out/devAssembly/dest devAssembly
```
Eventually, as Mill stabilizes, we will get rid of the SBT build entirely and
@@ -188,7 +188,7 @@ run something via `mill Core.cross[a].printIt` while from code you use
### Caching by default
Every `Target` in a build, defined by `def foo = T{...}`, is cached by default.
-Currently this is done using a `foo.mill.json` file in the `out/` folder. The
+Currently this is done using a `foo/meta.json` file in the `out/` folder. The
`Target` is also provided a `foo/` path on the filesystem dedicated to it, for
it to store output files etc.
@@ -209,10 +209,10 @@ structures where a previous process left off, in order to continue the build.
Re-construction is done via the hierarchical nature of the build: each `Target`
`Foo.bar.baz` has a fixed position in the build hierarchy, and thus a fixed
-position on disk `out/foo/bar/baz.mill.json`. When the old process dies and a
+position on disk `out/foo/bar/baz/meta.json`. When the old process dies and a
new process starts, there will be a new instance of `Target` with the same
implementation code and same position in the build hierarchy: this new `Target`
-can then load the `out/foo/bar/baz.mill.json` file and pick up where the
+can then load the `out/foo/bar/baz/meta.json` file and pick up where the
previous process left off.
Minimizing startup time means aggressive caching, as well as minimizing the
@@ -328,9 +328,9 @@ the `Target`s you can run.
A `Target`'s position in the module hierarchy tells you many things. For
example, a `Target` at position `Core.test.compile` would:
-- Cache output metadata at `out/Core/test/compile.mill.json`
+- Cache output metadata at `out/Core/test/compile/meta.json`
-- Output files to the folder `out/Core/test/compile/`
+- Output files to the folder `out/Core/test/compile/dest/`
- Be runnable from the command-line via `mill Core.test.compile`
diff --git a/scalaplugin/src/main/scala/mill/scalaplugin/GenIdea.scala b/scalaplugin/src/main/scala/mill/scalaplugin/GenIdea.scala
index ee2ddf60..d6cd0f7a 100644
--- a/scalaplugin/src/main/scala/mill/scalaplugin/GenIdea.scala
+++ b/scalaplugin/src/main/scala/mill/scalaplugin/GenIdea.scala
@@ -78,14 +78,14 @@ object GenIdea {
val Seq(sourcePath: PathRef) =
evaluator.evaluate(OSet(mod.sources)).values
- val (destPath, jsonPath) = Evaluator.resolveDestPaths(
+ val paths = Evaluator.resolveDestPaths(
evaluator.workspacePath,
evaluator.mapping.modules(mod.compile)
)
val elem = moduleXmlTemplate(
sourcePath.path,
- Seq(destPath, jsonPath),
+ Seq(paths.base),
resolvedDeps.map(pathToLibName),
for(m <- mod.projectDeps)
yield moduleName(moduleLabels(m))
diff --git a/scalaplugin/src/test/scala/mill/scalaplugin/HelloWorldTests.scala b/scalaplugin/src/test/scala/mill/scalaplugin/HelloWorldTests.scala
index 4272654a..b7948167 100644
--- a/scalaplugin/src/test/scala/mill/scalaplugin/HelloWorldTests.scala
+++ b/scalaplugin/src/test/scala/mill/scalaplugin/HelloWorldTests.scala
@@ -139,9 +139,9 @@ object HelloWorldTests extends TestSuite {
val outPath = result.classes.path
val analysisFile = result.analysisFile
val outputFiles = ls.rec(outPath)
- val expectedClassfiles = compileClassfiles.map(workspacePath / 'compile / 'classes / _)
+ val expectedClassfiles = compileClassfiles.map(workspacePath / 'compile / 'dest / 'classes / _)
assert(
- outPath == workspacePath / 'compile / 'classes,
+ outPath == workspacePath / 'compile / 'dest / 'classes,
exists(analysisFile),
outputFiles.nonEmpty,
outputFiles.forall(expectedClassfiles.contains),
@@ -168,14 +168,14 @@ object HelloWorldTests extends TestSuite {
assert(err.isInstanceOf[CompileFailed])
- val (compilePath, compileMetadataPath) = Evaluator.resolveDestPaths(
+ val paths = Evaluator.resolveDestPaths(
workspacePath,
helloWorldEvaluator.evaluator.mapping.targets(HelloWorld.compile)
)
assert(
- ls.rec(compilePath / 'classes).isEmpty,
- !exists(compileMetadataPath)
+ ls.rec(paths.dest / 'classes).isEmpty,
+ !exists(paths.meta)
)
// Works when fixed
write.over(mainObject, read(mainObject).dropRight("val x: ".length))
@@ -300,7 +300,7 @@ object HelloWorldTests extends TestSuite {
'logOutputToFile {
helloWorldEvaluator(HelloWorld.compile)
- val logFile = workspacePath / "compile.log"
+ val logFile = workspacePath / 'compile / 'log
assert(exists(logFile))
}
}
diff --git a/test.sh b/test.sh
index e73405ee..13d81631 100755
--- a/test.sh
+++ b/test.sh
@@ -12,7 +12,7 @@ sbt core/test scalaplugin/test scalajsplugin/test bin/test:assembly
bin/target/mill devAssembly
# Second build & run tests using Mill
-out/devAssembly Core.test
-out/devAssembly ScalaPlugin.test
-out/devAssembly ScalaJSPlugin.test
-out/devAssembly devAssembly \ No newline at end of file
+out/devAssembly/dest Core.test
+out/devAssembly/dest ScalaPlugin.test
+out/devAssembly/dest ScalaJSPlugin.test
+out/devAssembly/dest devAssembly \ No newline at end of file