diff --git a/core/define/src/mill/define/Task.scala b/core/define/src/mill/define/Task.scala index 55374fe4782f..f16a5b2ec590 100644 --- a/core/define/src/mill/define/Task.scala +++ b/core/define/src/mill/define/Task.scala @@ -148,34 +148,30 @@ object Task { * signature for you source files/folders and decides whether or not downstream * [[Task.Computed]]s need to be invalidated and re-computed. */ - inline def Sources(inline values: Result[os.Path]*)(implicit + inline def Sources(inline values: (os.SubPath | os.FilePath)*)(implicit inline ctx: mill.define.ModuleCtx ): Simple[Seq[PathRef]] = ${ - Macros.sourcesImpl('{ Result.sequence(values.map(_.map(PathRef(_)))) })('ctx) + Macros.sourcesImpl('{ values.map(p => PathRef(mapToPath(p))) })('ctx) } - inline def Sources(inline values: os.SubPath*)(implicit - inline ctx: mill.define.ModuleCtx, - dummy: Boolean = true - ): Simple[Seq[PathRef]] = ${ - Macros.sourcesImpl( - '{ values.map(sub => PathRef(ctx.millSourcePath / os.up / os.PathChunk.SubPathChunk(sub))) } - )('ctx) + inline private def mapToPath(value: os.SubPath | os.FilePath)(implicit + inline ctx: mill.define.ModuleCtx + ): os.Path = value match { + // TODO: support "." + case str: String => ctx.millSourcePath / os.up / os.PathChunk.segmentsFromString(str) + case sub: os.SubPath => ctx.millSourcePath / os.up / os.PathChunk.SubPathChunk(sub) + case rel: os.RelPath => ctx.millSourcePath / os.up / os.PathChunk.RelPathChunk(rel) + case p: os.Path => p } /** * Similar to [[Sources]], but only for a single source file or folder. Defined * using `Task.Source`. */ - inline def Source(inline value: Result[os.Path])(implicit - inline ctx: mill.define.ModuleCtx - ): Simple[PathRef] = - ${ Macros.sourceImpl('{ value.map(PathRef(_)) })('ctx) } - - inline def Source(inline value: os.SubPath)(implicit + inline def Source(inline value: os.SubPath | os.FilePath)(implicit inline ctx: mill.define.ModuleCtx ): Simple[PathRef] = - ${ Macros.sourceImpl('{ PathRef(ctx.millSourcePath / os.up / value) })('ctx) } + ${ Macros.sourceImpl('{ PathRef(mapToPath(value)) })('ctx) } /** * [[Input]]s, normally defined using `Task.Input`, are [[Task.Named]]s that diff --git a/core/exec/test/src/mill/exec/ExecutionTests.scala b/core/exec/test/src/mill/exec/ExecutionTests.scala index 452fa8df7784..e0b8ce5bd424 100644 --- a/core/exec/test/src/mill/exec/ExecutionTests.scala +++ b/core/exec/test/src/mill/exec/ExecutionTests.scala @@ -32,6 +32,19 @@ object ExecutionTests extends TestSuite { def task = Task[Int] { anon() } lazy val millDiscover = Discover[this.type] } + + object sourceBuild extends TestRootModule { + def source = Task.Source { "hello/world.txt" } + def task = Task { os.read(source().path) + " !" } + lazy val millDiscover = Discover[this.type] + } + + object sourcesBuild extends TestRootModule { + def source = Task.Sources("hello/world.txt", "hello/world2.txt") + def task = Task { source().map(pr => os.read(pr.path)).mkString + "!" } + lazy val millDiscover = Discover[this.type] + } + class Checker[T <: mill.testkit.TestRootModule](module: T) extends exec.Checker(module) @@ -45,12 +58,7 @@ object ExecutionTests extends TestSuite { } test("source") { - object build extends TestRootModule { - def source = Task.Source { "hello/world.txt" } - def task = Task { os.read(source().path) + " !" } - lazy val millDiscover = Discover[this.type] - } - + val build = sourceBuild val checker = new Checker(build) os.write(build.moduleDir / "hello/world.txt", "i am cow", createFolders = true) @@ -61,7 +69,13 @@ object ExecutionTests extends TestSuite { extraEvaled = -1, secondRunNoOp = false ) - checker(build.task, "i am cow !", Seq(build.source), extraEvaled = -1, secondRunNoOp = false) + checker( + build.task, + "i am cow !", + Seq(build.source), + extraEvaled = -1, + secondRunNoOp = false + ) os.write.over(build.moduleDir / "hello/world.txt", "hear me moo") checker( @@ -80,12 +94,7 @@ object ExecutionTests extends TestSuite { ) } test("sources") { - object build extends TestRootModule { - def source = Task.Sources("hello/world.txt", "hello/world2.txt") - def task = Task { source().map(pr => os.read(pr.path)).mkString + "!" } - lazy val millDiscover = Discover[this.type] - } - + val build = sourcesBuild val checker = new Checker(build) os.write(build.moduleDir / "hello/world.txt", "i am cow ", createFolders = true) @@ -298,10 +307,10 @@ object ExecutionTests extends TestSuite { UnitTester(build, null).scoped { tester => assert(y == 0) - val Right(_) = tester.apply(build.task) + val Right(_) = tester.apply(build.task): @unchecked assert(y == 10) x = 0 - val Left(_) = tester.apply(build.task) + val Left(_) = tester.apply(build.task): @unchecked assert(y == 10) } } @@ -315,12 +324,13 @@ object ExecutionTests extends TestSuite { lazy val millDiscover = Discover[this.type] } UnitTester(build, null).scoped { tester => - val Right(UnitTester.Result(Seq(1, 10, 100), _)) = tester.apply(build.task4) + val Right(UnitTester.Result(Seq(1, 10, 100), _)) = tester.apply(build.task4): @unchecked } } test("traverse") { UnitTester(traverseBuild, null).scoped { tester => - val Right(UnitTester.Result(Seq(1, 10, 100), _)) = tester.apply(traverseBuild.task4) + val Right(UnitTester.Result(Seq(1, 10, 100), _)) = + tester.apply(traverseBuild.task4): @unchecked } } @@ -332,7 +342,7 @@ object ExecutionTests extends TestSuite { lazy val millDiscover = Discover[this.type] } UnitTester(build, null).scoped { tester => - val Right(UnitTester.Result((1, 10), _)) = tester.apply(build.task4) + val Right(UnitTester.Result((1, 10), _)) = tester.apply(build.task4): @unchecked } } @@ -344,7 +354,7 @@ object ExecutionTests extends TestSuite { lazy val millDiscover = Discover[this.type] } UnitTester(build, null).scoped { tester => - val Right(UnitTester.Result(11, _)) = tester.apply(build.task2) + val Right(UnitTester.Result(11, _)) = tester.apply(build.task2): @unchecked } } @@ -421,13 +431,17 @@ object ExecutionTests extends TestSuite { test("backticked") { UnitTester(bactickIdentifiers, null).scoped { tester => - val Right(UnitTester.Result(1, _)) = tester.apply(bactickIdentifiers.`up-target`) - val Right(UnitTester.Result(3, _)) = tester.apply(bactickIdentifiers.`a-down-target`) - val Right(UnitTester.Result(3, _)) = tester.apply(bactickIdentifiers.`invisible&`) + val Right(UnitTester.Result(1, _)) = + tester.apply(bactickIdentifiers.`up-target`): @unchecked + val Right(UnitTester.Result(3, _)) = + tester.apply(bactickIdentifiers.`a-down-target`): @unchecked + val Right(UnitTester.Result(3, _)) = + tester.apply(bactickIdentifiers.`invisible&`): @unchecked val Right(UnitTester.Result(4, _)) = - tester.apply(bactickIdentifiers.`nested-module`.`nested-target`) + tester.apply(bactickIdentifiers.`nested-module`.`nested-target`): @unchecked } } + test("anonTaskFailure") { UnitTester(anonTaskFailure, null).scoped { tester => val res = tester.evaluator.execute(Seq(anonTaskFailure.task)) diff --git a/example/fundamentals/tasks/2-primary-tasks/build.mill b/example/fundamentals/tasks/2-primary-tasks/build.mill index 24e0b13b08e6..39a486c3bc32 100644 --- a/example/fundamentals/tasks/2-primary-tasks/build.mill +++ b/example/fundamentals/tasks/2-primary-tasks/build.mill @@ -12,8 +12,10 @@ import mill.{Module, T, _} def sources = Task.Source { "src" } def resources = Task.Source { "resources" } -// ``Source``s are defined using `Task.Source{...}` taking one `os.Path`, or `Task.Sources{...}`, -// taking multiple ``os.Path``s as arguments. A ``Source``'s: +// ``Source``s are defined using `Task.Source{...}` taking one path, or `Task.Sources{...}`, +// taking multiple paths as arguments. Both accept `os.Path`, `os.SubPath`, `os.RelPath` +// or a `String` containing a sub-path. All relative paths will be resolve against the `moduleDir` +// of the enclosing module. A ``Source``'s: // its build signature/`hashCode` depends not just on the path // it refers to (e.g. `foo/bar/baz`) but also the MD5 hash of the file contents or // folder tree at that path. diff --git a/example/thirdparty/arrow/build.mill b/example/thirdparty/arrow/build.mill index 95d83864495b..7df92b276081 100644 --- a/example/thirdparty/arrow/build.mill +++ b/example/thirdparty/arrow/build.mill @@ -143,7 +143,7 @@ object `package` extends Module { sources ++= Seq(nonJvmSourcesPath) } } - sources.map(mill.api.Result.Success(_)) + sources }*) override def kotlincOptions = @@ -163,8 +163,7 @@ object `package` extends Module { override def sources: T[Seq[PathRef]] = Task.Sources( Seq("common", outer.platformCrossSuffix) .map(platform => outer.moduleDir / "src" / s"${platform}Test" / "kotlin") - .filter(p => os.exists(p)) - .map(mill.api.Result.Success(_))* + .filter(p => os.exists(p))* ) } } diff --git a/libs/scalalib/test/src/mill/javalib/revapi/RevapiModuleTests.scala b/libs/scalalib/test/src/mill/javalib/revapi/RevapiModuleTests.scala index 0a9b7e2b102a..9534abccd447 100644 --- a/libs/scalalib/test/src/mill/javalib/revapi/RevapiModuleTests.scala +++ b/libs/scalalib/test/src/mill/javalib/revapi/RevapiModuleTests.scala @@ -73,7 +73,7 @@ object RevapiModuleTests extends TestSuite { object module2 extends module with RevapiModule { override def revapiConfigFiles: T[Seq[PathRef]] = Task.Sources( - os.list(conf).iterator.filter(_.ext == "json").toSeq.map(mill.api.Result.Success(_))* + os.list(conf).iterator.filter(_.ext == "json").toSeq* ) override def revapiClasspath: T[Seq[PathRef]] = Task { super.revapiClasspath() ++ Seq(PathRef(conf)) @@ -113,7 +113,7 @@ object RevapiModuleTests extends TestSuite { } override def revapiConfigFiles: T[Seq[PathRef]] = Task.Sources( - os.list(conf).iterator.filter(_.ext == "json").toSeq.map(mill.api.Result.Success(_))* + os.list(conf).iterator.filter(_.ext == "json").toSeq* ) override def revapiClasspath: T[Seq[PathRef]] = Task { super.revapiClasspath() ++ Seq(PathRef(conf)) diff --git a/runner/meta/src/mill/meta/MillBuildRootModule.scala b/runner/meta/src/mill/meta/MillBuildRootModule.scala index 0f5c887a394f..09236cb3c487 100644 --- a/runner/meta/src/mill/meta/MillBuildRootModule.scala +++ b/runner/meta/src/mill/meta/MillBuildRootModule.scala @@ -48,7 +48,7 @@ trait MillBuildRootModule()(implicit * @see [[generatedSources]] */ def scriptSources: T[Seq[PathRef]] = Task.Sources( - scriptSourcesPaths.map(Result.Success(_))* // Ensure ordering is deterministic + scriptSourcesPaths* // Ensure ordering is deterministic ) def parseBuildFiles: T[FileImportGraph] = Task {