summaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authorOlivier Mélois <baccata64@gmail.com>2018-04-18 22:36:00 +0100
committerLi Haoyi <haoyi.sg@gmail.com>2018-04-18 14:36:00 -0700
commit7898368fe809779e73ef1cd909f1b2e5de84e6c1 (patch)
tree1ebe94dd2066fdb7db07ea8d3fd486d9775138ec /core/src
parent5314da0e2dea8d61400241d6c9899ea9077fff8d (diff)
downloadmill-7898368fe809779e73ef1cd909f1b2e5de84e6c1.tar.gz
mill-7898368fe809779e73ef1cd909f1b2e5de84e6c1.tar.bz2
mill-7898368fe809779e73ef1cd909f1b2e5de84e6c1.zip
Make builds able to depend on external projects (#291)
* Make builds able to depend on external projects Builds are now able to load external projects and depend on them as if they were local submodules. `import $file.external.path.build` * Disambiguate "dest" for foreign modules. * Calling modules loaded from external directories "Foreign" to avoid conflicting with the already existing concept of "ExternalModule". * Amended the way `dest` is computed for foreign modules * Added tests to check that the source paths and dest are as expected * Added a test to show that local modules do not conflict with foreign modules when they are named the same * WIP windows build fail * Added bootstrapping step in CYGWIN CI job * * Revert externalOutPath deletion * Add documentation for foreign-modules * reverting appveyor changes * Disabling Foreign modules tests against Java9 See https://github.com/lihaoyi/mill/issues/302
Diffstat (limited to 'core/src')
-rw-r--r--core/src/mill/define/BaseModule.scala7
-rw-r--r--core/src/mill/define/Ctx.scala16
-rw-r--r--core/src/mill/define/Module.scala1
-rw-r--r--core/src/mill/eval/Evaluator.scala28
4 files changed, 46 insertions, 6 deletions
diff --git a/core/src/mill/define/BaseModule.scala b/core/src/mill/define/BaseModule.scala
index fccb19ae..70826be7 100644
--- a/core/src/mill/define/BaseModule.scala
+++ b/core/src/mill/define/BaseModule.scala
@@ -6,7 +6,9 @@ object BaseModule{
case class Implicit(value: BaseModule)
}
-abstract class BaseModule(millSourcePath0: Path, external0: Boolean = false)
+abstract class BaseModule(millSourcePath0: Path,
+ external0: Boolean = false,
+ foreign0 : Boolean = false)
(implicit millModuleEnclosing0: sourcecode.Enclosing,
millModuleLine0: sourcecode.Line,
millName0: sourcecode.Name,
@@ -20,6 +22,7 @@ abstract class BaseModule(millSourcePath0: Path, external0: Boolean = false)
Segments(),
mill.util.Router.Overrides(0),
Ctx.External(external0),
+ Ctx.Foreign(foreign0),
millFile0
)
){
@@ -37,7 +40,7 @@ abstract class BaseModule(millSourcePath0: Path, external0: Boolean = false)
abstract class ExternalModule(implicit millModuleEnclosing0: sourcecode.Enclosing,
millModuleLine0: sourcecode.Line,
millName0: sourcecode.Name)
- extends BaseModule(ammonite.ops.pwd, external0 = true){
+ extends BaseModule(ammonite.ops.pwd, external0 = true, foreign0 = false){
implicit def millDiscoverImplicit: Discover[_] = millDiscover
assert(
diff --git a/core/src/mill/define/Ctx.scala b/core/src/mill/define/Ctx.scala
index 9b8db6ed..fb15dc19 100644
--- a/core/src/mill/define/Ctx.scala
+++ b/core/src/mill/define/Ctx.scala
@@ -1,7 +1,7 @@
package mill.define
-import ammonite.ops.{Path, RelPath}
+import ammonite.ops.Path
import scala.annotation.implicitNotFound
@@ -41,6 +41,7 @@ case class Segments(value: Segment*){
}
head +: stringSegments
}
+ def last : Segments = Segments(value.last)
def render = value.toList match {
case Nil => ""
case Segment.Label(head) :: rest =>
@@ -52,6 +53,13 @@ case class Segments(value: Segment*){
}
}
+object Segments {
+
+ def labels(values : String*) : Segments =
+ Segments(values.map(Segment.Label):_*)
+
+}
+
@implicitNotFound("Modules, Targets and Commands can only be defined within a mill Module")
case class Ctx(enclosing: String,
lineNum: Int,
@@ -60,11 +68,13 @@ case class Ctx(enclosing: String,
segments: Segments,
overrides: Int,
external: Boolean,
+ foreign: Boolean,
fileName: String){
}
object Ctx{
case class External(value: Boolean)
+ case class Foreign(value : Boolean)
implicit def make(implicit millModuleEnclosing0: sourcecode.Enclosing,
millModuleLine0: sourcecode.Line,
millName0: sourcecode.Name,
@@ -72,6 +82,7 @@ object Ctx{
segments0: Segments,
overrides0: mill.util.Router.Overrides,
external0: External,
+ foreign0: Foreign,
fileName: sourcecode.File): Ctx = {
Ctx(
millModuleEnclosing0.value,
@@ -81,7 +92,8 @@ object Ctx{
segments0,
overrides0.value,
external0.value,
+ foreign0.value,
fileName.value
)
}
-} \ No newline at end of file
+}
diff --git a/core/src/mill/define/Module.scala b/core/src/mill/define/Module.scala
index 0f8e96ce..6abcc75a 100644
--- a/core/src/mill/define/Module.scala
+++ b/core/src/mill/define/Module.scala
@@ -26,6 +26,7 @@ class Module(implicit outerCtx0: mill.define.Ctx)
def millOuterCtx = outerCtx0
def millSourcePath: Path = millOuterCtx.millSourcePath / millOuterCtx.segment.pathSegments
implicit def millModuleExternal: Ctx.External = Ctx.External(millOuterCtx.external)
+ implicit def millModuleShared: Ctx.Foreign = Ctx.Foreign(millOuterCtx.foreign)
implicit def millModuleBasePath: BasePath = BasePath(millSourcePath)
implicit def millModuleSegments: Segments = {
millOuterCtx.segments ++ Seq(millOuterCtx.segment)
diff --git a/core/src/mill/eval/Evaluator.scala b/core/src/mill/eval/Evaluator.scala
index c0df83ff..34e1cf6f 100644
--- a/core/src/mill/eval/Evaluator.scala
+++ b/core/src/mill/eval/Evaluator.scala
@@ -124,9 +124,12 @@ case class Evaluator[T](home: Path,
(newResults, newEvaluated, false)
case Right(labelledNamedTask) =>
+ val out = if (!labelledNamedTask.task.ctx.external) outPath
+ else externalOutPath
+
val paths = Evaluator.resolveDestPaths(
- if (!labelledNamedTask.task.ctx.external) outPath else externalOutPath,
- labelledNamedTask.segments
+ out,
+ destSegments(labelledNamedTask)
)
if (!exists(paths.out)) mkdir(paths.out)
@@ -191,6 +194,27 @@ case class Evaluator[T](home: Path,
}
}
}
+
+ def destSegments(labelledTask : Labelled[_]) : Segments = {
+ import labelledTask.task.ctx
+ if (ctx.foreign) {
+ val prefix = "foreign-modules"
+ // Computing a path in "out" that uniquely reflects the location
+ // of the foreign module relatively to the current build.
+ val relative = labelledTask.task
+ .ctx.millSourcePath
+ .relativeTo(rootModule.millSourcePath)
+ // Encoding the number of `/..`
+ val ups = if (relative.ups > 0) Segments.labels(s"up-${relative.ups}")
+ else Segments()
+ Segments.labels(prefix)
+ .++(ups)
+ .++(Segments.labels(relative.segments: _*))
+ .++(labelledTask.segments.last)
+ } else labelledTask.segments
+ }
+
+
def handleTaskResult(v: Any,
hashCode: Int,
metaPath: Path,