Skip to content

Commit 30c19dd

Browse files
committed
Migrate Gradle build scripts to Kotlin DSL with build-logic convention plugins
1 parent dc2a4cb commit 30c19dd

35 files changed

Lines changed: 1145 additions & 1096 deletions

build-logic/build.gradle.kts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
plugins {
2+
`kotlin-dsl`
3+
}
4+
5+
val versionCatalog = versionCatalogs.named("libs")
6+
7+
fun plugin(alias: String): String {
8+
val p = versionCatalog.findPlugin(alias).get().get()
9+
return "${p.pluginId}:${p.pluginId}.gradle.plugin:${p.version}"
10+
}
11+
12+
dependencies {
13+
implementation(plugin("spotless"))
14+
implementation(plugin("spotless-changelog"))
15+
implementation("com.diffplug.spotless-changelog:spotless-changelog-lib:3.1.2")
16+
implementation(plugin("spotbugs"))
17+
implementation(plugin("errorprone"))
18+
implementation(plugin("rewrite"))
19+
implementation(plugin("test-logger"))
20+
implementation(plugin("nexus-publish"))
21+
implementation(plugin("develocity"))
22+
23+
// TODO: https://github.com/gradle/gradle/issues/15383
24+
implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
25+
}

build-logic/settings.gradle.kts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
dependencyResolutionManagement {
2+
repositories {
3+
mavenCentral()
4+
gradlePluginPortal()
5+
}
6+
versionCatalogs {
7+
create("libs") {
8+
from(files("../gradle/libs.versions.toml"))
9+
}
10+
}
11+
}
12+
13+
rootProject.name = "build-logic"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import org.gradle.accessors.dm.LibrariesForLibs
2+
import org.gradle.api.Project
3+
import org.gradle.kotlin.dsl.findByType
4+
import org.gradle.kotlin.dsl.getByType
5+
6+
val Project.libs: LibrariesForLibs
7+
get() = extensions.findByType() ?: rootProject.extensions.getByType()
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
plugins {
2+
id("com.diffplug.spotless-changelog")
3+
}
4+
5+
val (kind, releaseTitle) =
6+
when (project.name) {
7+
"plugin-gradle" -> "gradle" to "Gradle Plugin"
8+
"plugin-maven" -> "maven" to "Maven Plugin"
9+
else -> {
10+
check(project == rootProject)
11+
"lib" to "Lib"
12+
}
13+
}
14+
15+
spotlessChangelog {
16+
changelogFile("CHANGES.md")
17+
setAppendDashSnapshotUnless_dashPrelease(true)
18+
branch("release")
19+
tagPrefix("$kind/")
20+
commitMessage("Published $kind/{{version}}")
21+
tagMessage("{{changes}}")
22+
runAfterPush(
23+
"gh release create $kind/{{version}} --title '$releaseTitle v{{version}}' --notes-from-tag"
24+
)
25+
}
26+
27+
if (project == rootProject) {
28+
gradle.taskGraph.whenReady {
29+
val changelogPushTasks = allTasks.filter { it.name == "changelogPush" }.map { it.path }
30+
if (changelogPushTasks.size > 1) {
31+
throw IllegalArgumentException(
32+
"Run changelogPush one at a time:\n" + changelogPushTasks.joinToString("\n")
33+
)
34+
}
35+
if (changelogPushTasks.size == 1) {
36+
val isPlugin =
37+
changelogPushTasks[0] == ":plugin-gradle:changelogPush" ||
38+
changelogPushTasks[0] == ":plugin-maven:changelogPush"
39+
if (
40+
isPlugin &&
41+
!rootProject.spotlessChangelog.parsedChangelog.noUnreleasedChanges() &&
42+
rootProject.findProperty("ignoreUnreleasedLib")?.toString() != "true"
43+
) {
44+
throw IllegalArgumentException(
45+
"You're going to publish ${changelogPushTasks[0]}, but there are unreleased features in lib!\n" +
46+
"You should run :changelogPush first! Else you'll be missing out on:\n" +
47+
"${rootProject.spotlessChangelog.parsedChangelog.unreleasedChanges()}\n" +
48+
"If it's okay to miss those and link against the old ${rootProject.spotlessChangelog.versionLast} then " +
49+
"add -PignoreUnreleasedLib=true"
50+
)
51+
}
52+
}
53+
}
54+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import net.ltgt.gradle.errorprone.errorprone
2+
3+
plugins {
4+
id("net.ltgt.errorprone")
5+
}
6+
7+
tasks.withType<JavaCompile>().configureEach {
8+
options.errorprone {
9+
if (System.getenv("error-prone")?.toBoolean() == true) {
10+
enable()
11+
} else {
12+
disable()
13+
}
14+
disableAllWarnings = true
15+
disable(
16+
"AnnotateFormatMethod",
17+
"FunctionalInterfaceMethodChanged",
18+
"ImmutableEnumChecker",
19+
"InlineMeSuggester",
20+
"JavaxInjectOnAbstractMethod",
21+
"OverridesJavaxInjectableMethod",
22+
"ReturnValueIgnored",
23+
)
24+
error(
25+
"ReturnValueIgnored",
26+
"SelfAssignment",
27+
"StringJoin",
28+
"UnnecessarilyFullyQualified",
29+
"UnnecessaryLambda",
30+
)
31+
excludedPaths = ".*/GradleIntegrationHarness.java"
32+
}
33+
}
34+
35+
dependencies {
36+
errorprone(libs.errorprone.core)
37+
}
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
import com.diffplug.spotless.changelog.gradle.ChangelogExtension
2+
import java.util.Base64
3+
4+
plugins {
5+
`java-library`
6+
`maven-publish`
7+
signing
8+
}
9+
10+
fun decode64(varName: String): String {
11+
val envValue = System.getenv(varName) ?: return ""
12+
return String(Base64.getDecoder().decode(envValue), Charsets.UTF_8)
13+
}
14+
15+
java {
16+
withJavadocJar()
17+
withSourcesJar()
18+
}
19+
20+
tasks.named("sourcesJar") {
21+
dependsOn(tasks.jar)
22+
}
23+
24+
tasks.withType<Javadoc>().configureEach {
25+
options {
26+
(this as? StandardJavadocDocletOptions)?.apply {
27+
addStringOption("Xdoclint:none", "-quiet")
28+
addStringOption("Xwerror", "-quiet")
29+
addStringOption("source", "17")
30+
val artifactId = project.findProperty("artifactId")?.toString() ?: project.name
31+
val org = project.findProperty("org")?.toString() ?: "diffplug"
32+
val name = project.findProperty("name")?.toString() ?: "spotless"
33+
val version = project.version.toString()
34+
val group = project.group.toString()
35+
val javadocInfo =
36+
"<h2><a href=\"https://github.com/$org/$name\" style=\"text-transform: none;\">$group:$artifactId:$version</a> by <a href=\"https://www.diffplug.com\" style=\"text-transform: none;\">DiffPlug</a></h2>"
37+
header = javadocInfo
38+
39+
val dotdotGradle = if (project.name.startsWith("eclipse-")) "../../gradle" else "../gradle"
40+
linksOffline("https://docs.gradle.org/6.1.1/javadoc/", "$dotdotGradle/javadoc/gradle")
41+
val versionLast = rootProject.the<ChangelogExtension>().versionLast
42+
linksOffline(
43+
"https://javadoc.io/static/com.diffplug.spotless/spotless-lib/$versionLast",
44+
"$dotdotGradle/javadoc/spotless-lib",
45+
)
46+
linksOffline(
47+
"https://javadoc.io/static/com.diffplug.spotless/spotless-lib-extra/$versionLast",
48+
"$dotdotGradle/javadoc/spotless-lib-extra",
49+
)
50+
}
51+
}
52+
}
53+
54+
tasks.check {
55+
dependsOn(tasks.javadoc)
56+
}
57+
58+
afterEvaluate {
59+
val isExt = project.name.startsWith("eclipse-")
60+
val artifactId = project.findProperty("artifactId")?.toString() ?: project.name
61+
val isPluginMaven = artifactId == "spotless-maven-plugin"
62+
val isPluginGradle = pluginManager.hasPlugin("java-gradle-plugin")
63+
64+
publishing {
65+
publications {
66+
val pluginMaven =
67+
findByName("pluginMaven") as? MavenPublication
68+
?: create<MavenPublication>("pluginMaven") {
69+
if (!isPluginGradle) {
70+
from(components["java"])
71+
}
72+
}
73+
74+
pluginMaven.apply {
75+
groupId = project.group.toString()
76+
this.artifactId = artifactId
77+
version = project.version.toString()
78+
79+
pom {
80+
name = artifactId
81+
description = project.description
82+
url = "https://github.com/${project.findProperty("org")}/${rootProject.name}"
83+
scm {
84+
url = "https://github.com/${project.findProperty("org")}/${rootProject.name}"
85+
connection =
86+
"scm:git:https://github.com/${project.findProperty("org")}/${rootProject.name}.git"
87+
developerConnection =
88+
"scm:git:ssh:git@github.com/${project.findProperty("org")}/${rootProject.name}.git"
89+
}
90+
licenses {
91+
license {
92+
if (isExt) {
93+
name = "Eclipse Public License - v 1.0"
94+
url = "https://www.eclipse.org/legal/epl-v10.html"
95+
} else {
96+
name = "The Apache Software License, Version 2.0"
97+
url = "https://www.apache.org/licenses/LICENSE-2.0.txt"
98+
}
99+
distribution = "repo"
100+
}
101+
}
102+
developers {
103+
if (isExt) {
104+
@Suppress("UNCHECKED_CAST")
105+
val devs = project.findProperty("developers") as? Map<String, Map<String, String>>
106+
devs?.forEach { (extId, extValues) ->
107+
developer {
108+
id = extId
109+
name = extValues["name"]
110+
email = extValues["email"]
111+
}
112+
}
113+
} else {
114+
if (isPluginMaven) {
115+
developer {
116+
id = "lutovich"
117+
name = "Konstantin Lutovich"
118+
email = "konstantin.lutovich@neotechnology.com"
119+
}
120+
}
121+
developer {
122+
id = "nedtwigg"
123+
name = "Ned Twigg"
124+
email = "ned.twigg@diffplug.com"
125+
}
126+
}
127+
}
128+
if (isPluginMaven) {
129+
withXml {
130+
val rootNode = asNode()
131+
val prerequisites = rootNode.appendNode("prerequisites")
132+
prerequisites.appendNode("maven", "3.1.0")
133+
}
134+
}
135+
}
136+
}
137+
}
138+
if (System.getenv("JITPACK") == "true" || project.version.toString().endsWith("-SNAPSHOT")) {
139+
signing {
140+
isRequired = false
141+
}
142+
} else {
143+
signing {
144+
val gpgKey = decode64("ORG_GRADLE_PROJECT_gpg_key64")
145+
useInMemoryPgpKeys(
146+
"0x4272C851",
147+
gpgKey,
148+
System.getenv("ORG_GRADLE_PROJECT_gpg_passphrase"),
149+
)
150+
sign(publishing.publications)
151+
}
152+
153+
val changelogProject = if (tasks.names.contains("changelogBump")) project else rootProject
154+
val changelogTasks = changelogProject.tasks
155+
156+
tasks.jar {
157+
dependsOn(changelogTasks.named("changelogCheck"))
158+
}
159+
160+
val thisProj = project
161+
changelogTasks.named("changelogBump") {
162+
dependsOn(
163+
":${thisProj.path.removePrefix(":")}:publishPluginMavenPublicationToSonatypeRepository"
164+
)
165+
dependsOn(":closeAndReleaseSonatypeStagingRepository")
166+
if (thisProj.tasks.names.contains("publishPlugins")) {
167+
dependsOn(thisProj.tasks.named("publishPlugins"))
168+
}
169+
}
170+
}
171+
}
172+
}
173+
174+
tasks.withType<AbstractArchiveTask>().configureEach {
175+
isPreserveFileTimestamps = false
176+
isReproducibleFileOrder = true
177+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import com.github.spotbugs.snom.Confidence
2+
import com.github.spotbugs.snom.SpotBugsTask
3+
4+
plugins {
5+
id("java")
6+
id("com.github.spotbugs")
7+
id("spotless.error-prone")
8+
id("spotless.spotless-conventions")
9+
}
10+
11+
tasks.withType<JavaCompile>().configureEach {
12+
options.release = libs.versions.jdk.release.map { it.toInt() }
13+
}
14+
15+
spotbugs {
16+
ignoreFailures = false
17+
reportLevel = Confidence.MEDIUM
18+
omitVisitors = listOf("ConstructorThrow", "FindReturnRef")
19+
}
20+
21+
tasks.spotbugsTest {
22+
enabled = false
23+
}
24+
25+
tasks.withType<SpotBugsTask>().configureEach {
26+
outputs.file(project.layout.buildDirectory.file("reports/spotbugs/${name}.html"))
27+
outputs.file(project.layout.buildDirectory.file("spotbugs/auxclasspath/${name}"))
28+
reports.create("html") {
29+
required = true
30+
}
31+
}
32+
33+
dependencies {
34+
compileOnly(libs.jcip.annotations)
35+
compileOnly(spotbugs.toolVersion.map { "com.github.spotbugs:spotbugs-annotations:$it" })
36+
compileOnly(libs.jsr305)
37+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import java.util.Base64
2+
3+
plugins {
4+
id("io.github.gradle-nexus.publish-plugin")
5+
}
6+
7+
fun decode64(varName: String): String {
8+
val envValue = System.getenv(varName) ?: return ""
9+
return String(Base64.getDecoder().decode(envValue), Charsets.UTF_8)
10+
}
11+
12+
group = "com.diffplug.spotless"
13+
14+
nexusPublishing {
15+
repositories {
16+
sonatype {
17+
nexusUrl = uri("https://ossrh-staging-api.central.sonatype.com/service/local/")
18+
snapshotRepositoryUrl = uri("https://central.sonatype.com/repository/maven-snapshots/")
19+
username = System.getenv("ORG_GRADLE_PROJECT_nexus_user")
20+
password = decode64("ORG_GRADLE_PROJECT_nexus_pass64")
21+
}
22+
}
23+
}
24+
25+
val initTask = tasks.named("initializeSonatypeStagingRepository")
26+
27+
allprojects {
28+
initTask.configure {
29+
shouldRunAfter(tasks.withType<Sign>())
30+
}
31+
}

0 commit comments

Comments
 (0)