/
Ctx.scala
133 lines (115 loc) · 3.9 KB
/
Ctx.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package mill.api
import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.language.implicitConversions
/**
* Provides access to various resources in the context of a currently execution Target.
*/
object Ctx {
@compileTimeOnly("Target.ctx() / T.ctx() / T.* APIs can only be used with a T{...} block")
@ImplicitStub
implicit def taskCtx: Ctx = ???
/**
* Access to the targets [[dest]] path.
*/
trait Dest {
/**
* `T.dest` is a unique `os.Path` (e.g. `out/classFiles.dest/` or `out/run.dest/`)
* that is assigned to every Target or Command. It is cleared before your
* task runs, and you can use it as a scratch space for temporary files or
* a place to put returned artifacts. This is guaranteed to be unique for
* every Target or Command, so you can be sure that you will not collide or
* interfere with anyone else writing to those same paths.
*/
def dest: os.Path
}
object Dest {
implicit def pathToCtx(path: os.Path): Dest = new Dest { def dest = path }
}
/** Access to the targets [[Logger]] instance. */
trait Log {
/**
* `T.log` is the default logger provided for every task. While your task is running,
* `System.out` and `System.in` are also redirected to this logger. The logs for a
* task are streamed to standard out/error as you would expect, but each task's
* specific output is also streamed to a log file on disk, e.g. `out/run.log` or
* `out/classFiles.log` for you to inspect later.
*
* Messages logged with `log.debug` appear by default only in the log files.
* You can use the `--debug` option when running mill to show them on the console too.
*/
def log: Logger
}
object Log {
implicit def logToCtx(l: Logger): Log = new Log { def log = l }
}
/**
* Access to some internal storage dir used by underlying ammonite.
* You should not need this in a buildscript.
*/
trait Home {
def home: os.Path
}
/** Access to the current system environment settings. */
trait Env {
/**
* `T.env` is the environment variable map passed to the Mill command when
* it is run; typically used inside a `T.input` to ensure any changes in
* the env vars are properly detected.
*
* Note that you should not use `sys.env`, as Mill's long-lived server
* process means that `sys.env` variables may not be up to date.
*/
def env: Map[String, String]
}
trait Args {
def args: IndexedSeq[_]
}
/**
* Access to the selected parallel job count (`mill --jobs`).
*/
trait Jobs {
def jobs: Int
}
/** Access to the project root (aka workspace) directory. */
trait Workspace {
/**
* This is the `os.Path` pointing to the project root directory.
*
* This is the preferred access to the project directory, and should
* always be prefered over `os.pwd`* (which might also point to the
* project directory in classic cli scenarios, but might not in other
* use cases like BSP or LSP server usage).
*/
def workspace: os.Path
}
def defaultHome: os.Path = os.home / ".mill" / "ammonite"
/**
* Marker annotation.
*/
class ImplicitStub extends StaticAnnotation
}
/**
* Represents the data and utilities that are contextually available inside the
* implementation of a `Task`.
*/
class Ctx(
val args: IndexedSeq[_],
dest0: () => os.Path,
val log: Logger,
val home: os.Path,
val env: Map[String, String],
val reporter: Int => Option[CompileProblemReporter],
val testReporter: TestReporter,
val workspace: os.Path
) extends Ctx.Dest
with Ctx.Log
with Ctx.Args
with Ctx.Home
with Ctx.Env
with Ctx.Workspace {
def dest: os.Path = dest0()
def arg[T](index: Int): T = {
if (index >= 0 && index < args.length) args(index).asInstanceOf[T]
else throw new IndexOutOfBoundsException(s"Index $index outside of range 0 - ${args.length}")
}
}