Skip to content

Commit 870c43f

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

35 files changed

Lines changed: 1148 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: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
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+
encoding = Charsets.UTF_8.name()
28+
addStringOption("Xdoclint:none", "-quiet")
29+
addStringOption("Xwerror", "-quiet")
30+
addStringOption("source", "17")
31+
val artifactId = project.findProperty("artifactId")?.toString() ?: project.name
32+
val org = project.findProperty("org")?.toString() ?: "diffplug"
33+
val name = project.findProperty("name")?.toString() ?: "spotless"
34+
val version = project.version.toString()
35+
val group = project.group.toString()
36+
val javadocInfo =
37+
"<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>"
38+
header = javadocInfo
39+
40+
val dotdotGradle = if (project.name.startsWith("eclipse-")) "../../gradle" else "../gradle"
41+
linksOffline("https://docs.gradle.org/6.1.1/javadoc/", "$dotdotGradle/javadoc/gradle")
42+
val versionLast = rootProject.the<ChangelogExtension>().versionLast
43+
linksOffline(
44+
"https://javadoc.io/static/com.diffplug.spotless/spotless-lib/$versionLast",
45+
"$dotdotGradle/javadoc/spotless-lib",
46+
)
47+
linksOffline(
48+
"https://javadoc.io/static/com.diffplug.spotless/spotless-lib-extra/$versionLast",
49+
"$dotdotGradle/javadoc/spotless-lib-extra",
50+
)
51+
}
52+
}
53+
}
54+
55+
tasks.check {
56+
dependsOn(tasks.javadoc)
57+
}
58+
59+
afterEvaluate {
60+
val isExt = project.name.startsWith("eclipse-")
61+
val artifactId = project.findProperty("artifactId")?.toString() ?: project.name
62+
val isPluginMaven = artifactId == "spotless-maven-plugin"
63+
val isPluginGradle = pluginManager.hasPlugin("java-gradle-plugin")
64+
65+
publishing {
66+
publications {
67+
val pluginMaven =
68+
findByName("pluginMaven") as? MavenPublication
69+
?: create<MavenPublication>("pluginMaven") {
70+
if (!isPluginGradle) {
71+
from(components["java"])
72+
}
73+
}
74+
75+
pluginMaven.apply {
76+
groupId = project.group.toString()
77+
this.artifactId = artifactId
78+
version = project.version.toString()
79+
80+
pom {
81+
name = artifactId
82+
description = project.description
83+
url = "https://github.com/${project.findProperty("org")}/${rootProject.name}"
84+
scm {
85+
url = "https://github.com/${project.findProperty("org")}/${rootProject.name}"
86+
connection =
87+
"scm:git:https://github.com/${project.findProperty("org")}/${rootProject.name}.git"
88+
developerConnection =
89+
"scm:git:ssh:git@github.com/${project.findProperty("org")}/${rootProject.name}.git"
90+
}
91+
licenses {
92+
license {
93+
if (isExt) {
94+
name = "Eclipse Public License - v 1.0"
95+
url = "https://www.eclipse.org/legal/epl-v10.html"
96+
} else {
97+
name = "The Apache Software License, Version 2.0"
98+
url = "https://www.apache.org/licenses/LICENSE-2.0.txt"
99+
}
100+
distribution = "repo"
101+
}
102+
}
103+
developers {
104+
if (isExt) {
105+
@Suppress("UNCHECKED_CAST")
106+
val devs = project.findProperty("developers") as? Map<String, Map<String, String>>
107+
devs?.forEach { (extId, extValues) ->
108+
developer {
109+
id = extId
110+
name = extValues["name"]
111+
email = extValues["email"]
112+
}
113+
}
114+
} else {
115+
if (isPluginMaven) {
116+
developer {
117+
id = "lutovich"
118+
name = "Konstantin Lutovich"
119+
email = "konstantin.lutovich@neotechnology.com"
120+
}
121+
}
122+
developer {
123+
id = "nedtwigg"
124+
name = "Ned Twigg"
125+
email = "ned.twigg@diffplug.com"
126+
}
127+
}
128+
}
129+
if (isPluginMaven) {
130+
withXml {
131+
val rootNode = asNode()
132+
val prerequisites = rootNode.appendNode("prerequisites")
133+
prerequisites.appendNode("maven", "3.1.0")
134+
}
135+
}
136+
}
137+
}
138+
}
139+
if (System.getenv("JITPACK") == "true" || project.version.toString().endsWith("-SNAPSHOT")) {
140+
signing {
141+
isRequired = false
142+
}
143+
} else {
144+
signing {
145+
val gpgKey = decode64("ORG_GRADLE_PROJECT_gpg_key64")
146+
useInMemoryPgpKeys(
147+
"0x4272C851",
148+
gpgKey,
149+
System.getenv("ORG_GRADLE_PROJECT_gpg_passphrase"),
150+
)
151+
sign(publishing.publications)
152+
}
153+
154+
val changelogProject = if (tasks.names.contains("changelogBump")) project else rootProject
155+
val changelogTasks = changelogProject.tasks
156+
157+
tasks.jar {
158+
dependsOn(changelogTasks.named("changelogCheck"))
159+
}
160+
161+
val thisProj = project
162+
changelogTasks.named("changelogBump") {
163+
dependsOn(
164+
":${thisProj.path.removePrefix(":")}:publishPluginMavenPublicationToSonatypeRepository"
165+
)
166+
dependsOn(":closeAndReleaseSonatypeStagingRepository")
167+
if (thisProj.tasks.names.contains("publishPlugins")) {
168+
dependsOn(thisProj.tasks.named("publishPlugins"))
169+
}
170+
}
171+
}
172+
}
173+
}
174+
175+
tasks.withType<AbstractArchiveTask>().configureEach {
176+
isPreserveFileTimestamps = false
177+
isReproducibleFileOrder = true
178+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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.encoding = Charsets.UTF_8.name()
13+
options.release = libs.versions.jdk.release.map { it.toInt() }
14+
}
15+
16+
spotbugs {
17+
ignoreFailures = false
18+
reportLevel = Confidence.MEDIUM
19+
omitVisitors = listOf("ConstructorThrow", "FindReturnRef")
20+
}
21+
22+
tasks.spotbugsTest {
23+
enabled = false
24+
}
25+
26+
tasks.withType<SpotBugsTask>().configureEach {
27+
outputs.file(project.layout.buildDirectory.file("reports/spotbugs/${name}.html"))
28+
outputs.file(project.layout.buildDirectory.file("spotbugs/auxclasspath/${name}"))
29+
reports.create("html") {
30+
required = true
31+
}
32+
}
33+
34+
dependencies {
35+
compileOnly(libs.jcip.annotations)
36+
compileOnly(spotbugs.toolVersion.map { "com.github.spotbugs:spotbugs-annotations:$it" })
37+
compileOnly(libs.jsr305)
38+
}
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)