From b465df8792cd5a30b9b5cf1d0b0b93710248272d Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Fri, 23 May 2025 09:33:33 +0200 Subject: [PATCH 1/7] WIP: Allow some task reference from source tasks --- core/define/src/mill/define/Task.scala | 10 +++++----- .../mill/define/internal/Applicative.scala | 20 ++++++++++++++++--- .../src/mill/scalalib/JavaModule.scala | 1 + 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/core/define/src/mill/define/Task.scala b/core/define/src/mill/define/Task.scala index 55374fe4782f..ee40968e0d4e 100644 --- a/core/define/src/mill/define/Task.scala +++ b/core/define/src/mill/define/Task.scala @@ -471,9 +471,9 @@ object Task { Expr[(Seq[Any], mill.define.TaskCtx) => Result[T]] ) => Expr[M[T]], t: Expr[Result[T]], - allowTaskReferences: Boolean = true + allowedTaskReferences: Applicative.TaskReferences = Applicative.TaskReferences.All ): Expr[M[T]] = - Applicative.impl[M, Task, Result, T, mill.define.TaskCtx](traverseCtx, t, allowTaskReferences) + Applicative.impl[M, Task, Result, T, mill.define.TaskCtx](traverseCtx, t, allowedTaskReferences) private def taskIsPrivate()(using Quotes): Expr[Option[Boolean]] = Cacher.withMacroOwner { @@ -515,7 +515,7 @@ object Task { val expr = appImpl[Simple, Seq[PathRef]]( (in, ev) => '{ new Sources($ev, $ctx, ${ taskIsPrivate() }) }, values, - allowTaskReferences = false + allowedTaskReferences = Applicative.TaskReferences.Sources ) Cacher.impl0(expr) } @@ -529,7 +529,7 @@ object Task { val expr = appImpl[Simple, PathRef]( (in, ev) => '{ new Source($ev, $ctx, ${ taskIsPrivate() }) }, value, - allowTaskReferences = false + allowedTaskReferences = Applicative.TaskReferences.Source ) Cacher.impl0(expr) @@ -545,7 +545,7 @@ object Task { val expr = appImpl[Simple, T]( (in, ev) => '{ new Input[T]($ev, $ctx, $w, ${ taskIsPrivate() }) }, value, - allowTaskReferences = false + allowedTaskReferences = Applicative.TaskReferences.None ) Cacher.impl0(expr) } diff --git a/core/define/src/mill/define/internal/Applicative.scala b/core/define/src/mill/define/internal/Applicative.scala index e5dc942634a7..5e05f3707043 100644 --- a/core/define/src/mill/define/internal/Applicative.scala +++ b/core/define/src/mill/define/internal/Applicative.scala @@ -2,9 +2,10 @@ package mill.define.internal import mill.api.internal.internal import scala.annotation.compileTimeOnly - import scala.quoted.* +import mill.define.internal.Applicative.TaskReferences.All + /** * A generic Applicative-functor macro: translates calls to * @@ -24,12 +25,23 @@ object Applicative { type Id[+T] = T + enum TaskReferences { + /** No tasks can be references. */ + case None + /** Only `Task.Source` tasks can be references. */ + case Source + /** Only `Task.Source` and `Task.Sources` tasks can be references. */ + case Sources + /** All tasks can be references. */ + case All + } + def impl[M[_]: Type, W[_]: Type, Z[_]: Type, T: Type, Ctx: Type](using Quotes )( traverseCtx: (Expr[Seq[W[Any]]], Expr[(Seq[Any], Ctx) => Z[T]]) => Expr[M[T]], t: Expr[Z[T]], - allowTaskReferences: Boolean = true + allowedTaskReferences: TaskReferences = All ): Expr[M[T]] = { import quotes.reflect.* @@ -70,8 +82,10 @@ object Applicative { override def transformTerm(tree: Term)(owner: Symbol): Term = tree match case t @ Apply(sel @ Select(fun, "apply"), Nil) - if sel.symbol == targetApplySym && allowTaskReferences => + if sel.symbol == targetApplySym && allowedTaskReferences != TaskReferences.None => val localDefs = extractDefs(fun) + // TODO: Support TaskReferences.Sources and TaskReference.Source + // it should already work, but we don't restrict it properly visitAllTrees(t) { x => val sym = x.symbol if (sym != Symbol.noSymbol && defs(sym) && !localDefs(sym)) { diff --git a/libs/scalalib/src/mill/scalalib/JavaModule.scala b/libs/scalalib/src/mill/scalalib/JavaModule.scala index 6a3640e1ba7b..dade19be2215 100644 --- a/libs/scalalib/src/mill/scalalib/JavaModule.scala +++ b/libs/scalalib/src/mill/scalalib/JavaModule.scala @@ -744,6 +744,7 @@ trait JavaModule */ def assemblyRules: Seq[Assembly.Rule] = Assembly.defaultRules + @deprecated("FOR REMOVAL") def sourcesFolders: Seq[os.SubPath] = Seq("src") /** From d47c6e18c19d9df499f9477f3c9498905034c50a Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Fri, 23 May 2025 07:35:57 +0000 Subject: [PATCH 2/7] [autofix.ci] apply automated fixes --- core/define/src/mill/define/Task.scala | 6 +++++- core/define/src/mill/define/internal/Applicative.scala | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/core/define/src/mill/define/Task.scala b/core/define/src/mill/define/Task.scala index ee40968e0d4e..7ae5db113ad5 100644 --- a/core/define/src/mill/define/Task.scala +++ b/core/define/src/mill/define/Task.scala @@ -473,7 +473,11 @@ object Task { t: Expr[Result[T]], allowedTaskReferences: Applicative.TaskReferences = Applicative.TaskReferences.All ): Expr[M[T]] = - Applicative.impl[M, Task, Result, T, mill.define.TaskCtx](traverseCtx, t, allowedTaskReferences) + Applicative.impl[M, Task, Result, T, mill.define.TaskCtx]( + traverseCtx, + t, + allowedTaskReferences + ) private def taskIsPrivate()(using Quotes): Expr[Option[Boolean]] = Cacher.withMacroOwner { diff --git a/core/define/src/mill/define/internal/Applicative.scala b/core/define/src/mill/define/internal/Applicative.scala index 5e05f3707043..259b10b294c2 100644 --- a/core/define/src/mill/define/internal/Applicative.scala +++ b/core/define/src/mill/define/internal/Applicative.scala @@ -26,12 +26,16 @@ object Applicative { type Id[+T] = T enum TaskReferences { + /** No tasks can be references. */ case None + /** Only `Task.Source` tasks can be references. */ case Source + /** Only `Task.Source` and `Task.Sources` tasks can be references. */ case Sources + /** All tasks can be references. */ case All } From 5a05d6d822646fbeaf57c04409b8046d15f07d89 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Fri, 23 May 2025 15:25:59 +0200 Subject: [PATCH 3/7] Fix warnings and deprecations --- core/define/src/mill/define/BaseModule.scala | 2 +- .../test/src/mill/exec/ExecutionTests.scala | 30 +++++++++++-------- .../src/WatchSourceInputTests.scala | 8 ++--- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/core/define/src/mill/define/BaseModule.scala b/core/define/src/mill/define/BaseModule.scala index 178b29d03934..979f3e053bef 100644 --- a/core/define/src/mill/define/BaseModule.scala +++ b/core/define/src/mill/define/BaseModule.scala @@ -13,7 +13,7 @@ abstract class BaseModule( millModuleEnclosing0: sourcecode.Enclosing, millModuleLine0: sourcecode.Line, millFile0: sourcecode.File -) extends Module.BaseClass()( +) extends Module.BaseClass()(using mill.define.ModuleCtx.makeRoot( implicitly, implicitly, diff --git a/core/exec/test/src/mill/exec/ExecutionTests.scala b/core/exec/test/src/mill/exec/ExecutionTests.scala index 452fa8df7784..96d632d57654 100644 --- a/core/exec/test/src/mill/exec/ExecutionTests.scala +++ b/core/exec/test/src/mill/exec/ExecutionTests.scala @@ -229,13 +229,13 @@ object ExecutionTests extends TestSuite { } UnitTester(build, null).scoped { tester => - val Right(UnitTester.Result(worker1, _)) = tester.apply(build.worker) - val Right(UnitTester.Result(worker2, _)) = tester.apply(build.worker) + val Right(UnitTester.Result(worker1, _)) = tester.apply(build.worker): @unchecked + val Right(UnitTester.Result(worker2, _)) = tester.apply(build.worker): @unchecked assert(worker1 == worker2) assert(worker1.n == 10) assert(!worker1.closed) x = 11 - val Right(UnitTester.Result(worker3, _)) = tester.apply(build.worker) + val Right(UnitTester.Result(worker3, _)) = tester.apply(build.worker): @unchecked assert(worker3 != worker2) assert(worker3.n == 11) assert(!worker3.closed) @@ -298,10 +298,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 +315,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 +333,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 +345,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,11 +422,14 @@ 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") { diff --git a/integration/invalidation/watch-source-input/src/WatchSourceInputTests.scala b/integration/invalidation/watch-source-input/src/WatchSourceInputTests.scala index bbedde4cba86..38a594af8ca8 100644 --- a/integration/invalidation/watch-source-input/src/WatchSourceInputTests.scala +++ b/integration/invalidation/watch-source-input/src/WatchSourceInputTests.scala @@ -72,7 +72,7 @@ object WatchSourceTests extends WatchTests { expectedOut.append( "Setting up build.mill" ) - expectedErr.append( + expectedErr.appendAll( "Running qux foo contents initial-foo1 initial-foo2", "Running qux bar contents initial-bar" ) @@ -82,7 +82,7 @@ object WatchSourceTests extends WatchTests { os.write.over(workspacePath / "foo1.txt", "edited-foo1") awaitCompletionMarker(tester, "quxRan1") - expectedErr.append( + expectedErr.appendAll( "Running qux foo contents edited-foo1 initial-foo2", "Running qux bar contents initial-bar" ) @@ -92,7 +92,7 @@ object WatchSourceTests extends WatchTests { os.write.over(workspacePath / "foo2.txt", "edited-foo2") awaitCompletionMarker(tester, "quxRan2") - expectedErr.append( + expectedErr.appendAll( "Running qux foo contents edited-foo1 edited-foo2", "Running qux bar contents initial-bar" ) @@ -102,7 +102,7 @@ object WatchSourceTests extends WatchTests { os.write.over(workspacePath / "bar.txt", "edited-bar") awaitCompletionMarker(tester, "quxRan3") - expectedErr.append( + expectedErr.appendAll( "Running qux foo contents edited-foo1 edited-foo2", "Running qux bar contents edited-bar" ) From ae7124da44e85023b29fd2cbc1fed7440f969635 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Fri, 23 May 2025 15:27:02 +0200 Subject: [PATCH 4/7] Re-support task dependencies in `Source` and `Sources` --- core/define/src/mill/define/Task.scala | 22 ++++--- core/eval/src/mill/eval/EvaluatorImpl.scala | 24 ++++++-- .../test/src/mill/exec/ExecutionTests.scala | 61 +++++++++++++++++++ 3 files changed, 92 insertions(+), 15 deletions(-) diff --git a/core/define/src/mill/define/Task.scala b/core/define/src/mill/define/Task.scala index 7ae5db113ad5..16ab56802ef8 100644 --- a/core/define/src/mill/define/Task.scala +++ b/core/define/src/mill/define/Task.scala @@ -432,9 +432,9 @@ object Task { val evaluate0: (Seq[Any], mill.define.TaskCtx) => Result[T], val ctx0: mill.define.ModuleCtx, val writer: upickle.default.Writer[?], - val isPrivate: Option[Boolean] + val isPrivate: Option[Boolean], + val inputs: Seq[Task[Any]] = Nil ) extends Simple[T] { - val inputs = Nil override def sideHash: Int = util.Random.nextInt() // FIXME: deprecated return type: Change to Option override def writerOpt: Some[Writer[?]] = Some(writer) @@ -443,23 +443,27 @@ object Task { class Sources( evaluate0: (Seq[Any], mill.define.TaskCtx) => Result[Seq[PathRef]], ctx0: mill.define.ModuleCtx, - isPrivate: Option[Boolean] + isPrivate: Option[Boolean], + inputs: Seq[Task[Any]] ) extends Input[Seq[PathRef]]( evaluate0, ctx0, upickle.default.readwriter[Seq[PathRef]], - isPrivate + isPrivate, + inputs ) {} class Source( evaluate0: (Seq[Any], mill.define.TaskCtx) => Result[PathRef], ctx0: mill.define.ModuleCtx, - isPrivate: Option[Boolean] + isPrivate: Option[Boolean], + inputs: Seq[Task[Any]] ) extends Input[PathRef]( evaluate0, ctx0, upickle.default.readwriter[PathRef], - isPrivate + isPrivate, + inputs ) {} private object Macros { @@ -517,7 +521,7 @@ object Task { ctx: Expr[mill.define.ModuleCtx] ): Expr[Simple[Seq[PathRef]]] = { val expr = appImpl[Simple, Seq[PathRef]]( - (in, ev) => '{ new Sources($ev, $ctx, ${ taskIsPrivate() }) }, + (in, ev) => '{ new Sources($ev, $ctx, ${ taskIsPrivate() }, $in) }, values, allowedTaskReferences = Applicative.TaskReferences.Sources ) @@ -531,7 +535,7 @@ object Task { ): Expr[Simple[PathRef]] = { val expr = appImpl[Simple, PathRef]( - (in, ev) => '{ new Source($ev, $ctx, ${ taskIsPrivate() }) }, + (in, ev) => '{ new Source($ev, $ctx, ${ taskIsPrivate() }, $in) }, value, allowedTaskReferences = Applicative.TaskReferences.Source ) @@ -547,7 +551,7 @@ object Task { ): Expr[Simple[T]] = { val expr = appImpl[Simple, T]( - (in, ev) => '{ new Input[T]($ev, $ctx, $w, ${ taskIsPrivate() }) }, + (in, ev) => '{ new Input[T]($ev, $ctx, $w, ${ taskIsPrivate() }, $in) }, value, allowedTaskReferences = Applicative.TaskReferences.None ) diff --git a/core/eval/src/mill/eval/EvaluatorImpl.scala b/core/eval/src/mill/eval/EvaluatorImpl.scala index 9e397e170418..898df4cb9ee0 100644 --- a/core/eval/src/mill/eval/EvaluatorImpl.scala +++ b/core/eval/src/mill/eval/EvaluatorImpl.scala @@ -141,8 +141,16 @@ final class EvaluatorImpl private[mill] ( val selectiveExecutionEnabled = selectiveExecution && !targets.exists(_.isExclusiveCommand) - val selectedTasksOrErr = - if (!selectiveExecutionEnabled) (targets, Map.empty, None) + val selectedTasksOrErr: ( + selectedTasks: Seq[Task[T]], + selectiveResults: Map[? <: Task[?], ExecResult[Val]], + maybeNewMetadata: Option[SelectiveExecution.Metadata] + ) = + if (!selectiveExecutionEnabled) ( + selectedTasks = targets, + selectiveResults = Map.empty, + maybeNewMetadata = None + ) else { val (named, unnamed) = targets.partitionMap { case n: Task.Named[?] => Left(n); case t => Right(t) } @@ -162,17 +170,21 @@ final class EvaluatorImpl private[mill] ( val selectedSet = changedTasks.downstreamTasks.map(_.ctx.segments.render).toSet ( - unnamed ++ named.filter(t => + selectedTasks = unnamed ++ named.filter(t => t.isExclusiveCommand || selectedSet(t.ctx.segments.render) ), - newComputedMetadata.results, - Some(newComputedMetadata.metadata) + selectiveResults = newComputedMetadata.results, + maybeNewMetadata = Some(newComputedMetadata.metadata) ) } } selectedTasksOrErr match { - case (selectedTasks, selectiveResults, maybeNewMetadata) => + case ( + selectedTasks = selectedTasks, + selectiveResults = selectiveResults, + maybeNewMetadata = maybeNewMetadata + ) => val evaluated: ExecutionResults = execution.executeTasks( selectedTasks, diff --git a/core/exec/test/src/mill/exec/ExecutionTests.scala b/core/exec/test/src/mill/exec/ExecutionTests.scala index 96d632d57654..55038d67fd7e 100644 --- a/core/exec/test/src/mill/exec/ExecutionTests.scala +++ b/core/exec/test/src/mill/exec/ExecutionTests.scala @@ -1,5 +1,6 @@ package mill.exec +import mill.api.Result import mill.define.{Discover, Task} import mill.util.TestGraphs import mill.testkit.{TestRootModule, UnitTester} @@ -97,6 +98,7 @@ object ExecutionTests extends TestSuite { extraEvaled = -1, secondRunNoOp = false ) + // second run should only re-run the source/input-tasks checker( build.task, "i am cow hear me moo !", @@ -124,6 +126,65 @@ object ExecutionTests extends TestSuite { ) } + test("sources-with-deps") { + object build extends TestRootModule { + def source = Task.Sources("hello/world.txt", "hello/world2.txt") + + def sources2 = Task.Sources({ + val res = (source().map(_.path) ++ Seq(moduleDir / "hello/world3.txt")) + .map(Result.create) +// println("res: " + res) + res + }*) + + def task = Task { + sources2().map(pr => os.read(pr.path)).mkString + "!" + } + + lazy val millDiscover = Discover[this.type] + } + + val checker = new Checker(build) + + os.write(build.moduleDir / "hello/world.txt", "i am cow ", createFolders = true) + os.write(build.moduleDir / "hello/world2.txt", "hear me moo ", createFolders = true) + os.write(build.moduleDir / "hello/world3.txt", "moo ", createFolders = true) + checker( + target = build.task, + expValue = "i am cow hear me moo moo !", + expEvaled = Seq(build.sources2, build.source, build.task), + extraEvaled = 0, + secondRunNoOp = false + ) + // second run should only re-run the source/input-tasks + checker( + build.task, + "i am cow hear me moo moo !", + Seq(build.sources2, build.source), + extraEvaled = 0, + secondRunNoOp = false + ) + + os.write.over(build.moduleDir / "hello/world.txt", "I AM COW ") + + checker( + build.task, + "I AM COW hear me moo moo !", + Seq(build.sources2, build.source, build.task), + extraEvaled = 0, + secondRunNoOp = false + ) + + os.write.over(build.moduleDir / "hello/world2.txt", "HEAR ME MOO ") + checker( + build.task, + "I AM COW HEAR ME MOO moo !", + Seq(build.sources2, build.source, build.task), + extraEvaled = 0, + secondRunNoOp = false + ) + } + test("input") { var x = 10 object build extends TestRootModule { From 5fecefa21e939edb117a002c691300298abc0545 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Fri, 23 May 2025 15:56:50 +0200 Subject: [PATCH 5/7] . --- .../watch-source-input/src/WatchSourceInputTests.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/integration/invalidation/watch-source-input/src/WatchSourceInputTests.scala b/integration/invalidation/watch-source-input/src/WatchSourceInputTests.scala index 38a594af8ca8..bbedde4cba86 100644 --- a/integration/invalidation/watch-source-input/src/WatchSourceInputTests.scala +++ b/integration/invalidation/watch-source-input/src/WatchSourceInputTests.scala @@ -72,7 +72,7 @@ object WatchSourceTests extends WatchTests { expectedOut.append( "Setting up build.mill" ) - expectedErr.appendAll( + expectedErr.append( "Running qux foo contents initial-foo1 initial-foo2", "Running qux bar contents initial-bar" ) @@ -82,7 +82,7 @@ object WatchSourceTests extends WatchTests { os.write.over(workspacePath / "foo1.txt", "edited-foo1") awaitCompletionMarker(tester, "quxRan1") - expectedErr.appendAll( + expectedErr.append( "Running qux foo contents edited-foo1 initial-foo2", "Running qux bar contents initial-bar" ) @@ -92,7 +92,7 @@ object WatchSourceTests extends WatchTests { os.write.over(workspacePath / "foo2.txt", "edited-foo2") awaitCompletionMarker(tester, "quxRan2") - expectedErr.appendAll( + expectedErr.append( "Running qux foo contents edited-foo1 edited-foo2", "Running qux bar contents initial-bar" ) @@ -102,7 +102,7 @@ object WatchSourceTests extends WatchTests { os.write.over(workspacePath / "bar.txt", "edited-bar") awaitCompletionMarker(tester, "quxRan3") - expectedErr.appendAll( + expectedErr.append( "Running qux foo contents edited-foo1 edited-foo2", "Running qux bar contents edited-bar" ) From c9c98b75a60992e42cafb3e23aeecf188986f8d4 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Sat, 24 May 2025 11:38:37 +0200 Subject: [PATCH 6/7] Remove Source case --- core/define/src/mill/define/Task.scala | 2 +- core/define/src/mill/define/internal/Applicative.scala | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/core/define/src/mill/define/Task.scala b/core/define/src/mill/define/Task.scala index 16ab56802ef8..8a53ca1f6f3d 100644 --- a/core/define/src/mill/define/Task.scala +++ b/core/define/src/mill/define/Task.scala @@ -537,7 +537,7 @@ object Task { val expr = appImpl[Simple, PathRef]( (in, ev) => '{ new Source($ev, $ctx, ${ taskIsPrivate() }, $in) }, value, - allowedTaskReferences = Applicative.TaskReferences.Source + allowedTaskReferences = Applicative.TaskReferences.Sources ) Cacher.impl0(expr) diff --git a/core/define/src/mill/define/internal/Applicative.scala b/core/define/src/mill/define/internal/Applicative.scala index 259b10b294c2..779e220682d2 100644 --- a/core/define/src/mill/define/internal/Applicative.scala +++ b/core/define/src/mill/define/internal/Applicative.scala @@ -30,9 +30,6 @@ object Applicative { /** No tasks can be references. */ case None - /** Only `Task.Source` tasks can be references. */ - case Source - /** Only `Task.Source` and `Task.Sources` tasks can be references. */ case Sources @@ -88,7 +85,8 @@ object Applicative { case t @ Apply(sel @ Select(fun, "apply"), Nil) if sel.symbol == targetApplySym && allowedTaskReferences != TaskReferences.None => val localDefs = extractDefs(fun) - // TODO: Support TaskReferences.Sources and TaskReference.Source + // TODO: Support TaskReferences.Sources and TaskReference.Source by filtering by type: + // We only want to accept tasks returning PathRef or Seq[PathRef] // it should already work, but we don't restrict it properly visitAllTrees(t) { x => val sym = x.symbol From 1b8befad0c73d1c1c1c26ae2e4e123d7c588117a Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Sat, 24 May 2025 11:41:03 +0200 Subject: [PATCH 7/7] Fix deprecations --- .../watch-source-input/src/WatchSourceInputTests.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/invalidation/watch-source-input/src/WatchSourceInputTests.scala b/integration/invalidation/watch-source-input/src/WatchSourceInputTests.scala index bbedde4cba86..9536ed71bd4d 100644 --- a/integration/invalidation/watch-source-input/src/WatchSourceInputTests.scala +++ b/integration/invalidation/watch-source-input/src/WatchSourceInputTests.scala @@ -54,7 +54,7 @@ trait WatchTests extends UtestIntegrationTestSuite { if (show) assert(err == expectedErr) else assert(err.isEmpty) - val expectedShows = expectedShows0.map('"' + _ + '"') + val expectedShows = expectedShows0.map("\"" + _ + "\"") if (show) assert(shows == expectedShows) } }