Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an example doc folder for writing and testing a Mill plugin #3416

Merged
merged 25 commits into from
Aug 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
10 changes: 7 additions & 3 deletions .github/workflows/actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,17 @@ jobs:
# Group these tests together to try and balance out the runtimes of each job
# Just running in `local` mode since they shouldn't depend on the mode
- java-version: 17
millargs: "'example.{basic,scalabuilds,scalamodule,scalatesting,web}[_].local.test'"
millargs: "'example.javalib.__.local.test'"
- java-version: 17
millargs: "'example.{basicjava,javabuilds,javamodule,javatesting,javaweb}[_].local.test'"
millargs: "'example.scalalib.__.local.test'"
- java-version: 11
millargs: "'example.thirdparty[{mockito,acyclic,commons-io}].local.test'"
- java-version: 17
millargs: "'example.thirdparty[{fansi,jimfs,netty}].local.test'"
- java-version: 11
millargs: "'example.depth.__.local.test'"
- java-version: 17
millargs: "'example.extending.__.local.test'"

# Most of these integration tests should not depend on which mode they
# are run in, so just run them in `local`
Expand Down Expand Up @@ -144,7 +148,7 @@ jobs:
- java-version: 17
millargs: '"scalajslib.__.test"'
- java-version: 11
millargs: '"example.basic[_].local.test"'
millargs: '"example.scalalib.basic.__.local.test"'
- java-version: 17
millargs: "'integration.feature[_].fork.test'"
- java-version: 11
Expand Down
148 changes: 91 additions & 57 deletions build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.github.lolgab.mill.mima.Mima
import coursier.maven.MavenRepository
import de.tobiasroeser.mill.vcs.version.VcsVersion
import com.goyeau.mill.scalafix.ScalafixModule
import example.millSourcePath
import mill._
import mill.api.JarManifest
import mill.define.NamedTask
Expand Down Expand Up @@ -305,6 +306,21 @@ trait MillJavaModule extends JavaModule {
upstream.toMap ++ current
}


def testIvyDeps: T[Agg[Dep]] = Agg(Deps.TestDeps.utest)
def testModuleDeps: Seq[JavaModule] =
if (this == main) Seq(main)
else Seq(this, main.test)

def writeLocalTestOverrides = T.task {
for ((k, v) <- testTransitiveDeps()) {
os.write(T.dest / "mill" / "local-test-overrides" / k, v, createFolders = true)
}
Seq(PathRef(T.dest))
}

def runClasspath = super.runClasspath() ++ writeLocalTestOverrides()

def repositoriesTask = T.task {
super.repositoriesTask() ++
Seq(MavenRepository("https://oss.sonatype.org/content/repositories/releases"))
Expand Down Expand Up @@ -368,20 +384,6 @@ trait MillScalaModule extends ScalaModule with MillJavaModule with ScalafixModul
"-Xlint:adapted-args"
)

def testIvyDeps: T[Agg[Dep]] = Agg(Deps.TestDeps.utest)
def testModuleDeps: Seq[JavaModule] =
if (this == main) Seq(main)
else Seq(this, main.test)

def writeLocalTestOverrides = T.task {
for ((k, v) <- testTransitiveDeps()) {
os.write(T.dest / "mill" / "local-test-overrides" / k, v, createFolders = true)
}
Seq(PathRef(T.dest))
}

def runClasspath = super.runClasspath() ++ writeLocalTestOverrides()

