diff --git a/build-logic/src/main/kotlin/publishing/PublishingHelperExtension.kt b/build-logic/src/main/kotlin/publishing/PublishingHelperExtension.kt index 26c879a116..6fe21d3bc2 100644 --- a/build-logic/src/main/kotlin/publishing/PublishingHelperExtension.kt +++ b/build-logic/src/main/kotlin/publishing/PublishingHelperExtension.kt @@ -36,13 +36,40 @@ abstract class PublishingHelperExtension @Inject constructor(objectFactory: ObjectFactory, project: Project) { // the following are only relevant on the root project - val asfProjectName = objectFactory.property().convention(project.name) + + /** + * Lowercase ASF project ID, as present in keys in the JSON docs describing the projects (for + * example in `https://whimsy.apache.org/public/public_ldap_projects.json`). + */ + val asfProjectId = objectFactory.property().convention(project.name) + + /** Used to override the full project name, for example `Apache Polaris`. */ val overrideName = objectFactory.property() + /** Used to override the project description as it appears in published Maven poms. */ val overrideDescription = objectFactory.property() + /** Used to override the project URL as it appears in published Maven poms. */ + val overrideProjectUrl = objectFactory.property() + /** + * Used to override the name of the GitHub repo in the apache organization. Defaults to the + * project ID. + */ + val githubRepositoryName = objectFactory.property() + /** + * Used to override the project's SCM as it appears in published Maven poms. Default is derived + * from `githubRepoName`. + */ + val overrideScm = objectFactory.property() + /** Used to override the project's issue management URL as it appears in published Maven poms. */ + val overrideIssueManagement = objectFactory.property() + /** Prefix for the tag published for non-SNAPSHOT versions in the Maven poms. */ + val overrideTagPrefix = objectFactory.property() + + /** The published distributables, including the source tarball, base file name. */ val baseName = objectFactory .property() - .convention(project.provider { "apache-${asfProjectName.get()}-${project.version}" }) + .convention(project.provider { "apache-${asfProjectId.get()}-${project.version}" }) + val distributionDir = objectFactory.directoryProperty().convention(project.layout.buildDirectory.dir("distributions")) val sourceTarball = @@ -50,6 +77,7 @@ constructor(objectFactory: ObjectFactory, project: Project) { .fileProperty() .convention(project.provider { distributionDir.get().file("${baseName.get()}.tar.gz") }) + /** List of mailing-lists. */ val mailingLists = objectFactory.listProperty(String::class.java).convention(emptyList()) fun distributionFile(ext: String): File = diff --git a/build-logic/src/main/kotlin/publishing/configurePom.kt b/build-logic/src/main/kotlin/publishing/configurePom.kt index 6618b9fb27..b81c51d2a6 100644 --- a/build-logic/src/main/kotlin/publishing/configurePom.kt +++ b/build-logic/src/main/kotlin/publishing/configurePom.kt @@ -23,6 +23,7 @@ import groovy.util.Node import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.artifacts.component.ModuleComponentSelector +import org.gradle.api.provider.Provider import org.gradle.api.publish.maven.MavenPom import org.gradle.api.publish.maven.MavenPublication import org.gradle.internal.extensions.stdlib.capitalized @@ -73,7 +74,7 @@ internal fun configurePom(project: Project, mavenPublication: MavenPublication, task.doFirst { mavenPom.run { - val asfName = e.asfProjectName.get() + val asfName = e.asfProjectId.get() val projectPeople = fetchProjectPeople(asfName) organization { @@ -98,21 +99,35 @@ internal fun configurePom(project: Project, mavenPublication: MavenPublication, } } + val githubRepoName: Provider = e.githubRepositoryName.orElse(asfName) + val codeRepo: Provider = + e.overrideScm.orElse( + githubRepoName + .map { r -> "https://github.com/apache/$r" } + .orElse(projectPeople.repository) + ) + scm { - val codeRepo: String = projectPeople.repository - connection.set("scm:git:$codeRepo") - developerConnection.set("scm:git:$codeRepo") - url.set("$codeRepo/tree/main") + val codeRepoString: String = codeRepo.get() + connection.set("scm:git:$codeRepoString") + developerConnection.set("scm:git:$codeRepoString") + url.set("$codeRepoString/tree/main") val version = project.version.toString() if (!version.endsWith("-SNAPSHOT")) { - tag.set("apache-polaris-$version") + val tagPrefix: String = + e.overrideTagPrefix.orElse("apache-${projectPeople.apacheId}").get() + tag.set("$tagPrefix-$version") } } - issueManagement { url.set(projectPeople.bugDatabase) } + issueManagement { + val issuesUrl: Provider = + codeRepo.map { r -> "$r/issues" }.orElse(projectPeople.bugDatabase) + url.set(e.overrideIssueManagement.orElse(issuesUrl)) + } - name.set(e.overrideName.orElse(projectPeople.name)) + name.set(e.overrideName.orElse("Apache ${projectPeople.name}")) description.set(e.overrideDescription.orElse(projectPeople.description)) - url.set(projectPeople.website) + url.set(e.overrideProjectUrl.orElse(projectPeople.website)) inceptionYear.set(projectPeople.inceptionYear.toString()) developers { @@ -127,7 +142,7 @@ internal fun configurePom(project: Project, mavenPublication: MavenPublication, } } - addContributorsToPom(mavenPom, asfName, "Apache ${projectPeople.name}") + addContributorsToPom(mavenPom, githubRepoName.get(), "Apache ${projectPeople.name}") } } } diff --git a/build-logic/src/main/kotlin/publishing/rootProject.kt b/build-logic/src/main/kotlin/publishing/rootProject.kt index ee585fff3b..32da60d22d 100644 --- a/build-logic/src/main/kotlin/publishing/rootProject.kt +++ b/build-logic/src/main/kotlin/publishing/rootProject.kt @@ -96,7 +96,7 @@ internal fun configureOnRootProject(project: Project) = doFirst { val e = project.extensions.getByType(PublishingHelperExtension::class.java) - val asfName = e.asfProjectName.get() + val asfName = e.asfProjectId.get() val gitInfo = MemoizedGitInfo.gitInfo(rootProject) val gitCommitId = gitInfo["Apache-Polaris-Build-Git-Head"] @@ -132,7 +132,8 @@ internal fun configureOnRootProject(project: Project) = "NO STAGING REPOSITORY (no build service) !!" } - val asfProjectName = "Apache Polaris" + val asfProjectName = + e.overrideName.orElse(project.provider { "Apache ${fetchAsfProjectName(asfName)}" }).get() val versionNoRc = version.toString().replace("-rc-?[0-9]+".toRegex(), "") diff --git a/build-logic/src/main/kotlin/publishing/util.kt b/build-logic/src/main/kotlin/publishing/util.kt index 409a7aee58..2f073d4d74 100644 --- a/build-logic/src/main/kotlin/publishing/util.kt +++ b/build-logic/src/main/kotlin/publishing/util.kt @@ -79,8 +79,7 @@ internal fun parseJson(url: String): T { } } -// TODO: this function doesn't work because name attribute doesn't exist on -// public_ldap_projects.json +/** Retrieves the project name, for example `Polaris` using the lower-case project ID. */ internal fun fetchAsfProjectName(apacheId: String): String { val projectsAll: Map> = parseJson("https://whimsy.apache.org/public/public_ldap_projects.json") @@ -90,7 +89,25 @@ internal fun fetchAsfProjectName(apacheId: String): String { ?: throw IllegalArgumentException( "No project '$apacheId' found in https://whimsy.apache.org/public/public_ldap_projects.json" ) - return project["name"] as String + val isPodlingCurrent = project.containsKey("podling") && project["podling"] == "current" + if (isPodlingCurrent) { + val podlingsAll: Map> = + parseJson("https://whimsy.apache.org/public/public_podlings.json") + val podlings = unsafeCast>>(podlingsAll["podling"]) + val podling = + podlings[apacheId] + ?: throw IllegalArgumentException( + "No podling '$apacheId' found in https://whimsy.apache.org/public/public_podlings.json" + ) + return podling["name"] as String + } else { + // top-level-project + val committeesAll: Map> = + parseJson("https://whimsy.apache.org/public/committee-info.json") + val committees = unsafeCast>>(committeesAll["committees"]) + val committee = unsafeCast>(committees[apacheId]) + return committee["display_name"] as String + } } internal fun fetchProjectPeople(apacheId: String): ProjectPeople { @@ -146,6 +163,7 @@ internal fun fetchProjectPeople(apacheId: String): ProjectPeople { val mentors = unsafeCast(podling["mentors"]) as List mentors.forEach { member -> peopleProjectRoles[member]!!.add("Mentor") } } else { + // top-level-project val tlpPrj: Map = parseJson("https://projects.apache.org/json/projects/$apacheId.json") website = tlpPrj["homepage"] as String