Skip to content
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
ab80850
Extended `mill init` to support an existing Maven project
ajaychandran Oct 16, 2024
9cfa813
Renamed variable
ajaychandran Oct 17, 2024
6b1d573
Added magic import to generated build.mill
ajaychandran Oct 17, 2024
0e1dbe6
Added provided dependencies to compileIvyDeps
ajaychandran Oct 17, 2024
6c4ad41
Extended `mill init` to support an existing Maven project
ajaychandran Oct 16, 2024
b60147e
Renamed variable
ajaychandran Oct 17, 2024
db77ae6
Added magic import to generated build.mill
ajaychandran Oct 17, 2024
e28b83f
Added provided dependencies to compileIvyDeps
ajaychandran Oct 17, 2024
6fc9eb2
Merge remote-tracking branch 'origin/main'
ajaychandran Oct 17, 2024
229e95c
Added magic import to resolve base module in package build files
ajaychandran Oct 18, 2024
4b7948c
Fix test
ajaychandran Oct 18, 2024
6e7061e
Refactored out code generation
ajaychandran Oct 18, 2024
76e4bd5
Merge branch 'com-lihaoyi:main' into main
ajaychandran Oct 23, 2024
b784532
Merge branch 'com-lihaoyi:main' into main
ajaychandran Oct 25, 2024
d16915f
Merge branch 'com-lihaoyi:main' into main
ajaychandran Oct 28, 2024
3b5d140
Merge branch 'com-lihaoyi:main' into main
ajaychandran Nov 1, 2024
69273e8
Merge branch 'com-lihaoyi:main' into main
ajaychandran Nov 5, 2024
3658abb
- Addressed review comments
ajaychandran Nov 5, 2024
50f87b9
Renamed exception
ajaychandran Nov 5, 2024
70e4614
Fixed formatting
ajaychandran Nov 5, 2024
84098b7
Renamed symbolic operators
ajaychandran Nov 6, 2024
a71c46f
Added test case for avaje-config
ajaychandran Nov 6, 2024
34ac1e0
Added location of compile errors
ajaychandran Nov 6, 2024
dab05d0
Separated variable declarations
ajaychandran Nov 6, 2024
1d6e756
Changed implicit parameters to arguments.
ajaychandran Nov 6, 2024
acae1a8
Cleaned folder names
ajaychandran Nov 6, 2024
d5778a7
Cleaned object names
ajaychandran Nov 6, 2024
dd41e49
Merge branch 'com-lihaoyi:main' into main
ajaychandran Nov 7, 2024
52a11a0
Replaced arrow assertions with assert
ajaychandran Nov 6, 2024
f092903
Format build files generated in tests
ajaychandran Nov 6, 2024
50fe2ac
Removed support for build-helper-maven-plugin
ajaychandran Nov 6, 2024
86501ff
Aligned inheritance scheme with existing capabilities
ajaychandran Nov 7, 2024
4785683
Merge branch 'com-lihaoyi:main' into main
ajaychandran Nov 11, 2024
7b15c28
Added test class for owner project and cleaned existing tests
ajaychandran Nov 7, 2024
b0d45da
Reordered parameters
ajaychandran Nov 7, 2024
17d8e92
Improved generator algorithm
ajaychandran Nov 9, 2024
0bb1824
Annotated compile tasks
ajaychandran Nov 9, 2024
d641e2a
Replaced System.lineSeparator()
ajaychandran Nov 9, 2024
65ddee1
Renamed method and updated Scaladoc
ajaychandran Nov 9, 2024
5622b78
Simplified build IR
ajaychandran Nov 9, 2024
76b21c6
Added feature flag to compact build tree
ajaychandran Nov 11, 2024
ee93973
Updated comments for JPMS errors
ajaychandran Nov 11, 2024
4df7e8d
Added documentation with example
ajaychandran Nov 11, 2024
e3aa816
Refactored integration tests
ajaychandran Nov 11, 2024
8a229d8
Removed compile tasks for "pom" modules
ajaychandran Nov 11, 2024
ff40e9e
Merge branch 'com-lihaoyi:main' into main
ajaychandran Nov 11, 2024
46cd3b2
Improved integration tests
ajaychandran Nov 11, 2024
c3bcb72
Updated documentation
ajaychandran Nov 11, 2024
2ab9b05
- Fix error due to use of /* in command
ajaychandran Nov 11, 2024
f0b487f
Updated test golden files
ajaychandran Nov 11, 2024
75e704f
Compare lines instead of content to avoid file EOL differences
ajaychandran Nov 12, 2024
7018dde
Merge remote-tracking branch 'upstream/main'
ajaychandran Nov 12, 2024
895ffe2
Removed default parameter value
ajaychandran Nov 12, 2024
a01a8d2
Suppressed test assertion to avoid CI failure
ajaychandran Nov 12, 2024
fe6cc7b
Cleanup
ajaychandran Nov 12, 2024
b0839c8
Escape single backslash to handle Windows paths
ajaychandran Nov 12, 2024
e8683d9
Use raw interpolator for single backslashes
ajaychandran Nov 12, 2024
88cdcf6
debug
lihaoyi Nov 14, 2024
fbffb2a
use pprint literalize
lihaoyi Nov 14, 2024
0c56337
cleanup
lihaoyi Nov 14, 2024
e309e9b
docs
lihaoyi Nov 14, 2024
3449411
docs
lihaoyi Nov 14, 2024
0d2ddc0
fixtests
lihaoyi Nov 14, 2024
639c2a4
docs
lihaoyi Nov 14, 2024
6010bce
docs
lihaoyi Nov 14, 2024
219cef4
docs
lihaoyi Nov 14, 2024
ef66ca9
docs
lihaoyi Nov 14, 2024
9cb7be5
.
lihaoyi Nov 14, 2024
47a71fc
.
lihaoyi Nov 14, 2024
c08d6d0
.
lihaoyi Nov 14, 2024
a0a0d2c
.
lihaoyi Nov 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions build.mill
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,14 @@ object Deps {
val sonatypeCentralClient = ivy"com.lumidion::sonatype-central-client-requests:0.3.0"
val kotlinVersion = "2.0.21"
val kotlinCompiler = ivy"org.jetbrains.kotlin:kotlin-compiler:$kotlinVersion"
val mavenVersion = "3.9.9"
val mavenEmbedder = ivy"org.apache.maven:maven-embedder:$mavenVersion"
val mavenResolverVersion = "1.9.22"
val mavenResolverConnectorBasic = ivy"org.apache.maven.resolver:maven-resolver-connector-basic:$mavenResolverVersion"
val mavenResolverSupplier = ivy"org.apache.maven.resolver:maven-resolver-supplier:$mavenResolverVersion"
val mavenResolverTransportFile = ivy"org.apache.maven.resolver:maven-resolver-transport-file:$mavenResolverVersion"
val mavenResolverTransportHttp = ivy"org.apache.maven.resolver:maven-resolver-transport-http:$mavenResolverVersion"
val mavenResolverTransportWagon = ivy"org.apache.maven.resolver:maven-resolver-transport-wagon:$mavenResolverVersion"

object RuntimeDeps {
val dokkaVersion = "1.9.20"
Expand Down
1 change: 1 addition & 0 deletions dist/package.mill
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ object `package` extends RootModule with build.MillPublishJavaModule {

def testTransitiveDeps = build.runner.testTransitiveDeps() ++ Seq(
build.main.graphviz.testDep(),
build.main.maven.testDep(),
build.runner.linenumbers.testDep(),
build.scalalib.backgroundwrapper.testDep(),
build.contrib.bloop.testDep(),
Expand Down
221 changes: 221 additions & 0 deletions integration/feature/init/src/MillInitMavenTests.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
package mill.integration

import mill.testkit.{IntegrationTester, UtestIntegrationTestSuite}
import utest._

object MillInitMavenTests extends UtestIntegrationTestSuite {

private def prep[T](githubSourceZipUrl: String)(f: IntegrationTester => T): T = {
val zipFile = os.temp(requests.get(githubSourceZipUrl))
val unzipDir = os.unzip(zipFile, os.temp.dir())
val sourceDir = os.list(unzipDir).head

integrationTest { tester =>
for (p <- os.list(sourceDir)) os.move.into(p, tester.workspacePath)
f(tester)
}
}

def tests: Tests = Tests {

// - Junit5
// - maven-compiler-plugin release option
test("jansi") {
prep("https://github.com/fusesource/jansi/archive/refs/tags/jansi-2.4.1.zip") { tester =>
import tester._

val initRes = eval(("init", "--deps-object", "Deps"))
initRes.out.contains(
"generated 1 Mill build file(s)"
) ==> true
initRes.isSuccess ==> true

val compileRes = eval("compile")
compileRes.err.contains(
"compiling 20 Java sources"
) ==> true
compileRes.isSuccess ==> true

val testRes = eval("test")
testRes.out.contains(
"Test run finished: 0 failed, 1 ignored, 90 total"
) ==> true
testRes.isSuccess ==> true

val publishLocalRes = eval("publishLocal")
publishLocalRes.err.contains(
"Publishing Artifact(org.fusesource.jansi,jansi,2.4.1)"
) ==> true
publishLocalRes.isSuccess ==> true
}
}

// - multi-module
// - TestNg
// - maven-compiler-plugin release option
test("dotenv") {
prep("https://github.com/shyiko/dotenv/archive/refs/tags/0.1.1.zip") { tester =>
import tester._

val initRes = eval("init")
initRes.out.contains(
"generated 3 Mill build file(s)"
) ==> true
initRes.isSuccess ==> true

val resolveRes = eval(("resolve", "_"))
Seq(
"dotenv",
"dotenv-guice"
).forall(resolveRes.out.contains) ==> true

// JavaModule.JavaTests is not picking compileIvyDeps from outer module
val compileRes = eval("__.compile")
compileRes.err.contains("package com.google.inject does not exist") ==> true
compileRes.isSuccess ==> false

// even if compile error is fixed, TestNg version is not supported
// val testRes = eval("__.test")
// testRes.isSuccess ==> false
}
}

// - multi-module
// - Junit5
// - submodule e2e directory and artifact name differ
test("fastexcel") {
prep("https://github.com/dhatim/fastexcel/archive/refs/tags/0.18.4.zip") { tester =>
import tester._

val initRes = eval("init")
initRes.out.contains(
"generated 4 Mill build file(s)"
) ==> true
initRes.isSuccess ==> true

val resolveRes = eval(("resolve", "_"))
Seq(
"fastexcel-reader",
"fastexcel-writer",
"e2e"
).forall(resolveRes.out.contains) ==> true

// not sure why this happens but pom.xml has a hack to handle JPMS
val compileRes = eval("__.compile")
Seq(
"module not found: org.apache.commons.compress",
"module not found: com.fasterxml.aalto",
"module not found: opczip"
).forall(compileRes.err.contains) ==> true
compileRes.isSuccess ==> false
}
}

// - multi-module
// - Junit5
// - build-helper-maven-plugin
// - maven-compiler-plugin compilerArgs options
// - submodule directory and artifact names differ
// - multi line description, property <argLine.common>
// - property <jetty.alpnAgent.path> contains quotes
test("netty") {
prep("https://github.com/netty/netty/archive/refs/tags/netty-4.1.114.Final.zip") { tester =>
import tester._

val initRes = eval(("init", "--publish-properties"))
// cannot resolve native dependencies defined by build extension os-maven-plugin
initRes.out.contains(
"""[codec-http2] dropping classifier ${os.detected.classifier} for dependency io.netty:netty-tcnative:2.0.66.Final
|[transport-native-epoll] dropping classifier ${os.detected.classifier} for dependency io.netty:netty-tcnative:2.0.66.Final
|[transport-native-kqueue] dropping classifier ${os.detected.classifier} for dependency io.netty:netty-tcnative:2.0.66.Final
|[handler] dropping classifier ${os.detected.classifier} for dependency io.netty:netty-tcnative:2.0.66.Final
|[example] dropping classifier ${os.detected.classifier} for dependency io.netty:netty-tcnative:2.0.66.Final
|[testsuite] dropping classifier ${os.detected.classifier} for dependency io.netty:netty-tcnative:2.0.66.Final
|[testsuite-shading] dropping classifier ${os.detected.classifier} for dependency io.netty:netty-tcnative:2.0.66.Final
|[transport-blockhound-tests] dropping classifier ${os.detected.classifier} for dependency io.netty:netty-tcnative:2.0.66.Final
|[microbench] dropping classifier ${os.detected.classifier} for dependency io.netty:netty-tcnative:2.0.66.Final
|""".stripMargin
) ==> true
initRes.out.contains(
"generated 47 Mill build file(s)"
) ==> true
initRes.isSuccess ==> true

val resolveRes = eval(("resolve", "_"))
Seq(
"all",
"dev-tools",
"common",
"buffer",
"codec",
"codec-dns",
"codec-haproxy",
"codec-http",
"codec-http2",
"codec-memcache",
"codec-mqtt",
"codec-redis",
"codec-smtp",
"codec-socks",
"codec-stomp",
"codec-xml",
"resolver",
"resolver-dns",
"resolver-dns-classes-macos",
"resolver-dns-native-macos",
"transport",
"transport-native-unix-common-tests",
"transport-native-unix-common",
"transport-classes-epoll",
"transport-native-epoll",
"transport-classes-kqueue",
"transport-native-kqueue",
"transport-rxtx",
"transport-sctp",
"transport-udt",
"handler",
"handler-proxy",
"handler-ssl-ocsp",
"example",
"testsuite",
"testsuite-autobahn",
"testsuite-http2",
"testsuite-osgi",
"testsuite-shading",
"testsuite-native",
"testsuite-native-image",
"testsuite-native-image-client",
"testsuite-native-image-client-runtime-init",
"transport-blockhound-tests",
"microbench",
"bom"
).forall(resolveRes.out.contains) ==> true

// additional sources defined by build-helper-maven-plugin
val sourcesRes = eval(("show", "transport-native-epoll.sources"))
Seq(
s"$workspacePath/transport-native-epoll/src/main/java",
s"$workspacePath/transport-native-epoll/src/main/c"
).forall(sourcesRes.out.contains) ==> true

// compile succeeds for submodule
val compileRes = eval("codec.compile")
compileRes.err.contains(
"compiling 155 Java sources"
) ==> true
compileRes.isSuccess ==> true

// test compile fails for submodule due to missing native dependency
val testRes = eval("codec.test")
testRes.err.contains(
"package io.netty.nativeimage does not exist"
) ==> true
testRes.isSuccess ==> false

// publishLocal fails for submodule (due to several Javadoc errors)
val publishLocalRes = eval("codec.publishLocal")
publishLocalRes.isSuccess ==> false
}
}
}
}
3 changes: 2 additions & 1 deletion main/init/package.mill
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import mill._
import scala.util.matching.Regex

object `package` extends RootModule with build.MillPublishScalaModule {
def moduleDeps = Seq(build.main)

def moduleDeps = Seq(build.main, build.scalalib)

override def resources = Task {
super.resources() ++ Seq(exampleList())
Expand Down
95 changes: 95 additions & 0 deletions main/init/src/mill/init/InitMavenModule.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package mill.init

import coursier.LocalRepositories
import coursier.maven.MavenRepository
import mill.api.{Loose, PathRef}
import mill.define.{Discover, ExternalModule, TaskModule}
import mill.scalalib.scalafmt.ScalafmtWorkerModule
import mill.util.{Jvm, Util}
import mill.{Command, T, Task}

import scala.util.control.NoStackTrace

@mill.api.experimental
object InitMavenModule extends ExternalModule with InitMavenModule with TaskModule {

lazy val millDiscover: Discover = Discover[this.type]
}

/**
* Defines a [[InitModule.init task]] to convert a Maven build to Mill.
*/
@mill.api.experimental
trait InitMavenModule extends TaskModule {

def defaultCommandName(): String = "init"

/**
* Classpath containing [[buildGenMainClass build file generator]].
*/
def buildGenClasspath: T[Loose.Agg[PathRef]] = T {
val repositories = Seq(
LocalRepositories.ivy2Local,
MavenRepository("https://repo1.maven.org/maven2"),
MavenRepository("https://oss.sonatype.org/content/repositories/releases")
)
Util.millProjectModule("mill-main-maven", repositories)
}

/**
* Mill build file generator application entrypoint.
*/
def buildGenMainClass: T[String] = "mill.main.maven.BuildGen"

/**
* Scalafmt configuration file for formatting generated Mill build files.
*/
def initScalafmtConfig: T[PathRef] = T {
val config = millSourcePath / ".scalafmt.conf"
if (!os.exists(config)) {
T.log.info(s"creating Scalafmt configuration file $config ...")
os.write(
config,
s"""version = "3.8.4-RC1"
|runner.dialect = scala213
|""".stripMargin
)
}
PathRef(config)
}

/**
* Generates and formats Mill build files for an existing Maven project.
*
* @param args arguments for the [[buildGenMainClass build file generator]]
*/
def init(args: String*): Command[Unit] = Task.Command {
val root = millSourcePath

val mainClass = buildGenMainClass()
val classPath = buildGenClasspath().map(_.path)
val exit = Jvm.callSubprocess(
mainClass = mainClass,
classPath = classPath,
mainArgs = args,
workingDir = root
).exitCode

if (exit == 0) {
val files = os.walk.stream(root, skip = (root / "out").equals)
.filter(_.ext == "mill")
.map(PathRef(_))
.toSeq
val config = initScalafmtConfig()
T.log.info("formatting Mill build files ...")
ScalafmtWorkerModule.worker().reformat(files, config)

T.log.info("init completed, run \"mill resolve _\" to list available tasks")
} else {
throw InitMavenException(s"$mainClass exit($exit)")
}
}
}

@mill.api.experimental
case class InitMavenException(message: String) extends Exception(message) with NoStackTrace
Loading
Loading