def scalacPluginIvyDeps =
super.scalacPluginIvyDeps() ++
Agg(Deps.acyclic) ++
Expand All @@ -394,7 +396,6 @@ trait MillScalaModule extends ScalaModule with MillJavaModule with ScalafixModul
/** Default tests module. */
lazy val test: MillScalaTests = new MillScalaTests {}
trait MillScalaTests extends ScalaTests with MillBaseTestsModule {
def runClasspath = super.runClasspath() ++ writeLocalTestOverrides()
def forkArgs = super.forkArgs() ++ outer.testArgs()
def moduleDeps = outer.testModuleDeps
def ivyDeps = super.ivyDeps() ++ outer.testIvyDeps()
Expand Down Expand Up @@ -598,18 +599,18 @@ object main extends MillStableScalaModule with BuildInfo {
"millEmbeddedDeps",
(
T.traverse(
dev.recursiveModuleDeps.collect { case m: PublishModule => m }
dist.recursiveModuleDeps.collect { case m: PublishModule => m }
)(
_.publishSelfDependency
)()
.map(artifact => s"${artifact.group}:${artifact.id}:${artifact.version}") ++
Lib.resolveDependenciesMetadata(
repositories = dev.repositoriesTask(),
dev.transitiveIvyDeps(),
Some(dev.mapDependencies()),
dev.resolutionCustomizer(),
repositories = dist.repositoriesTask(),
dist.transitiveIvyDeps(),
Some(dist.mapDependencies()),
dist.resolutionCustomizer(),
Some(T.ctx()),
dev.coursierCacheCustomizer()
dist.coursierCacheCustomizer()
)._2.minDependencies.toSeq
.map(d => s"${d.module.organization.value}:${d.module.name.value}:${d.version}")
)
Expand Down Expand Up @@ -762,7 +763,7 @@ object testkit extends MillPublishScalaModule {
super.sources() ++
Seq(PathRef(build.millSourcePath / "mill-build" / "src"))

def forkEnv = super.forkEnv() ++ Map("MILL_EXECUTABLE_PATH" -> dev.launcher().path.toString())
def forkEnv = super.forkEnv() ++ Map("MILL_EXECUTABLE_PATH" -> dist.launcher().path.toString())
}

object testrunner extends MillPublishScalaModule {
Expand Down Expand Up @@ -1178,10 +1179,10 @@ trait IntegrationTestModule extends MillScalaModule {
) ++
testReleaseEnv()

def forkArgs = T { super.forkArgs() ++ dev.forkArgs() }
def forkArgs = T { super.forkArgs() ++ dist.forkArgs() }

def testReleaseEnv =
if (mode == "local") T { Map("MILL_INTEGRATION_LAUNCHER" -> dev.launcher().path.toString()) }
if (mode == "local") T { Map("MILL_INTEGRATION_LAUNCHER" -> dist.launcher().path.toString()) }
else T { Map("MILL_INTEGRATION_LAUNCHER" -> integration.testMill().path.toString()) }

def compile = IntegrationTestModule.this.compile()
Expand All @@ -1201,30 +1202,46 @@ trait IntegrationTestCrossModule extends IntegrationTestModule with Cross.Module
def listIn(path: os.Path) = interp.watchValue(os.list(path).map(_.last))

object example extends Module {
def exampleModules: Seq[ExampleCrossModule] =
millInternal.modules.collect { case m: ExampleCrossModule => m }

object basic extends Cross[ExampleCrossModule](listIn(millSourcePath / "basic"))
object basicjava extends Cross[ExampleCrossModuleJava](listIn(millSourcePath / "basicjava"))
object scalabuilds extends Cross[ExampleCrossModule](listIn(millSourcePath / "scalabuilds"))
object scalatesting extends Cross[ExampleCrossModule](listIn(millSourcePath / "scalatesting"))
object javabuilds extends Cross[ExampleCrossModuleJava](listIn(millSourcePath / "javabuilds"))
object javatesting extends Cross[ExampleCrossModuleJava](listIn(millSourcePath / "javatesting"))
object scalamodule extends Cross[ExampleCrossModule](listIn(millSourcePath / "scalamodule"))
object javamodule extends Cross[ExampleCrossModuleJava](listIn(millSourcePath / "javamodule"))
object tasks extends Cross[ExampleCrossModule](listIn(millSourcePath / "tasks"))
object cross extends Cross[ExampleCrossModule](listIn(millSourcePath / "cross"))
object misc extends Cross[ExampleCrossModule](listIn(millSourcePath / "misc"))
object web extends Cross[ExampleCrossModule](listIn(millSourcePath / "web"))
object javaweb extends Cross[ExampleCrossModule](listIn(millSourcePath / "javaweb"))
def exampleModules: Seq[ExampleCrossModule] = millInternal
.modules
.collect { case m: ExampleCrossModule => m }


object javalib extends Module{
object basic extends Cross[ExampleCrossModuleJava](listIn(millSourcePath / "basic"))
object builds extends Cross[ExampleCrossModuleJava](listIn(millSourcePath / "builds"))
object testing extends Cross[ExampleCrossModuleJava](listIn(millSourcePath / "testing"))
object module extends Cross[ExampleCrossModuleJava](listIn(millSourcePath / "module"))
object web extends Cross[ExampleCrossModule](listIn(millSourcePath / "web"))
}
object scalalib extends Module{
object basic extends Cross[ExampleCrossModule](listIn(millSourcePath / "basic"))
object builds extends Cross[ExampleCrossModule](listIn(millSourcePath / "builds"))
object testing extends Cross[ExampleCrossModule](listIn(millSourcePath / "testing"))
object module extends Cross[ExampleCrossModule](listIn(millSourcePath / "module"))
object web extends Cross[ExampleCrossModule](listIn(millSourcePath / "web"))
}

object depth extends Module{
object tasks extends Cross[ExampleCrossModule](listIn(millSourcePath / "tasks"))
object modules extends Cross[ExampleCrossModule](listIn(millSourcePath / "modules"))
object cross extends Cross[ExampleCrossModule](listIn(millSourcePath / "cross"))
}

object extending extends Module{
object imports extends Cross[ExampleCrossModule](listIn(millSourcePath / "imports"))
object metabuild extends Cross[ExampleCrossModule](listIn(millSourcePath / "metabuild"))
object plugins extends Cross[ExampleCrossModule](listIn(millSourcePath / "plugins"))
}

trait ExampleCrossModuleJava extends ExampleCrossModule {

def upstreamCross(s: String) = s match {
case "basicjava" => basic
case "javabuilds" => scalabuilds
case "javamodule" => scalamodule
case "javatesting" => scalatesting
case "basic" => scalalib.basic
case "builds" => scalalib.builds
case "module" => scalalib.module
case "testing" => scalalib.testing
case "web" => scalalib.web
}
def testRepoRoot = T{
os.copy.over(super.testRepoRoot().path, T.dest)
Expand Down Expand Up @@ -1268,6 +1285,7 @@ object example extends Module {
}
}
}

trait ExampleCrossModule extends IntegrationTestCrossModule {
// disable scalafix because these example modules don't have sources causing it to misbehave
def fix(args: String*): Command[Unit] = T.command {}
Expand Down Expand Up @@ -1520,17 +1538,17 @@ object idea extends MillPublishScalaModule {
def moduleDeps = Seq(scalalib, runner)
}

object dist extends MillPublishJavaModule {
def jar = dev.assembly()
def moduleDeps = Seq(runner, idea)
}

object dev extends MillPublishScalaModule {
/**
* Version of [[dist]] meant for local integration testing within the Mill
* repo. Looks mostly the same as [[dist]], except it does not have a reference
* to itself in its [[testTransitiveDeps]], to avoid a circular dependency.
*/
object dist0 extends MillPublishJavaModule {
// disable scalafix here because it crashes when a module has no sources
def fix(args: String*): Command[Unit] = T.command {}
def moduleDeps = Seq(runner, idea)

def testTransitiveDeps = super.testTransitiveDeps() ++ Seq(
def testTransitiveDeps = runner.testTransitiveDeps() ++ Seq(
runner.linenumbers.testDep(),
scalalib.backgroundwrapper.testDep(),
contrib.bloop.testDep(),
Expand All @@ -1540,7 +1558,18 @@ object dev extends MillPublishScalaModule {
contrib.jmh.testDep(),
contrib.playlib.testDep(),
contrib.playlib.worker("2.8").testDep(),
bsp.worker.testDep()
bsp.worker.testDep(),
testkit.testDep(),
)
}


object dist extends MillPublishJavaModule {
def jar = rawAssembly()
def moduleDeps = Seq(runner, idea)

def testTransitiveDeps = dist0.testTransitiveDeps() ++ Seq(
(s"com.lihaoyi-${dist.artifactId()}", dist0.runClasspath().map(_.path).mkString("\n")),
)

def genTask(m: ScalaModule) = T.task { Seq(m.jar(), m.sourceJar()) ++ m.runClasspath() }
Expand Down Expand Up @@ -1586,8 +1615,7 @@ object dev extends MillPublishScalaModule {
case m: PublishModule if (m ne this) && (m ne dist) => m
}

def assembly = T {
T.traverse(allPublishModules)(m => m.publishLocalCached)()
def rawAssembly = T{
val version = millVersion()
val devRunClasspath = runClasspath().map(_.path)
val filename = if (scala.util.Properties.isWin) "mill.bat" else "mill"
Expand All @@ -1608,6 +1636,12 @@ object dev extends MillPublishScalaModule {
)
PathRef(T.dest / filename)
}
def assembly = T {
T.traverse(allPublishModules)(m => m.publishLocalCached)()
val raw = rawAssembly().path
os.copy(raw, T.dest / raw.last)
PathRef(T.dest / raw.last)
}

def prependShellScript = T {
val (millArgs, otherArgs) =
Expand Down Expand Up @@ -1974,12 +2008,12 @@ def installLocalCache() = T.command {
}

def installLocalTask(binFile: Task[String], ivyRepo: String = null): Task[os.Path] = T.task {
val millBin = dev.assembly()
val millBin = dist.assembly()
val targetFile = os.Path(binFile(), T.workspace)
if (os.exists(targetFile))
T.log.info(s"Overwriting existing local Mill binary at ${targetFile}")
os.copy.over(millBin.path, targetFile, createFolders = true)
T.log.info(s"Published ${dev.allPublishModules.size} modules and installed ${targetFile}")
T.log.info(s"Published ${dist.allPublishModules.size} modules and installed ${targetFile}")
targetFile
}

Expand Down Expand Up @@ -2046,7 +2080,7 @@ def uploadToGithub(authKey: String) = T.command {
val examples = exampleZips().map(z => (z.path, z.path.last))

val zips = examples ++ Seq(
(dev.assembly().path, label + "-assembly"),
(dist.assembly().path, label + "-assembly"),
(bootstrapLauncher().path, label)
)

Expand Down
2 changes: 1 addition & 1 deletion ci/test-mill-bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ ci/prepare-mill-bootstrap.sh

# Run tests
target/mill-release -i "__.compile"
target/mill-release -i "example.basic[1-simple].server.test"
target/mill-release -i "example.scalalib.basic[1-simple].server.test"
6 changes: 3 additions & 3 deletions ci/test-mill-dev.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

set -eux

EXAMPLE=example/scalabuilds/9-realistic
EXAMPLE=example/scalalib/builds/9-realistic

rm -rf $EXAMPLE/out

test ! -d $EXAMPLE/out/foo/3.3.3/compile.dest
test ! -f $EXAMPLE/out/bar/2.13.8/assembly.dest/out.jar

./mill -i dev.run $EXAMPLE -i "foo[3.3.3].run"
./mill -i dist.run $EXAMPLE -i "foo[3.3.3].run"

test -d $EXAMPLE/out/foo/3.3.3/compile.dest

./mill -i dev.run $EXAMPLE show "bar[2.13.8].assembly"
./mill -i dist.run $EXAMPLE show "bar[2.13.8].assembly"

test -f $EXAMPLE/out/bar/2.13.8/assembly.dest/out.jar
8 changes: 4 additions & 4 deletions ci/test-mill-release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@
set -eux

# Build Mill
./mill -i dev.assembly
./mill -i dist.assembly

EXAMPLE=example/scalabuilds/9-realistic
EXAMPLE=example/scalalib/builds/9-realistic

rm -rf $EXAMPLE/out

test ! -d $EXAMPLE/out/foo/3.3.3/compile.dest
test ! -f $EXAMPLE/out/bar/2.13.8/assembly.dest/out.jar

(cd $EXAMPLE && ../../../out/dev/assembly.dest/mill -i "foo[3.3.3].run")
(cd $EXAMPLE && ../../../../out/dist/assembly.dest/mill -i "foo[3.3.3].run")

test -d $EXAMPLE/out/foo/3.3.3/compile.dest

(cd $EXAMPLE && ../../../out/dev/assembly.dest/mill show "bar[2.13.8].assembly")
(cd $EXAMPLE && ../../../../out/dist/assembly.dest/mill show "bar[2.13.8].assembly")

test -f $EXAMPLE/out/bar/2.13.8/assembly.dest/out.jar
1 change: 1 addition & 0 deletions docs/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
** xref:contrib/twirllib.adoc[]
** xref:contrib/versionfile.adoc[]
* xref:Thirdparty_Plugins.adoc[]
* xref:Writing_Mill_Plugins.adoc[]
* xref:The_Mill_Meta_Build.adoc[]

// Reference pages that a typical user would not typically read top-to-bottom,
Expand Down
2 changes: 1 addition & 1 deletion docs/modules/ROOT/pages/Contrib_Plugins.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,4 @@ import $ivy.`com.lihaoyi::mill-contrib-bloop:`

== Importing Contrib Modules

include::example/misc/6-contrib-import.adoc[]
include::example/extending/imports/6-contrib-import.adoc[]
Loading
Loading