From fe8667d58aef03e8b97c1361495ab5d851deee60 Mon Sep 17 00:00:00 2001 From: Olivier Mélois Date: Mon, 8 Jul 2019 10:33:31 +0200 Subject: Interpolates $MILL_VERSION in ivy imports (#649) * Interpolates $MILL_VERSION in ivy imports This overrides the default $ivy magic import by replacing the `$MILL_VERSION` string with mill's version, in order to facilitate the loading/update of contrib modules. Ammonite had to be bumped to 1.6.9 * Removed bloop import * AmmoniteExit import fix * Removed repl dep check * Removed problematic check * Made ammonite version override-able --- build.sc | 20 ++- docs/pages/9 - Contrib Modules.md | 265 +++++++++++++++----------------- main/core/src/util/Compat.scala | 13 ++ main/core/src/util/Router.scala | 1 - main/core/src/util/Scripts.scala | 2 +- main/src/main/MainRunner.scala | 5 +- main/src/main/MillIvyHook.scala | 15 ++ scalalib/src/ScalaModule.scala | 8 +- scalalib/src/Versions.scala | 2 +- scalalib/test/src/HelloWorldTests.scala | 3 +- 10 files changed, 188 insertions(+), 146 deletions(-) create mode 100644 main/core/src/util/Compat.scala create mode 100644 main/src/main/MillIvyHook.scala diff --git a/build.sc b/build.sc index b95d46ac..ed5415f8 100755 --- a/build.sc +++ b/build.sc @@ -92,14 +92,30 @@ object main extends MillModule { def ivyDeps = Agg( // Keep synchronized with ammonite in Versions.scala - ivy"com.lihaoyi:::ammonite:1.6.7", + ivy"com.lihaoyi:::ammonite:1.6.9", // Necessary so we can share the JNA classes throughout the build process ivy"net.java.dev.jna:jna:4.5.0", ivy"net.java.dev.jna:jna-platform:4.5.0" ) def generatedSources = T { - Seq(PathRef(shared.generateCoreSources(T.ctx().dest))) + val dest = T.ctx().dest + val version = publishVersion() + writeBuildInfo(dest, version) + shared.generateCoreSources(dest) + Seq(PathRef(dest)) + } + + def writeBuildInfo(dir : os.Path, version : String) = { + val code = s""" + |package mill + | + |object BuildInfo { + | val millVersion = "$version" + |} + """.stripMargin.trim + + os.write(dir / "BuildInfo.scala", code) } } diff --git a/docs/pages/9 - Contrib Modules.md b/docs/pages/9 - Contrib Modules.md index d2038576..73863391 100644 --- a/docs/pages/9 - Contrib Modules.md +++ b/docs/pages/9 - Contrib Modules.md @@ -1,64 +1,69 @@ The plugins in this section are developed/maintained in the mill git tree. -When using one of these, you should make sure to use the versions that matches your mill version. +When using one of these, it is important that the versions you load match your mill version. To facilitate this, Mill will automatically replace the `$MILL_VERSION` literal in your ivy imports with the correct value. + +For instance : + +```scala +import $ivy`com.lihaoyi::mill-contrib-bloop:$MILL_VERSION` +``` [comment]: # (Please keep list of plugins in alphabetical order) ## Bloop -This plugin generates [bloop](https://scalacenter.github.io/bloop/) configuration -from your build file, which lets you use the bloop CLI for compiling, and makes -your scala code editable in [Metals](https://scalameta.org/metals/) +This plugin generates [bloop](https://scalacenter.github.io/bloop/) configuration +from your build file, which lets you use the bloop CLI for compiling, and makes +your scala code editable in [Metals](https://scalameta.org/metals/) ### Quickstart ```scala -// build.sc (or any other .sc file it depends on, including predef) -// Don't forget to replace VERSION -import $ivy.`com.lihaoyi::mill-contrib-bloop:VERSION` +// build.sc (or any other .sc file it depends on, including predef) +import $ivy.`com.lihaoyi::mill-contrib-bloop:$MILL_VERSION` ``` -Then in your terminal : +Then in your terminal : ``` -> mill mill.contrib.Bloop/install +> mill mill.contrib.Bloop/install ``` -It generate correct bloop config for any `JavaModule`, `ScalaModule`, +It generate correct bloop config for any `JavaModule`, `ScalaModule`, `ScalaJsModule` or `ScalaNativeModule` under the `.bloop` folder ### Mix-in -You can mix-in the `Bloop.Module` trait with any JavaModule to quickly access -the deserialised configuration for that particular module: +You can mix-in the `Bloop.Module` trait with any JavaModule to quickly access +the deserialised configuration for that particular module: ```scala -// build.sc -import mill._ +// build.sc +import mill._ import mill.scalalib._ import mill.contrib.Bloop object MyModule extends ScalaModule with Bloop.Module { def myTask = T { bloop.config() } } -``` +``` -### Note regarding metals +### Note regarding metals -Generating the bloop config should be enough for metals to pick it up and for -features to start working in vscode (or the bunch of other editors metals supports). +Generating the bloop config should be enough for metals to pick it up and for +features to start working in vscode (or the bunch of other editors metals supports). However, note that this applies only to your project sources. Your mill/ammonite related -`.sc` files are not yet supported by metals. +`.sc` files are not yet supported by metals. The generated bloop config references the semanticDB compiler plugin required by -metals to function. If need be, the version of semanticDB can be overriden by -extending `mill.contrib.bloop.BloopImpl` in your own space. +metals to function. If need be, the version of semanticDB can be overriden by +extending `mill.contrib.bloop.BloopImpl` in your own space. -### Note regarding current mill support in bloop +### Note regarding current mill support in bloop The mill-bloop integration currently present in the [bloop codebase](https://github.com/scalacenter/bloop/blob/master/integrations/mill-bloop/src/main/scala/bloop/integrations/mill/MillBloop.scala#L10) -will be deprecated in favour of this implementation. +will be deprecated in favour of this implementation. ## BuildInfo @@ -71,8 +76,7 @@ To declare a module that uses BuildInfo you must extend the `mill.contrib.buildi Quickstart: ```scala // build.sc -// You have to replace VERSION -import $ivy.`com.lihaoyi::mill-contrib-buildinfo:VERSION` +import $ivy.`com.lihaoyi::mill-contrib-buildinfo:$MILL_VERSION` import mill.contrib.buildinfo.BuildInfo object project extends BuildInfo { @@ -96,7 +100,7 @@ object project extends BuildInfo { * `def buildInfoPackageName: Option[String]`, default: `None` The package name of the object. - + ## Docker Automatically build docker images from your mill project. @@ -131,9 +135,9 @@ Configure the image by overriding tasks in the `DockerConfig` object object docker extends DockerConfig { // Override tags to set the output image name def tags = List("aws_account_id.dkr.ecr.region.amazonaws.com/hello-repository") - + def baseImage = "openjdk:11" - + // Configure whether the docker build should check the remote registry for a new version of the base image before building. // By default this is true if the base image is using a latest tag def pullBaseImage = true @@ -141,7 +145,7 @@ object docker extends DockerConfig { ``` Run mill in interactive mode to see the docker client output, like `mill -i foo.docker.build`. - + ## Flyway Enables you to configure and run [Flyway](https://flywaydb.org/) commands from your mill build file. @@ -152,15 +156,14 @@ Configure flyway by overriding settings in your module. For example ```scala // build.sc -// You have to replace VERSION import mill._, scalalib._ -import ivy`com.lihaoyi::mill-contrib-flyway:VERSION` +import ivy`com.lihaoyi::mill-contrib-flyway:$MILL_VERSION` import contrib.flyway.FlywayModule object foo extends ScalaModule with FlywayModule { def scalaVersion = "2.12.8" - + //region flyway def flywayUrl = "jdbc:postgresql:myDb" // required def flywayDriverDeps = Agg(ivy"org.postgresql:postgresql:42.2.5") // required @@ -181,14 +184,14 @@ mill foo.flywayInfo mill foo.flywayMigrate ``` -> REMINDER: +> REMINDER: > You should never hard-code credentials or check them into a version control system. -> You should write some code to populate the settings for flyway instead. +> You should write some code to populate the settings for flyway instead. > For example `def flywayPassword = T.input(T.ctx().env("FLYWAY_PASSWORD"))` ## Play Framework -This module adds basic Play Framework support to mill: +This module adds basic Play Framework support to mill: * configures mill for Play default directory layout, * integrates the Play routes compiler, @@ -196,42 +199,41 @@ This module adds basic Play Framework support to mill: * optionally: integrates the Twirl template engine, * optionally: configures mill for single module play applications. -There is no specific Play Java support, building a Play Java application will require a bit -of customization (mostly adding the proper dependencies). +There is no specific Play Java support, building a Play Java application will require a bit +of customization (mostly adding the proper dependencies). ### Using the plugin There are 2 base modules and 2 helper traits in this plugin, all of which can be found in `mill.playlib`. -The base modules: +The base modules: -* `PlayModule` applies the default Play configuration (layout, dependencies, routes compilation, +* `PlayModule` applies the default Play configuration (layout, dependencies, routes compilation, Twirl compilation and Akka HTTP server) -* `PlayApiModule` applies the default Play configuration without `Twirl` templating. This is useful +* `PlayApiModule` applies the default Play configuration without `Twirl` templating. This is useful if your Play app is a pure API server or if you want to use a different templating engine. -The two helper traits: +The two helper traits: -* `SingleModule` can be useful to configure mill for a single module Play application such as the -[play-scala-seed project](https://github.com/playframework/play-scala-seed.g8). Mill is -multi-module by default and requires a bit more configuration to have source, resource, and test -directories at the top level alongside the `build.sc` file. This trait takes care of that (See -[Using SingleModule](#using-singlemodule) below). -* `RouterModule` allows you to use the Play router without the rest of the configuration (see +* `SingleModule` can be useful to configure mill for a single module Play application such as the +[play-scala-seed project](https://github.com/playframework/play-scala-seed.g8). Mill is +multi-module by default and requires a bit more configuration to have source, resource, and test +directories at the top level alongside the `build.sc` file. This trait takes care of that (See +[Using SingleModule](#using-singlemodule) below). +* `RouterModule` allows you to use the Play router without the rest of the configuration (see [Using the router module directly](#using-the-router-module-directly).) ### Using `PlayModule` -In order to use the `PlayModule` for your application, you need to provide the scala, Play and -Twirl versions. You also need to define your own test object which extends the provided -`PlayTests` trait. +In order to use the `PlayModule` for your application, you need to provide the scala, Play and +Twirl versions. You also need to define your own test object which extends the provided +`PlayTests` trait. ```scala // build.sc import mill._ -// You have to replace VERSION -import $ivy.`com.lihaoyi::mill-contrib-playlib:VERSION`, mill.playlib._ +import $ivy.`com.lihaoyi::mill-contrib-playlib:$MILL_VERSION`, mill.playlib._ object core extends PlayModule { @@ -239,10 +241,10 @@ object core extends PlayModule { override def scalaVersion= T{"2.12.8"} override def playVersion= T{"2.7.0"} override def twirlVersion= T{"1.4.0"} - + object test extends PlayTests -} -``` +} +``` Using the above definition, your build will be configured to use the default Play layout: @@ -256,7 +258,7 @@ Using the above definition, your build will be configured to use the default Pla ├── conf │   └── application.conf │   └── routes - │   └── ... + │   └── ... ├── logs ├── public │   ├── images @@ -275,14 +277,14 @@ ivy"com.typesafe.play::play-server:${playVersion()}", ivy"com.typesafe.play::play-logback:${playVersion()}" ``` -Scala test will be setup as the default test framework and the following test dependencies will be +Scala test will be setup as the default test framework and the following test dependencies will be added (the actual version depends on the version of Play you are pulling `2.6.x` or `2.7.x`): ``` ivy"org.scalatestplus.play::scalatestplus-play::4.0.1" ``` -In order to have a working `start` command the following runtime dependency is also added: +In order to have a working `start` command the following runtime dependency is also added: ``` ivy"com.typesafe.play::play-akka-http-server:${playVersion()}" @@ -296,27 +298,26 @@ The `PlayApiModule` trait behaves the same as the `PlayModule` trait but it won' ```scala // build.sc import mill._ -// You have to replace VERSION -import $ivy.`com.lihaoyi::mill-contrib-playlib:VERSION`, mill.playlib._ +import $ivy.`com.lihaoyi::mill-contrib-playlib:$MILL_VERSION`, mill.playlib._ object core extends PlayApiModule { //config override def scalaVersion= T{"2.12.8"} - override def playVersion= T{"2.7.0"} - + override def playVersion= T{"2.7.0"} + object test extends PlayTests -} +} ``` ### Play configuration options -The Play modules themselves don't have specific configuration options at this point but the [router -module configuration options](#router-configuration-options) and the [Twirl module configuration options](#twirl-configuration-options) are applicable. +The Play modules themselves don't have specific configuration options at this point but the [router +module configuration options](#router-configuration-options) and the [Twirl module configuration options](#twirl-configuration-options) are applicable. ### Additional play libraries -The following helpers are available to provide additional Play Framework dependencies: +The following helpers are available to provide additional Play Framework dependencies: * `core()` - added by default , * `guice()` - added by default, @@ -326,49 +327,48 @@ The following helpers are available to provide additional Play Framework depende * `jdbc()` - optional, * `filters()` - optional, * `ws()` - optional, -* `caffeine()` - optional. +* `caffeine()` - optional. -If you want to add an optional library using the helper you can do so by overriding `ivyDeps` -like in the following example build: +If you want to add an optional library using the helper you can do so by overriding `ivyDeps` +like in the following example build: ```scala // build.sc import mill._ -// You have to replace VERSION -import $ivy.`com.lihaoyi::mill-contrib-playlib:VERSION`, mill.playlib._ +import $ivy.`com.lihaoyi::mill-contrib-playlib:$MILL_VERSION`, mill.playlib._ object core extends PlayApiModule { //config override def scalaVersion= T{"2.12.8"} - override def playVersion= T{"2.7.0"} - + override def playVersion= T{"2.7.0"} + object test extends PlayTests - + override def ivyDeps = T{ super.ivyDeps() ++ Agg(ws(), filters()) } -} -``` +} +``` ### Commands equivalence Mill commands are targets on a named build. For example if your build is called `core`: * compile: `core.compile` -* run: *NOT Implemented yet*. It can be approximated with `mill -w core.runBackground` but this -starts a server in *PROD* mode which: +* run: *NOT Implemented yet*. It can be approximated with `mill -w core.runBackground` but this +starts a server in *PROD* mode which: * doesn't do any kind of classloading magic (meaning potentially slower restarts) * returns less detailed error messages (no source code extract and line numbers) - * can sometimes fail because of a leftover RUNNING_PID file -* start: `core.start` or `core.run` both start the server in *PROD* mode. + * can sometimes fail because of a leftover RUNNING_PID file +* start: `core.start` or `core.run` both start the server in *PROD* mode. * test: `core.test` -* dist: *NOT Implemented yet*. However you can use the equivalent `core.assembly` -command to get a runnable fat jar of the project. The packaging is slightly different but should +* dist: *NOT Implemented yet*. However you can use the equivalent `core.assembly` +command to get a runnable fat jar of the project. The packaging is slightly different but should be find for a production deployment. ### Using `SingleModule` The `SingleModule` trait allows you to have the build descriptor at the same level as the source - code on the filesystem. You can move from there to a multi-module build either by refactoring + code on the filesystem. You can move from there to a multi-module build either by refactoring your directory layout into multiple subdirectories or by using mill's nested modules feature. Looking back at the sample build definition in [Using PlayModule](#using-playmodule): @@ -376,8 +376,7 @@ Looking back at the sample build definition in [Using PlayModule](#using-playmod ```scala // build.sc import mill._ -// You have to replace VERSION -import $ivy.`com.lihaoyi::mill-contrib-playlib:VERSION`, mill.playlib._ +import $ivy.`com.lihaoyi::mill-contrib-playlib:$MILL_VERSION`, mill.playlib._ object core extends PlayModule { @@ -385,9 +384,9 @@ object core extends PlayModule { override def scalaVersion= T{"2.12.8"} override def playVersion= T{"2.7.0"} override def twirlVersion= T{"1.4.0"} - + object test extends PlayTests -} +} ``` The directory layout was: @@ -402,7 +401,7 @@ The directory layout was: ├── conf │   └── application.conf │   └── routes - │   └── ... + │   └── ... ├── logs ├── public │   ├── images @@ -417,8 +416,7 @@ by mixing in the `SingleModule` trait in your build: ```scala // build.sc import mill._ -// You have to replace VERSION -import $ivy.`com.lihaoyi::mill-contrib-playlib:VERSION`, mill.playlib._ +import $ivy.`com.lihaoyi::mill-contrib-playlib:$MILL_VERSION`, mill.playlib._ object core extends PlayModule with SingleModule { @@ -426,12 +424,12 @@ object core extends PlayModule with SingleModule { override def scalaVersion= T{"2.12.8"} override def playVersion= T{"2.7.0"} override def twirlVersion= T{"1.4.0"} - + object test extends PlayTests -} +} ``` -the layout becomes: +the layout becomes: ```text . @@ -443,7 +441,7 @@ the layout becomes: ├── conf │   └── application.conf │   └── routes - │   └── ... + │   └── ... ├── logs ├── public │   ├── images @@ -455,36 +453,35 @@ the layout becomes: #### Using the router module directly -If you want to use the router module in a project which doesn't use the default Play layout, you +If you want to use the router module in a project which doesn't use the default Play layout, you can mix-in the `mill.playlib.routesModule` trait directly when defining your module. Your app must -define `playVersion` and `scalaVersion`. +define `playVersion` and `scalaVersion`. ```scala // build.sc import mill._ -// You have to replace VERSION -import $ivy.`com.lihaoyi::mill-contrib-playlib:VERSION`, mill.playlib._ +import $ivy.`com.lihaoyi::mill-contrib-playlib:$MILL_VERSION`, mill.playlib._ object app extends ScalaModule with RouterModule { def playVersion= T{"2.7.0"} def scalaVersion= T{"2.12.8"} -} -``` +} +``` ##### Router Configuration options * `def playVersion: T[String]` (mandatory) - The version of Play to use to compile the routes file. * `def scalaVersion: T[String]` - The scalaVersion in use in your project. -* `def routes: Sources` - The directory which contains your route files. (Defaults to : `routes/`) -* `def routesAdditionalImport: Seq[String]` - Additional imports to use in the generated routers. +* `def routes: Sources` - The directory which contains your route files. (Defaults to : `routes/`) +* `def routesAdditionalImport: Seq[String]` - Additional imports to use in the generated routers. (Defaults to `Seq("controllers.Assets.Asset", "play.libs.F")` * `def generateForwardsRouter: Boolean = true` - Enables the forward router generation. * `def generateReverseRouter: Boolean = true` - Enables the reverse router generation. * `def namespaceReverseRouter: Boolean = false` - Enables the namespacing of reverse routers. -* `def generatorType: RouteCompilerType = RouteCompilerType.InjectedGenerator` - The routes +* `def generatorType: RouteCompilerType = RouteCompilerType.InjectedGenerator` - The routes compiler type, one of RouteCompilerType.InjectedGenerator or RouteCompilerType.StaticGenerator - + ##### Details The following filesystem layout is expected by default: @@ -505,10 +502,10 @@ mill app.compileRouter (it will be automatically run whenever you compile your module) -This task will compile `routes` templates into the `out/app/compileRouter/dest` -directory. This directory must be added to the generated sources of the module to be compiled and -made accessible from the rest of the code. This is done by default in the trait, but if you need -to have a custom override for `generatedSources` you can get the list of files from `routerClasses` +This task will compile `routes` templates into the `out/app/compileRouter/dest` +directory. This directory must be added to the generated sources of the module to be compiled and +made accessible from the rest of the code. This is done by default in the trait, but if you need +to have a custom override for `generatedSources` you can get the list of files from `routerClasses` To add additional imports to all of the routes: @@ -516,14 +513,13 @@ To add additional imports to all of the routes: // build.sc import mill.scalalib._ -// You have to replace VERSION -import $ivy.`com.lihaoyi::mill-contrib-playlib:VERSION`, mill.playlib._ +import $ivy.`com.lihaoyi::mill-contrib-playlib:$MILL_VERSION`, mill.playlib._ object app extends ScalaModule with RouterModule { def playVersion = "2.7.0" - override def routesAdditionalImport = Seq("my.additional.stuff._", "my.other.stuff._") + override def routesAdditionalImport = Seq("my.additional.stuff._", "my.other.stuff._") } -``` +``` ## ScalaPB @@ -537,8 +533,7 @@ This creates a Scala module which compiles `.proto` files in the `protobuf` fold ```scala // build.sc -// You have to replace VERSION -import $ivy.`com.lihaoyi::mill-contrib-scalapblib:VERSION` +import $ivy.`com.lihaoyi::mill-contrib-scalapblib:$MILL_VERSION` import contrib.scalapblib._ object example extends ScalaPBModule { @@ -574,8 +569,7 @@ If you'd like to configure the options that are passed to the ScalaPB compiler d ```scala // build.sc -// You have to replace VERSION -import $ivy.`com.lihaoyi::mill-contrib-scalapblib:VERSION` +import $ivy.`com.lihaoyi::mill-contrib-scalapblib:$MILL_VERSION` import contrib.scalapblib._ object example extends ScalaPBModule { @@ -598,8 +592,7 @@ module. Additionally, you must define a submodule that extends the `ScoverageTests` trait that belongs to your instance of `ScoverageModule`. ```scala -// You have to replace VERSION -import $ivy.`com.lihaoyi::mill-contrib-scoverage:VERSION` +import $ivy.`com.lihaoyi::mill-contrib-scoverage:$MILL_VERSION` import mill.contrib.scoverage.ScoverageModule object foo extends ScoverageModule { @@ -660,8 +653,7 @@ By default the resulting documents are simply placed in the Mill build output fo ```scala // build.sc -// You have to replace VERSION -import $ivy.`com.lihaoyi::mill-contrib-tut:VERSION` +import $ivy.`com.lihaoyi::mill-contrib-tut:$MILL_VERSION` import contrib.tut._ object example extends TutModule { @@ -710,29 +702,28 @@ sh> mill example.tut Twirl templates support. -To declare a module that needs to compile twirl templates you must extend the `mill.twirllib.TwirlModule` trait when defining your module. +To declare a module that needs to compile twirl templates you must extend the `mill.twirllib.TwirlModule` trait when defining your module. Also note that twirl templates get compiled into scala code, so you also need to extend `ScalaModule`. - + ```scala // build.sc import mill.scalalib._ -// You have to replace VERSION -import $ivy.`com.lihaoyi::mill-contrib-twirllib:VERSION`, mill.twirllib._ +import $ivy.`com.lihaoyi::mill-contrib-twirllib:$MILL_VERSION`, mill.twirllib._ object app extends ScalaModule with TwirlModule { // ... -} -``` +} +``` ### Twirl configuration options * `def twirlVersion: T[String]` (mandatory) - the version of the twirl compiler to use, like "1.3.15" * `def twirlAdditionalImports: Seq[String] = Nil` - the additional imports that will be added by twirl compiler to the top of all templates -* `def twirlConstructorAnnotations: Seq[String] = Nil` - annotations added to the generated classes' constructors (note it only applies to templates with `@this(...)` constructors) -* `def twirlCodec = Codec(Properties.sourceEncoding)` - the codec used to generate the files (the default is the same sbt plugin uses) -* `def twirlInclusiveDot: Boolean = false` - +* `def twirlConstructorAnnotations: Seq[String] = Nil` - annotations added to the generated classes' constructors (note it only applies to templates with `@this(...)` constructors) +* `def twirlCodec = Codec(Properties.sourceEncoding)` - the codec used to generate the files (the default is the same sbt plugin uses) +* `def twirlInclusiveDot: Boolean = false` + ### Details The following filesystem layout is expected: @@ -753,21 +744,20 @@ mill app.compileTwirl (it will be automatically run whenever you compile your module) -This task will compile `*.scala.html` templates (and others, like `*.scala.txt`) into the `out/app/compileTwirl/dest` +This task will compile `*.scala.html` templates (and others, like `*.scala.txt`) into the `out/app/compileTwirl/dest` directory. This directory must be added to the generated sources of the module to be compiled and made accessible from the rest of the code: ```scala // build.sc import mill.scalalib._ -// You have to replace VERSION -import $ivy.`com.lihaoyi::mill-contrib-twirllib:VERSION`, mill.twirllib._ +import $ivy.`com.lihaoyi::mill-contrib-twirllib:$MILL_VERSION`, mill.twirllib._ object app extends ScalaModule with TwirlModule { def twirlVersion = "1.3.15" def generatedSources = T{ Seq(compileTwirl().classes) } } -``` +``` To add additional imports to all of the twirl templates: @@ -775,15 +765,14 @@ To add additional imports to all of the twirl templates: // build.sc import mill.scalalib._ -// You have to replace VERSION -import $ivy.`com.lihaoyi::mill-contrib-twirllib:VERSION`, mill.twirllib._ +import $ivy.`com.lihaoyi::mill-contrib-twirllib:$MILL_VERSION`, mill.twirllib._ object app extends ScalaModule with TwirlModule { def twirlVersion = "1.3.15" override def twirlAdditionalImports = Seq("my.additional.stuff._", "my.other.stuff._") def generatedSources = T{ Seq(compileTwirl().classes) } } -``` +``` as the result all templates will get this line at the top: @@ -803,7 +792,7 @@ Seq( "_root_.play.twirl.api.Txt", "_root_.play.twirl.api.Xml" ) -``` +``` These imports will always be added to every template. You don't need to list them if you override `twirlAdditionalImports`. diff --git a/main/core/src/util/Compat.scala b/main/core/src/util/Compat.scala new file mode 100644 index 00000000..859f3747 --- /dev/null +++ b/main/core/src/util/Compat.scala @@ -0,0 +1,13 @@ +package mill.util + +import scala.reflect.macros.blackbox.Context + +object Compat{ + def copyAnnotatedType(c: Context) + (tpe: c.universe.AnnotatedType, + newAnnots: List[c.universe.Annotation]) = { + import c.universe.compat._ + + c.universe.AnnotatedType(newAnnots, tpe.underlying) + } +} diff --git a/main/core/src/util/Router.scala b/main/core/src/util/Router.scala index 5dd3c947..9504b937 100644 --- a/main/core/src/util/Router.scala +++ b/main/core/src/util/Router.scala @@ -1,6 +1,5 @@ package mill.util -import ammonite.main.Compat import language.experimental.macros import scala.annotation.StaticAnnotation diff --git a/main/core/src/util/Scripts.scala b/main/core/src/util/Scripts.scala index 65eb6b2b..f61d5cb5 100644 --- a/main/core/src/util/Scripts.scala +++ b/main/core/src/util/Scripts.scala @@ -3,7 +3,7 @@ package mill.util import java.nio.file.NoSuchFileException -import ammonite.runtime.Evaluator.AmmoniteExit +import ammonite.interp.api.AmmoniteExit import ammonite.util.Name.backtickWrap import ammonite.util.Util.CodeSource import ammonite.util.{Name, Res, Util} diff --git a/main/src/main/MainRunner.scala b/main/src/main/MainRunner.scala index 6705a4b3..354b6173 100644 --- a/main/src/main/MainRunner.scala +++ b/main/src/main/MainRunner.scala @@ -9,6 +9,7 @@ import mill.eval.{Evaluator, PathRef} import mill.util.PrintLogger import scala.annotation.tailrec +import ammonite.runtime.ImportHook /** @@ -120,11 +121,13 @@ class MainRunner(val config: ammonite.main.Cli.Config, } override def initMain(isRepl: Boolean) = { + val hooks = ImportHook.defaults + (Seq("ivy") -> MillIvyHook) super.initMain(isRepl).copy( scriptCodeWrapper = CustomCodeWrapper, // Ammonite does not properly forward the wd from CliConfig to Main, so // force forward it outselves - wd = config.wd + wd = config.wd, + importHooks = hooks ) } diff --git a/main/src/main/MillIvyHook.scala b/main/src/main/MillIvyHook.scala new file mode 100644 index 00000000..2b4eb6a7 --- /dev/null +++ b/main/src/main/MillIvyHook.scala @@ -0,0 +1,15 @@ +package mill.main +import ammonite.runtime.ImportHook.BaseIvy +import ammonite.runtime.ImportHook +import java.io.File + +/** + * Overrides the ivy hook to interpret $MILL_VERSION as the version of mill + * the user runs. + * + * Can be used to ensure loaded contrib modules keep up to date. + */ +object MillIvyHook extends BaseIvy(plugin = false){ + override def resolve(interp: ImportHook.InterpreterInterface, signatures: Seq[String]): Either[String,Set[File]] = + super.resolve(interp, signatures.map(_.replace("$MILL_VERSION", mill.BuildInfo.millVersion))) +} diff --git a/scalalib/src/ScalaModule.scala b/scalalib/src/ScalaModule.scala index f45a7e98..0ebd5700 100644 --- a/scalalib/src/ScalaModule.scala +++ b/scalalib/src/ScalaModule.scala @@ -196,6 +196,12 @@ trait ScalaModule extends JavaModule { outer => } } + /** + * Ammonite's version used in the `repl` command is by default + * set to the one Mill is built against. + */ + def ammoniteVersion = T(Versions.ammonite) + /** * Dependencies that are necessary to run the Ammonite Scala REPL */ @@ -205,7 +211,7 @@ trait ScalaModule extends JavaModule { outer => unmanagedClasspath() ++ resolveDeps(T.task{ runIvyDeps() ++ scalaLibraryIvyDeps() ++ transitiveIvyDeps() ++ - Agg(ivy"com.lihaoyi:::ammonite:${Versions.ammonite}") + Agg(ivy"com.lihaoyi:::ammonite:${ammoniteVersion()}") })() } diff --git a/scalalib/src/Versions.scala b/scalalib/src/Versions.scala index 973b05ed..3fddd545 100644 --- a/scalalib/src/Versions.scala +++ b/scalalib/src/Versions.scala @@ -2,7 +2,7 @@ package mill.scalalib object Versions { // Keep synchronized with ammonite dependency in core in build.sc - val ammonite = "1.6.7" + val ammonite = "1.6.9" // Keep synchronized with zinc dependency in scalalib.worker in build.sc val zinc = "1.2.5" } diff --git a/scalalib/test/src/HelloWorldTests.scala b/scalalib/test/src/HelloWorldTests.scala index 57750991..d74d7d64 100644 --- a/scalalib/test/src/HelloWorldTests.scala +++ b/scalalib/test/src/HelloWorldTests.scala @@ -212,6 +212,7 @@ object HelloWorldTests extends TestSuite { object foo extends ScalaModule { def scalaVersion = "2.11.8" override def scalaOrganization = "org.typelevel" + override def ammoniteVersion = "1.6.7" def ivyDeps = Agg( ivy"com.github.julien-truffaut::monocle-macro::1.4.0" @@ -241,7 +242,7 @@ object HelloWorldTests extends TestSuite { object HelloWorldFlags extends HelloBase{ object core extends ScalaModule { def scalaVersion = "2.12.4" - + def scalacOptions = super.scalacOptions() ++ Seq( "-Ypartial-unification" ) -- cgit v1.2.3