diff --git a/build-logic/src/main/kotlin/GitInfo.kt b/build-logic/src/main/kotlin/GitInfo.kt index bc00c15d0a3..044fc816555 100644 --- a/build-logic/src/main/kotlin/GitInfo.kt +++ b/build-logic/src/main/kotlin/GitInfo.kt @@ -17,8 +17,13 @@ * under the License. */ +import java.io.ByteArrayOutputStream +import javax.inject.Inject import org.gradle.api.Project -import org.gradle.kotlin.dsl.extra +import org.gradle.api.provider.Property +import org.gradle.api.services.BuildService +import org.gradle.api.services.BuildServiceParameters +import org.gradle.process.ExecOperations /** * Container to memoize Git information retrieved via `git` command executions across all Gradle @@ -30,41 +35,52 @@ class GitInfo(val gitHead: String, val gitDescribe: String, private val rawLinkR "https://raw.githubusercontent.com/apache/polaris/$rawLinkRef/$file" companion object { - private fun execGit(rootProject: Project, vararg args: Any): String { - val out = - rootProject.providers - .exec { - executable = "git" - args(args.toList()) - } - .standardOutput - .asText - .get() - return out.trim() - } - fun memoized(project: Project): GitInfo { val rootProject = project.rootProject - return if (rootProject.extra.has("gitInfo")) { - @Suppress("UNCHECKED_CAST") - rootProject.extra["gitInfo"] as GitInfo + val isRelease = + rootProject.hasProperty("release") || rootProject.hasProperty("jarWithGitInfo") + val service = + project.gradle.sharedServices.registerIfAbsent( + "gitInfo-$isRelease", + GitInfoService::class.java, + ) { + parameters.isRelease.set(isRelease) + } + return service.get().gitInfo + } + } +} + +abstract class GitInfoService : BuildService { + interface Parameters : BuildServiceParameters { + val isRelease: Property + } + + @get:Inject abstract val execOperations: ExecOperations + + val gitInfo: GitInfo by lazy { + val isRelease = parameters.isRelease.get() + val gitHead = execGit("rev-parse", "HEAD") + val gitDescribe = + if (isRelease) { + try { + execGit("describe", "--tags") + } catch (_: Exception) { + execGit("describe", "--always", "--dirty") + } } else { - val isRelease = - rootProject.hasProperty("release") || rootProject.hasProperty("jarWithGitInfo") - val gitHead = execGit(rootProject, "rev-parse", "HEAD") - val gitDescribe = - if (isRelease) - try { - execGit(rootProject, "describe", "--tags") - } catch (_: Exception) { - execGit(rootProject, "describe", "--always", "--dirty") - } - else "" - val rawLinkRef = if (isRelease) gitDescribe else "HEAD" - val gitInfo = GitInfo(gitHead, gitDescribe, rawLinkRef) - rootProject.extra["gitInfo"] = gitInfo - return gitInfo + "" } + val rawLinkRef = if (isRelease) gitDescribe else "HEAD" + GitInfo(gitHead, gitDescribe, rawLinkRef) + } + + private fun execGit(vararg args: String): String { + val out = ByteArrayOutputStream() + execOperations.exec { + commandLine(listOf("git") + args) + standardOutput = out } + return out.toString().trim() } } diff --git a/build-logic/src/main/kotlin/asf/AsfProject.kt b/build-logic/src/main/kotlin/asf/AsfProject.kt index c997751ed00..70f1e5a9640 100644 --- a/build-logic/src/main/kotlin/asf/AsfProject.kt +++ b/build-logic/src/main/kotlin/asf/AsfProject.kt @@ -24,7 +24,9 @@ import groovy.json.JsonSlurper import java.io.FileNotFoundException import java.net.URI import org.gradle.api.Project -import org.gradle.kotlin.dsl.extra +import org.gradle.api.provider.Property +import org.gradle.api.services.BuildService +import org.gradle.api.services.BuildServiceParameters class AsfProject( val apacheId: String, @@ -39,14 +41,14 @@ class AsfProject( companion object { fun memoized(project: Project, asfName: String): AsfProject { - val rootProject = project.rootProject - return if (rootProject.extra.has("asfProject")) { - unsafeCast(rootProject.extra["asfProject"]) as AsfProject - } else { - val asfProject = fetchProjectInformation(asfName) - rootProject.extra["asfProject"] = asfProject - return asfProject - } + val service = + project.gradle.sharedServices.registerIfAbsent( + "asfProject-${asfName}", + AsfProjectService::class.java, + ) { + parameters.asfName.set(asfName) + } + return service.get().asfProject } internal fun unsafeCast(o: Any?): T { @@ -185,3 +187,13 @@ class AsfProject( } } } + +abstract class AsfProjectService : BuildService { + interface Parameters : BuildServiceParameters { + val asfName: Property + } + + val asfProject: AsfProject by lazy { + AsfProject.fetchProjectInformation(parameters.asfName.get()) + } +} diff --git a/build-logic/src/main/kotlin/polaris-java.gradle.kts b/build-logic/src/main/kotlin/polaris-java.gradle.kts index cc759704cdc..05434b7d580 100644 --- a/build-logic/src/main/kotlin/polaris-java.gradle.kts +++ b/build-logic/src/main/kotlin/polaris-java.gradle.kts @@ -17,12 +17,14 @@ * under the License. */ -import asf.AsfProject.Companion.unsafeCast import java.util.Properties import kotlin.jvm.java import net.ltgt.gradle.errorprone.CheckSeverity import net.ltgt.gradle.errorprone.errorprone import org.gradle.api.file.FileCollection +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.services.BuildService +import org.gradle.api.services.BuildServiceParameters import org.gradle.api.tasks.Classpath import org.gradle.api.tasks.compile.JavaCompile import org.gradle.api.tasks.testing.Test @@ -275,16 +277,32 @@ class BannedDependencies( } fun bannedDependencies(): BannedDependencies { - return if (rootProject.extra.has("bannedDependencies")) { - unsafeCast(rootProject.extra["bannedDependencies"]) as BannedDependencies - } else { - val bannedDependencies = - BannedDependencies( - BannedDependency.parseList(rootProject.file("gradle/banned-dependencies.txt")), - BannedDependency.parseList(rootProject.file("gradle/banned-quarkus-prod-dependencies.txt")), + val service = + gradle.sharedServices.registerIfAbsent( + "bannedDependencies", + BannedDependenciesService::class.java, + ) { + parameters.globallyBannedFile.set( + rootProject.layout.projectDirectory.file("gradle/banned-dependencies.txt") ) - rootProject.extra["bannedDependencies"] = bannedDependencies - bannedDependencies + parameters.quarkusProdBannedFile.set( + rootProject.layout.projectDirectory.file("gradle/banned-quarkus-prod-dependencies.txt") + ) + } + return service.get().bannedDependencies +} + +abstract class BannedDependenciesService : BuildService { + interface Parameters : BuildServiceParameters { + val globallyBannedFile: RegularFileProperty + val quarkusProdBannedFile: RegularFileProperty + } + + val bannedDependencies: BannedDependencies by lazy { + BannedDependencies( + BannedDependency.parseList(parameters.globallyBannedFile.asFile.get()), + BannedDependency.parseList(parameters.quarkusProdBannedFile.asFile.get()), + ) } } diff --git a/build-logic/src/main/kotlin/publishing/MemoizedJarInfo.kt b/build-logic/src/main/kotlin/publishing/MemoizedJarInfo.kt index f90894efad6..9b3a12d889b 100644 --- a/build-logic/src/main/kotlin/publishing/MemoizedJarInfo.kt +++ b/build-logic/src/main/kotlin/publishing/MemoizedJarInfo.kt @@ -21,7 +21,6 @@ package publishing import org.gradle.api.Project import org.gradle.api.java.archives.Attributes -import org.gradle.kotlin.dsl.extra /** * Helper class to generate Jar manifest attributes including project version and Java specification @@ -36,43 +35,34 @@ internal class MemoizedJarInfo { } private fun jarManifestAttributes(rootProject: Project): Map { - return if (rootProject.extra.has("gitReleaseInfo")) { - @Suppress("UNCHECKED_CAST") - rootProject.extra["gitReleaseInfo"] as Map - } else { - val version = rootProject.version.toString() - val javaSpecificationVersion = System.getProperty("java.specification.version") - val includeGitInformation = - rootProject.hasProperty("release") || rootProject.hasProperty("jarWithGitInfo") - - val info = - if (includeGitInformation) { - val gi = GitInfo.memoized(rootProject) - mapOf( - "Implementation-Version" to version, - "Apache-Polaris-Version" to version, - "Apache-Polaris-Is-Release" to "true", - "Apache-Polaris-Build-Git-Head" to gi.gitHead, - "Apache-Polaris-Build-Git-Describe" to gi.gitDescribe, - "Apache-Polaris-Build-Java-Specification-Version" to javaSpecificationVersion, - ) - } else { - // Not adding Git information here to keep Gradle's up-to-date functionality intact. - // Varying information in the manifest would change the MANIFEST.MF file and the jar. - // If the output changes, the input of dependent tasks is no longer up-to-date and would - // need to be rebuilt. - // This would render the Gradle build-cache ineffective for every Git commit, - // especially in CI, leading to unnecessary long builds. - mapOf( - "Implementation-Version" to version, - "Apache-Polaris-Version" to version, - "Apache-Polaris-Is-Release" to "false", - "Apache-Polaris-Build-Java-Specification-Version" to javaSpecificationVersion, - ) - } + val version = rootProject.version.toString() + val javaSpecificationVersion = System.getProperty("java.specification.version") + val includeGitInformation = + rootProject.hasProperty("release") || rootProject.hasProperty("jarWithGitInfo") - rootProject.extra["gitReleaseInfo"] = info - return info + return if (includeGitInformation) { + val gi = GitInfo.memoized(rootProject) + mapOf( + "Implementation-Version" to version, + "Apache-Polaris-Version" to version, + "Apache-Polaris-Is-Release" to "true", + "Apache-Polaris-Build-Git-Head" to gi.gitHead, + "Apache-Polaris-Build-Git-Describe" to gi.gitDescribe, + "Apache-Polaris-Build-Java-Specification-Version" to javaSpecificationVersion, + ) + } else { + // Not adding Git information here to keep Gradle's up-to-date functionality intact. + // Varying information in the manifest would change the MANIFEST.MF file and the jar. + // If the output changes, the input of dependent tasks is no longer up-to-date and would + // need to be rebuilt. + // This would render the Gradle build-cache ineffective for every Git commit, + // especially in CI, leading to unnecessary long builds. + mapOf( + "Implementation-Version" to version, + "Apache-Polaris-Version" to version, + "Apache-Polaris-Is-Release" to "false", + "Apache-Polaris-Build-Java-Specification-Version" to javaSpecificationVersion, + ) } } }