@@ -17,7 +17,7 @@ import scala.quoted.*
1717 * single output of type [[T ]].
1818 *
1919 * Generally not instantiated manually, but instead constructed via the
20- * [[Target .apply ]] & similar macros.
20+ * [[Task .apply ]] & similar macros.
2121 */
2222sealed abstract class Task [+ T ] extends Task .Ops [T ] with Applyable [Task , T ] with TaskApi [T ] {
2323
@@ -51,7 +51,92 @@ sealed abstract class Task[+T] extends Task.Ops[T] with Applyable[Task, T] with
5151 }
5252}
5353
54- object Task extends TaskBase {
54+ object Task {
55+
56+ /**
57+ * Returns the [[mill.define.TaskCtx ]] that is available within this task
58+ */
59+ def ctx ()(implicit c : mill.define.TaskCtx ): mill.define.TaskCtx = c
60+
61+ /**
62+ * `Task.dest` is a unique `os.Path` (e.g. `out/classFiles.dest/` or `out/run.dest/`)
63+ * that is assigned to every Target or Command. It is cleared before your
64+ * task runs, and you can use it as a scratch space for temporary files or
65+ * a place to put returned artifacts. This is guaranteed to be unique for
66+ * every Target or Command, so you can be sure that you will not collide or
67+ * interfere with anyone else writing to those same paths.
68+ */
69+ def dest (implicit ctx : mill.define.TaskCtx .Dest ): os.Path = ctx.dest
70+
71+ /**
72+ * `Task.log` is the default logger provided for every task. While your task is running,
73+ * `System.out` and `System.in` are also redirected to this logger. The logs for a
74+ * task are streamed to standard out/error as you would expect, but each task's
75+ * specific output is also streamed to a log file on disk, e.g. `out/run.log` or
76+ * `out/classFiles.log` for you to inspect later.
77+ *
78+ * Messages logged with `log.debug` appear by default only in the log files.
79+ * You can use the `--debug` option when running mill to show them on the console too.
80+ */
81+ def log (implicit ctx : mill.define.TaskCtx .Log ): Logger = ctx.log
82+
83+ /**
84+ * `Task.env` is the environment variable map passed to the Mill command when
85+ * it is run; typically used inside a `Task.Input` to ensure any changes in
86+ * the env vars are properly detected.
87+ *
88+ * Note that you should not use `sys.env`, as Mill's long-lived server
89+ * process means that `sys.env` variables may not be up to date.
90+ */
91+ def env (implicit ctx : mill.define.TaskCtx .Env ): Map [String , String ] = ctx.env
92+
93+ /**
94+ * Returns the implicit [[mill.define.TaskCtx.Args.args ]] in scope.
95+ */
96+ def args (implicit ctx : mill.define.TaskCtx .Args ): IndexedSeq [? ] = ctx.args
97+
98+ /**
99+ * Report test results to BSP for IDE integration
100+ */
101+ def testReporter (implicit ctx : mill.define.TaskCtx ): TestReporter = ctx.testReporter
102+
103+ /**
104+ * Report build results to BSP for IDE integration
105+ */
106+ def reporter (implicit ctx : mill.define.TaskCtx ): Int => Option [CompileProblemReporter ] =
107+ ctx.reporter
108+
109+ /**
110+ * This is the `os.Path` pointing to the project root directory.
111+ *
112+ * This is the preferred access to the project directory, and should
113+ * always be prefered over `os.pwd`* (which might also point to the
114+ * project directory in classic cli scenarios, but might not in other
115+ * use cases like BSP or LSP server usage).
116+ */
117+ def workspace (implicit ctx : mill.define.TaskCtx ): os.Path = ctx.workspace
118+
119+ /**
120+ * Provides the `.fork.async` and `.fork.await` APIs for spawning and joining
121+ * async futures within your task in a Mill-friendly mannter
122+ */
123+ def fork (implicit ctx : mill.define.TaskCtx ): mill.define.TaskCtx .Fork .Api = ctx.fork
124+
125+ def offline (implicit ctx : mill.define.TaskCtx ): Boolean = ctx.offline
126+
127+ def fail (msg : String )(implicit ctx : mill.define.TaskCtx ): Nothing = ctx.fail(msg)
128+
129+ /**
130+ * Converts a `Seq[Task[T]]` into a `Task[Seq[T]]`
131+ */
132+ def sequence [T ](source : Seq [Task [T ]]): Task [Seq [T ]] = new Task .Sequence [T ](source)
133+
134+ /**
135+ * Converts a `Seq[T]` into a `Task[Seq[V]]` using the given `f: T => Task[V]`
136+ */
137+ def traverse [T , V ](source : Seq [T ])(f : T => Task [V ]): Task [Seq [V ]] = {
138+ new Task .Sequence [V ](source.map(f))
139+ }
55140
56141 /**
57142 * A specialization of [[InputImpl ]] defined via `Task.Sources`, [[SourcesImpl ]]
@@ -269,21 +354,21 @@ trait NamedTask[+T] extends Task[T] with NamedTaskApi[T] {
269354 */
270355trait Target [+ T ] extends NamedTask [T ]
271356
272- object Target extends TaskBase {
357+ object Target {
273358
274359 /**
275360 * A target is the most common [[Task ]] a user would encounter, commonly
276361 * defined using the `def foo = Task {...}` syntax. [[TargetImpl ]]s require that their
277362 * return type is JSON serializable. In return they automatically caches their
278363 * return value to disk, only re-computing if upstream [[Task ]]s change
279364 */
280- implicit inline def apply [T ](inline t : T )(implicit
365+ implicit inline def create [T ](inline t : T )(implicit
281366 inline rw : ReadWriter [T ],
282367 inline ctx : ModuleCtx
283368 ): Target [T ] =
284369 $ { TaskMacros .targetResultImpl[T ](' { Result .Success (t) })(' rw , ' ctx , ' { false }) }
285370
286- implicit inline def apply [T ](inline t : Result [T ])(implicit
371+ implicit inline def create [T ](inline t : Result [T ])(implicit
287372 inline rw : ReadWriter [T ],
288373 inline ctx : ModuleCtx
289374 ): Target [T ] =
0 commit comments