aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build-logic/src/main/kotlin/org/jetbrains/conventions/maven-cli-setup.gradle.kts103
-rw-r--r--gradle.properties3
-rw-r--r--integration-tests/maven/build.gradle.kts13
-rw-r--r--runners/maven-plugin/build.gradle.kts117
-rw-r--r--runners/maven-plugin/pom.template.xml (renamed from runners/maven-plugin/pom.tpl.xml)6
5 files changed, 182 insertions, 60 deletions
diff --git a/build-logic/src/main/kotlin/org/jetbrains/conventions/maven-cli-setup.gradle.kts b/build-logic/src/main/kotlin/org/jetbrains/conventions/maven-cli-setup.gradle.kts
new file mode 100644
index 00000000..ec59da7b
--- /dev/null
+++ b/build-logic/src/main/kotlin/org/jetbrains/conventions/maven-cli-setup.gradle.kts
@@ -0,0 +1,103 @@
+package org.jetbrains.conventions
+
+import org.gradle.kotlin.dsl.support.serviceOf
+
+/**
+ * Utility for downloading and installing a Maven binary.
+ *
+ * Provides the `setupMavenProperties` extension that contains the default versions and locations
+ * of the Maven binary.
+ *
+ * The task [installMavenBinary] will download and unzip the Maven bianry.
+ */
+
+plugins {
+ base
+}
+
+abstract class SetupMavenProperties {
+ abstract val mavenVersion: Property<String>
+ abstract val mavenPluginToolsVersion: Property<String>
+ abstract val mavenBuildDir: DirectoryProperty
+
+ /** Directory that will contain the unpacked Apache Maven dependency */
+ abstract val mavenInstallDir: DirectoryProperty
+
+ /**
+ * Path to the Maven executable.
+ *
+ * This should be different per OS:
+ *
+ * * Windows: `$mavenInstallDir/bin/mvn.cmd`
+ * * Unix: `$mavenInstallDir/bin/mvn`
+ */
+ abstract val mvn: RegularFileProperty
+}
+
+val setupMavenProperties =
+ extensions.create("setupMavenProperties", SetupMavenProperties::class).apply {
+ mavenVersion.convention(providers.gradleProperty("mavenVersion"))
+ mavenPluginToolsVersion.convention(providers.gradleProperty("mavenPluginToolsVersion"))
+
+ mavenBuildDir.convention(layout.buildDirectory.dir("maven"))
+ mavenInstallDir.convention(layout.buildDirectory.dir("apache-maven"))
+
+ val isWindowsProvider =
+ providers.systemProperty("os.name").map { "win" in it.toLowerCase() }
+
+ mvn.convention(
+ providers.zip(mavenInstallDir, isWindowsProvider) { mavenInstallDir, isWindows ->
+ mavenInstallDir.file(
+ when {
+ isWindows -> "bin/mvn.cmd"
+ else -> "bin/mvn"
+ }
+ )
+ }
+ )
+ }
+
+val mavenBinary by configurations.registering {
+ description = "used to download the Maven binary"
+ isCanBeResolved = true
+ isCanBeConsumed = false
+ isVisible = false
+
+ defaultDependencies {
+ addLater(setupMavenProperties.mavenVersion.map { mavenVersion ->
+ project.dependencies.create(
+ group = "org.apache.maven",
+ name = "apache-maven",
+ version = mavenVersion,
+ classifier = "bin",
+ ext = "zip"
+ )
+ })
+ }
+}
+
+tasks.clean {
+ delete(setupMavenProperties.mavenBuildDir)
+ delete(setupMavenProperties.mavenInstallDir)
+}
+
+val installMavenBinary by tasks.registering(Sync::class) {
+ val archives = serviceOf<ArchiveOperations>()
+ from(
+ mavenBinary.flatMap { conf ->
+ @Suppress("UnstableApiUsage")
+ val resolvedArtifacts = conf.incoming.artifacts.resolvedArtifacts
+
+ resolvedArtifacts.map { artifacts ->
+ artifacts.map { archives.zipTree(it.file) }
+ }
+ }
+ ) {
+ eachFile {
+ // drop the first directory inside the zipped Maven bin (apache-maven-$version)
+ relativePath = RelativePath(true, *relativePath.segments.drop(1).toTypedArray())
+ }
+ includeEmptyDirs = false
+ }
+ into(setupMavenProperties.mavenInstallDir)
+}
diff --git a/gradle.properties b/gradle.properties
index a8eb1eff..d68155d7 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -14,6 +14,9 @@ jackson_version=2.12.7
# fixes CVE-2022-42003
jackson_databind_version=2.12.7.1
freemarker_version=2.3.31
+# Dokka Maven Plugin versions
+mavenVersion=3.5.0
+mavenPluginToolsVersion=3.5.2
# Code style
kotlin.code.style=official
# Gradle settings
diff --git a/integration-tests/maven/build.gradle.kts b/integration-tests/maven/build.gradle.kts
index 4b8b6011..a2e7c440 100644
--- a/integration-tests/maven/build.gradle.kts
+++ b/integration-tests/maven/build.gradle.kts
@@ -1,12 +1,10 @@
-import org.jetbrains.SetupMaven
import org.jetbrains.dependsOnMavenLocalPublication
plugins {
id("org.jetbrains.conventions.dokka-integration-test")
+ id("org.jetbrains.conventions.maven-cli-setup")
}
-evaluationDependsOn(":runners:maven-plugin")
-
dependencies {
implementation(project(":integration-tests"))
implementation(kotlin("stdlib"))
@@ -16,10 +14,13 @@ dependencies {
tasks.integrationTest {
dependsOnMavenLocalPublication()
- val setupMavenTask = project(":runners:maven-plugin").tasks.withType<SetupMaven>().single()
- dependsOn(setupMavenTask)
+ dependsOn(tasks.installMavenBinary)
+ val mvn = setupMavenProperties.mvn
+ inputs.file(mvn)
val dokka_version: String by project
environment("DOKKA_VERSION", dokka_version)
- environment("MVN_BINARY_PATH", setupMavenTask.mvn.absolutePath)
+ doFirst("workaround for https://github.com/gradle/gradle/issues/24267") {
+ environment("MVN_BINARY_PATH", mvn.get().asFile.invariantSeparatorsPath)
+ }
}
diff --git a/runners/maven-plugin/build.gradle.kts b/runners/maven-plugin/build.gradle.kts
index f8badf8e..90f2ffef 100644
--- a/runners/maven-plugin/build.gradle.kts
+++ b/runners/maven-plugin/build.gradle.kts
@@ -1,82 +1,97 @@
-import org.jetbrains.CrossPlatformExec
-import org.jetbrains.SetupMaven
+import org.gradle.kotlin.dsl.support.appendReproducibleNewLine
import org.jetbrains.registerDokkaArtifactPublication
plugins {
id("org.jetbrains.conventions.kotlin-jvm")
id("org.jetbrains.conventions.maven-publish")
+ id("org.jetbrains.conventions.maven-cli-setup")
}
-val setupMaven by tasks.register<SetupMaven>("setupMaven")
-
dependencies {
implementation(project(":core"))
- implementation("org.apache.maven:maven-core:${setupMaven.mavenVersion}")
- implementation("org.apache.maven:maven-plugin-api:${setupMaven.mavenVersion}")
- implementation("org.apache.maven.plugin-tools:maven-plugin-annotations:${setupMaven.mavenPluginToolsVersion}")
+ implementation("org.apache.maven:maven-core:${setupMavenProperties.mavenVersion.get()}")
+ implementation("org.apache.maven:maven-plugin-api:${setupMavenProperties.mavenVersion.get()}")
+ implementation("org.apache.maven.plugin-tools:maven-plugin-annotations:${setupMavenProperties.mavenPluginToolsVersion.get()}")
implementation("org.apache.maven:maven-archiver:2.5")
implementation(kotlin("stdlib-jdk8"))
}
-val mavenBuildDir = setupMaven.mavenBuildDir
-val mavenBinDir = setupMaven.mavenBinDir
-
-tasks.clean {
- delete(mavenBuildDir)
- delete(mavenBinDir)
-}
+val mavenPluginTaskGroup = "maven plugin"
-val generatePom by tasks.registering(Copy::class) {
+val generatePom by tasks.registering(Sync::class) {
description = "Generate pom.xml for Maven Plugin Plugin"
+ group = mavenPluginTaskGroup
val dokka_version: String by project
inputs.property("dokka_version", dokka_version)
- from("$projectDir/pom.tpl.xml") {
- rename("(.*).tpl.xml", "$1.xml")
- }
- into(setupMaven.mavenBuildDir)
-
- eachFile {
- filter { line ->
- line.replace("<maven.version></maven.version>", "<maven.version>${setupMaven.mavenVersion}</maven.version>")
- }
- filter { line ->
- line.replace("<version>dokka_version</version>", "<version>$dokka_version</version>")
- }
- filter { line ->
- line.replace(
- "<version>maven-plugin-plugin</version>",
- "<version>${setupMaven.mavenPluginToolsVersion}</version>"
- )
- }
+ val pomTemplateFile = layout.projectDirectory.file("pom.template.xml")
+
+ val mavenVersion = setupMavenProperties.mavenVersion.get()
+ val mavenPluginToolsVersion = setupMavenProperties.mavenPluginToolsVersion.get()
+
+ from(pomTemplateFile) {
+ rename { it.replace(".template.xml", ".xml") }
+
+ expand(
+ "mavenVersion" to mavenVersion,
+ "dokka_version" to dokka_version,
+ "mavenPluginToolsVersion" to mavenPluginToolsVersion,
+ )
}
+
+ into(temporaryDir)
}
-val syncClasses by tasks.registering(Sync::class) {
- description = "Copy compiled classes to the Maven build dir, for Maven Plugin task execution"
+val prepareMavenPluginBuildDir by tasks.registering(Sync::class) {
+ description = "Prepares all files for Maven Plugin task execution"
+ group = mavenPluginTaskGroup
+
+ from(tasks.compileKotlin.flatMap { it.destinationDirectory }) { into("classes/java/main") }
+ from(tasks.compileJava.flatMap { it.destinationDirectory }) { into("classes/java/main") }
- dependsOn(tasks.compileKotlin, tasks.compileJava)
- from("$buildDir/classes/kotlin", "$buildDir/classes/java")
- into("${setupMaven.mavenBuildDir}/classes/java")
+ from(generatePom)
- preserve {
- include("**/*.class")
+ into(setupMavenProperties.mavenBuildDir)
+}
+
+val helpMojo by tasks.registering(Exec::class) {
+ group = mavenPluginTaskGroup
+
+ dependsOn(tasks.installMavenBinary, prepareMavenPluginBuildDir)
+
+ workingDir(setupMavenProperties.mavenBuildDir)
+ executable(setupMavenProperties.mvn.get())
+ args("-e", "-B", "org.apache.maven.plugins:maven-plugin-plugin:helpmojo")
+
+ outputs.dir(setupMavenProperties.mavenBuildDir)
+
+ doLast("normalize maven-plugin-help.properties") {
+ // The maven-plugin-help.properties file contains a timestamp by default.
+ // It should be removed as it is not reproducible and impacts Gradle caching
+ val pluginHelpProperties = workingDir.resolve("maven-plugin-help.properties")
+ pluginHelpProperties.writeText(
+ buildString {
+ val lines = pluginHelpProperties.readText().lines().iterator()
+ // the first line is a descriptive comment
+ appendReproducibleNewLine(lines.next())
+ // the second line is the timestamp, which should be ignored
+ lines.next()
+ // the remaining lines are properties
+ lines.forEach { appendReproducibleNewLine(it) }
+ }
+ )
}
}
-val helpMojo by tasks.registering(CrossPlatformExec::class) {
- dependsOn(setupMaven, generatePom, syncClasses)
- workingDir(setupMaven.mavenBuildDir)
- commandLine(setupMaven.mvn, "-e", "-B", "org.apache.maven.plugins:maven-plugin-plugin:helpmojo")
+val pluginDescriptor by tasks.registering(Exec::class) {
+ group = mavenPluginTaskGroup
- outputs.dir(layout.buildDirectory.dir("maven"))
-}
+ dependsOn(tasks.installMavenBinary, prepareMavenPluginBuildDir)
-val pluginDescriptor by tasks.registering(CrossPlatformExec::class) {
- dependsOn(setupMaven, generatePom, syncClasses)
- workingDir(setupMaven.mavenBuildDir)
- commandLine(setupMaven.mvn, "-e", "-B", "org.apache.maven.plugins:maven-plugin-plugin:descriptor")
+ workingDir(setupMavenProperties.mavenBuildDir)
+ executable(setupMavenProperties.mvn.get())
+ args("-e", "-B", "org.apache.maven.plugins:maven-plugin-plugin:descriptor")
outputs.dir(layout.buildDirectory.dir("maven/classes/java/main/META-INF/maven"))
}
@@ -84,7 +99,7 @@ val pluginDescriptor by tasks.registering(CrossPlatformExec::class) {
tasks.jar {
dependsOn(pluginDescriptor, helpMojo)
metaInf {
- from("${setupMaven.mavenBuildDir}/classes/java/main/META-INF")
+ from(setupMavenProperties.mavenBuildDir.map { it.dir("classes/java/main/META-INF") })
}
manifest {
attributes("Class-Path" to configurations.runtimeClasspath.map { configuration ->
diff --git a/runners/maven-plugin/pom.tpl.xml b/runners/maven-plugin/pom.template.xml
index c5883c6a..97db90ee 100644
--- a/runners/maven-plugin/pom.tpl.xml
+++ b/runners/maven-plugin/pom.template.xml
@@ -4,17 +4,17 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.jetbrains.dokka</groupId>
<artifactId>dokka-maven-plugin</artifactId>
- <version>dokka_version</version>
+ <version>${dokka_version}</version>
<packaging>maven-plugin</packaging>
<properties>
- <maven.version></maven.version>
+ <maven.version>${mavenVersion}</maven.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
- <version>maven-plugin-plugin</version>
+ <version>${mavenPluginToolsVersion}</version>
<configuration>
<helpPackageName>org.jetbrains.dokka.maven</helpPackageName>
</configuration>