Skip to content

Commit

Permalink
Added --import command-line option (#1526)
Browse files Browse the repository at this point in the history
With this PR applied, you can run targets from external modules from the command-line without touching the `build.sc`.

Example:
```
dev-mill --plugin ivy:de.tototec::de.tobiasroeser.mill.vcs.version_mill0.10.0-M2:0.1.2 show de.tobiasroeser.mill.vcs.version.VcsVersion/vcsState
```

This PR also add support for empty versions in $ivy-imports, which will get expanded to the exact mill version. This makes consuming mill contrib plugins even more easy.

Example: Generating Bloop Config without modifying the `build.sc`

```
mill --plugin ivy:com.lihaoyi::mill-contrib-bloop: mill.contrib.bloop.Bloop/install
```

Pull request: #1526
  • Loading branch information
lefou committed Oct 14, 2021
2 parents 959629b + b63d204 commit 5de0742
Show file tree
Hide file tree
Showing 7 changed files with 211 additions and 157 deletions.
51 changes: 30 additions & 21 deletions docs/antora/modules/ROOT/pages/Contrib_Plugins.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,22 @@ For details about including plugins in your `build.sc` read xref:Extending_Mill.
--
When using one of these contribution modules, 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.
You can also leave the version completely empty to default to the mill version (but don't forget to keep the trailing colon).

For instance:

[source,scala]
----
import $ivy.`com.lihaoyi::mill-contrib-bloop:$MILL_VERSION`
----

or

[source,scala]
----
import $ivy.`com.lihaoyi::mill-contrib-bloop:`
----

--

== Artifactory
Expand All @@ -26,7 +35,7 @@ This plugin allows publishing to Artifactory.

[source,scala]
----
import $ivy.`com.lihaoyi::mill-contrib-artifactory:$MILL_VERSION`
import $ivy.`com.lihaoyi::mill-contrib-artifactory:`
import mill.contrib.artifactory.ArtifactoryPublishModule
object mymodule extends ArtifactoryPublishModule {
Expand Down Expand Up @@ -54,7 +63,7 @@ Make sure your module extends from `BintrayPublishModule`:

[source,scala]
----
import $ivy.`com.lihaoyi::mill-contrib-bintray:$MILL_VERSION`
import $ivy.`com.lihaoyi::mill-contrib-bintray:`
import mill.contrib.bintray.BintrayPublishModule
object mymodule extends BintrayPublishModule {
Expand All @@ -73,7 +82,7 @@ the package used, you can do that like this:

[source,scala]
----
import $ivy.`com.lihaoyi::mill-contrib-bintray:$MILL_VERSION`
import $ivy.`com.lihaoyi::mill-contrib-bintray:`
import mill.contrib.bintray.BintrayPublishModule
object mymodule extends BintrayPublishModule {
Expand Down Expand Up @@ -121,7 +130,7 @@ your scala code editable in https://scalameta.org/metals/[Metals]
[source,scala]
----
// build.sc (or any other .sc file it depends on, including predef)
import $ivy.`com.lihaoyi::mill-contrib-bloop:$MILL_VERSION`
import $ivy.`com.lihaoyi::mill-contrib-bloop:`
----

Then in your terminal :
Expand Down Expand Up @@ -174,7 +183,7 @@ Quickstart:
.`build.sc`
[source,scala]
----
import $ivy.`com.lihaoyi::mill-contrib-buildinfo:$MILL_VERSION`
import $ivy.`com.lihaoyi::mill-contrib-buildinfo:`
import mill.contrib.buildinfo.BuildInfo
object project extends BuildInfo {
Expand Down Expand Up @@ -224,7 +233,7 @@ This plugin allows publishing to AWS Codeartifact.

[source,scala]
----
import $ivy.`com.lihaoyi::mill-contrib-codeartifact:$MILL_VERSION`
import $ivy.`com.lihaoyi::mill-contrib-codeartifact:`
import mill.contrib.codeartifact.CodeartifactPublishModule
object mymodule extends CodeartifactPublishModule {
Expand Down Expand Up @@ -322,7 +331,7 @@ Configure flyway by overriding settings in your module. For example
----
import mill._, scalalib._
import $ivy.`com.lihaoyi::mill-contrib-flyway:$MILL_VERSION`
import $ivy.`com.lihaoyi::mill-contrib-flyway:`
import contrib.flyway.FlywayModule
object foo extends ScalaModule with FlywayModule {
Expand Down Expand Up @@ -398,7 +407,7 @@ Twirl versions. You also need to define your own test object which extends the p
[source,scala]
----
import mill._
import $ivy.`com.lihaoyi::mill-contrib-playlib:$MILL_VERSION`, mill.playlib._
import $ivy.`com.lihaoyi::mill-contrib-playlib:`, mill.playlib._
object core extends PlayModule {
//config
Expand Down Expand Up @@ -587,7 +596,7 @@ by mixing in the `SingleModule` trait in your build:
[source,scala]
----
import mill._
import $ivy.`com.lihaoyi::mill-contrib-playlib:$MILL_VERSION`, mill.playlib._
import $ivy.`com.lihaoyi::mill-contrib-playlib:`, mill.playlib._
object core extends PlayModule with SingleModule {
//config
Expand Down Expand Up @@ -632,7 +641,7 @@ define `playVersion` and `scalaVersion`.
[source,scala]
----
import mill._
import $ivy.`com.lihaoyi::mill-contrib-playlib:$MILL_VERSION`, mill.playlib._
import $ivy.`com.lihaoyi::mill-contrib-playlib:`, mill.playlib._
object app extends ScalaModule with RouterModule {
def playVersion= T{"2.7.0"}
Expand Down Expand Up @@ -715,7 +724,7 @@ Here is a simple example:
.`build.sc`
[source,scala]
----
import $ivy.`com.lihaoyi::mill-contrib-proguard:$MILL_VERSION`
import $ivy.`com.lihaoyi::mill-contrib-proguard:`
import contrib.proguard._
object foo extends ScalaModule with Proguard {
Expand All @@ -740,7 +749,7 @@ This creates a Scala module which compiles `.proto` files in the `protobuf` fold
.`build.sc`
[source,scala]
----
import $ivy.`com.lihaoyi::mill-contrib-scalapblib:$MILL_VERSION`
import $ivy.`com.lihaoyi::mill-contrib-scalapblib:`
import contrib.scalapblib._
object example extends ScalaPBModule {
Expand Down Expand Up @@ -779,7 +788,7 @@ If you'd like to configure the https://scalapb.github.io/docs/scalapbc#passing-g
.`build.sc`
[source,scala]
----
import $ivy.`com.lihaoyi::mill-contrib-scalapblib:$MILL_VERSION`
import $ivy.`com.lihaoyi::mill-contrib-scalapblib:`
import contrib.scalapblib._
object example extends ScalaPBModule {
Expand Down Expand Up @@ -819,7 +828,7 @@ module. Additionally, you must define a submodule that extends the
.`build.sc`
[source,scala]
----
import $ivy.`com.lihaoyi::mill-contrib-scoverage:$MILL_VERSION`
import $ivy.`com.lihaoyi::mill-contrib-scoverage:`
import mill.contrib.scoverage.ScoverageModule
object foo extends ScoverageModule {
Expand Down Expand Up @@ -924,7 +933,7 @@ Also note that twirl templates get compiled into scala code, so you also need to
----
import mill.scalalib._
import $ivy.`com.lihaoyi::mill-contrib-twirllib:$MILL_VERSION`, mill.twirllib._
import $ivy.`com.lihaoyi::mill-contrib-twirllib:`, mill.twirllib._
object app extends ScalaModule with TwirlModule {
// ...
Expand Down Expand Up @@ -961,7 +970,7 @@ directory. This directory must be added to the generated sources of the module t
----
import mill.scalalib._
import $ivy.`com.lihaoyi::mill-contrib-twirllib:$MILL_VERSION`, mill.twirllib._
import $ivy.`com.lihaoyi::mill-contrib-twirllib:`, mill.twirllib._
object app extends ScalaModule with TwirlModule {
def twirlVersion = "1.3.15"
Expand Down Expand Up @@ -998,7 +1007,7 @@ To add additional imports to all of the twirl templates, override `twirlImports`
----
import mill.scalalib._
import $ivy.`com.lihaoyi::mill-contrib-twirllib:$MILL_VERSION`, mill.twirllib._
import $ivy.`com.lihaoyi::mill-contrib-twirllib:`, mill.twirllib._
object app extends ScalaModule with TwirlModule {
def twirlVersion = "1.3.15"
Expand Down Expand Up @@ -1040,7 +1049,7 @@ To add additional formats, override `twirlFormats` in your build:
----
import mill.scalalib._
import $ivy.`com.lihaoyi::mill-contrib-twirllib:$MILL_VERSION`, mill.twirllib._
import $ivy.`com.lihaoyi::mill-contrib-twirllib:`, mill.twirllib._
object app extends ScalaModule with TwirlModule {
def twirlVersion = "1.3.15"
Expand Down Expand Up @@ -1078,7 +1087,7 @@ Add a `VersionFileModule` to the `build.sc` file:

[source,scala]
----
import $ivy.`com.lihaoyi::mill-contrib-versionfile:$MILL_VERSION`
import $ivy.`com.lihaoyi::mill-contrib-versionfile:`
import mill.contrib.versionfile.VersionFileModule
object versionFile extends VersionFileModule
Expand Down Expand Up @@ -1115,7 +1124,7 @@ If you want to use the version file for publishing, you can do it like this:

[source,scala]
----
import $ivy.`com.lihaoyi::mill-contrib-versionfile:$MILL_VERSION`
import $ivy.`com.lihaoyi::mill-contrib-versionfile:`
import mill.contrib.versionfile.VersionFileModule
object versionFile extends VersionFileModule
Expand All @@ -1135,7 +1144,7 @@ at the root of the project, you can override `millSourcePath`:

[source,scala]
----
import $ivy.`com.lihaoyi::mill-contrib-versionfile:$MILL_VERSION`
import $ivy.`com.lihaoyi::mill-contrib-versionfile:`
import mill.contrib.versionfile.VersionFileModule
object versionFile extends VersionFileModule {
Expand Down
9 changes: 9 additions & 0 deletions docs/antora/modules/ROOT/pages/Extending_Mill.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,15 @@ This is typical required for Mill contrib modules, which are developed in the Mi
----
import $ivy:`com.lihaoyi:mill-contrib-bloop:$MILL_VERSION`
----

There is the even more convenient option to leave the version completely empty.
Mill will substitute it with its current version.
But don't forget to provide the trailing colon!

.Example: Use `mill-contrib-bloop` plugin matching the current Mill version
----
import $ivy:`com.lihaoyi:mill-contrib-bloop:`
----
--

`$MILL_BIN_PLATFORM` ::
Expand Down
82 changes: 82 additions & 0 deletions main/src/mill/MillConfig.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package mill

import mainargs.{Flag, Leftover, arg}

case class MillConfig(
ammoniteCore: ammonite.main.Config.Core,
@arg(
short = 'h',
doc =
"The home directory of the REPL; where it looks for config and caches"
)
home: os.Path = mill.api.Ctx.defaultHome,
@arg(
doc =
"""Run Mill in interactive mode and start a build REPL. In this mode, no
mill server will be used. Must be the first argument."""
)
repl: Flag,
@arg(
name = "no-server",
doc =
"""Run Mill in interactive mode, suitable for opening REPLs and taking user
input. In this mode, no mill server will be used. Must be the first argument."""
)
noServer: Flag,
@arg(
short = 'i',
doc =
"""Run Mill in interactive mode, suitable for opening REPLs and taking user
input. In this mode, no mill server will be used. Must be the first argument."""
)
interactive: Flag,
@arg(name = "version", short = 'v', doc = "Show mill version and exit.")
showVersion: Flag,
@arg(
name = "bell",
short = 'b',
doc =
"Ring the bell once if the run completes successfully, twice if it fails."
)
ringBell: Flag,
@arg(
name = "disable-ticker",
doc =
"Disable ticker log (e.g. short-lived prints of stages and progress bars)"
)
disableTicker: Flag,
@arg(name = "debug", short = 'd', doc = "Show debug output on STDOUT")
debugLog: Flag,
@arg(
name = "keep-going",
short = 'k',
doc = "Continue build, even after build failures"
)
keepGoing: Flag,
@arg(
name = "define",
short = 'D',
doc = "Define (or overwrite) a system property"
)
extraSystemProperties: Map[String, String],
@arg(
name = "jobs",
short = 'j',
doc =
"""Allow processing N targets in parallel. Use 1 to disable parallel and 0 to
use as much threads as available processors."""
)
threadCountRaw: Option[Int],
@arg(
name = "import",
doc = """Additional ivy dependencies to load into mill, e.g. plugins."""
)
imports: Seq[String],
@arg(
name = "rest",
doc =
"""The name of the targets you want to build, followed by any parameters
you wish to pass to those targets."""
)
leftoverArgs: Leftover[String]
)
30 changes: 30 additions & 0 deletions main/src/mill/MillConfigParser.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package mill

import mainargs.ParserForClass
import ammonite.repl.tools.Util.PathRead

object MillConfigParser {

val customName = s"Mill Build Tool, version ${BuildInfo.millVersion}"
val customDoc = "usage: mill [options] [[target [target-options]] [+ [target ...]]]"

private[this] lazy val parser: ParserForClass[MillConfig] = mainargs.ParserForClass[MillConfig]

lazy val usageText = parser.helpText(customName = customName, customDoc = customDoc)

def parse(args: Array[String]): Either[String, MillConfig] = {
parser.constructEither(
args,
allowRepeats = true,
autoPrintHelpAndExit = None,
customName = customName,
customDoc = customDoc
)
.map { config =>
config.copy(
ammoniteCore = config.ammoniteCore.copy(home = config.home)
)
}
}

}
Loading

0 comments on commit 5de0742

Please sign in to comment.