Skip to content

Commit

Permalink
Refactor Maven Runner build config (#2911)
Browse files Browse the repository at this point in the history
  • Loading branch information
aSemy committed Mar 16, 2023
1 parent 34c0f73 commit 12e2a3c
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 60 deletions.
@@ -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)
}
3 changes: 3 additions & 0 deletions gradle.properties
Expand Up @@ -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
Expand Down
13 changes: 7 additions & 6 deletions 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"))
Expand All @@ -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)
}
}
117 changes: 66 additions & 51 deletions runners/maven-plugin/build.gradle.kts
@@ -1,90 +1,105 @@
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"))
}

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 ->
Expand Down
Expand Up @@ -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>
Expand Down

0 comments on commit 12e2a3c

Please sign in to comment.