Skip to content

Commit

Permalink
Use Gradle POM DSL for customizations
Browse files Browse the repository at this point in the history
- First introduced in Gradle 4.8 (released 2018-06-04)[1]
- Allows this to gracefully co-exist with other plugins that also
  customize the POM. The concrete issue this addresses is a
  conflict with another plugin that also set the POM's description
  from the project's description. This works OK when both use the
  dsl, but when just one does we end up with duplicate nodes and
  publishing fails
- Some test files are changed because the XML comparison function
  relies on ordering in the document. The contents remain the same

[1]: https://docs.gradle.org/4.8/release-notes.html#customizing-the-generated-pom
  • Loading branch information
sghill committed Apr 2, 2019
1 parent 32fc9e7 commit 792be79
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 53 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
## 0.31.0 (unreleased)

* Use [Gradle DSL for POM customization](https://docs.gradle.org/4.8/release-notes.html#customizing-the-generated-pom)
to allow multiple customizations to co-exist. For example, if you have multiple
plugins that set the POM's description from the project description, they work
OK together if both using the DSL. This plugin was creating another node, which
resulted in duplicate elements. This feature has been available since Gradle 4.8
(released 2018-06-04).

## 0.30.0 (2019-04-01)

* `-SNAPSHOT` plugin version suffix format changed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import org.gradle.api.GradleException
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.XmlProvider
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ConfigurationContainer
import org.gradle.api.artifacts.Dependency
Expand Down Expand Up @@ -348,10 +347,7 @@ class JpiPlugin implements Plugin<Project> {
artifact sourcesJar
artifact javadocJar

pom.packaging = jpiExtension.fileExtension
pom.withXml { XmlProvider xmlProvider ->
new JpiPomCustomizer(project).customizePom(xmlProvider.asNode())
}
new JpiPomCustomizer(project).customizePom(pom)
}
}
publishingExtension.repositories {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
package org.jenkinsci.gradle.plugins.jpi

import groovy.transform.CompileStatic
import org.gradle.api.Project
import org.gradle.api.XmlProvider
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.DependencySet
import org.gradle.api.artifacts.ModuleDependency
import org.gradle.api.artifacts.repositories.MavenArtifactRepository
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.provider.Property
import org.gradle.api.publish.maven.MavenPom
import org.gradle.api.publish.maven.MavenPomDeveloper
import org.gradle.api.publish.maven.MavenPomDeveloperSpec
import org.gradle.api.publish.maven.MavenPomLicense
import org.gradle.api.publish.maven.MavenPomLicenseSpec
import org.gradle.api.publish.maven.MavenPomScm

import static org.gradle.api.artifacts.ArtifactRepositoryContainer.DEFAULT_MAVEN_CENTRAL_REPO_NAME
import static org.gradle.api.artifacts.ArtifactRepositoryContainer.DEFAULT_MAVEN_LOCAL_REPO_NAME
Expand Down Expand Up @@ -34,23 +43,62 @@ class JpiPomCustomizer {
this.jpiExtension = project.extensions.findByType(JpiExtension)
}

void customizePom(Node pom) {
pom.appendNode('name', jpiExtension.displayName)
if (jpiExtension.url) {
pom.appendNode('url', jpiExtension.url)
}
if (project.description) {
pom.appendNode('description', project.description)
}
if (jpiExtension.gitHubUrl) {
pom.append(makeScmNode())
@CompileStatic
void customizePom(MavenPom pom) {
pom.packaging = jpiExtension.fileExtension
pom.name.set(jpiExtension.displayName)
pom.url.set(jpiExtension.url)
pom.description.set(project.description)
def github = jpiExtension.gitHubUrl
if (github) {
pom.scm { MavenPomScm s ->
s.url.set(github)
if (github =~ /^https:\/\/github\.com/) {
s.connection.set(github.replaceFirst(~/https:/, 'scm:git:git:') + '.git')
}
}
}
if (!jpiExtension.licenses.isEmpty()) {
pom.appendNode('licenses', jpiExtension.licenses.collect { JpiLicense l -> makeLicenseNode(l) })
pom.licenses { MavenPomLicenseSpec s ->
jpiExtension.licenses.each { JpiLicense declared ->
s.license { MavenPomLicense l ->
['name' : l.name,
'url' : l.url,
'distribution': l.distribution,
'comments' : l.comments,
].each {
mapExtensionToProperty(declared, it.key, it.value)
}
}
}
}
}
if (!jpiExtension.developers.isEmpty()) {
pom.appendNode('developers', jpiExtension.developers.collect { JpiDeveloper d -> makeDeveloperNode(d) })
pom.developers { MavenPomDeveloperSpec s ->
jpiExtension.developers.each { JpiDeveloper declared ->
s.developer { MavenPomDeveloper d ->
['id' : d.id,
'name' : d.name,
'email' : d.email,
'url' : d.url,
'organization' : d.organization,
'organizationUrl': d.organizationUrl,
'timezone' : d.timezone,
].each {
mapExtensionToProperty(declared, it.key, it.value)
}
}
}
}
}
pom.withXml { XmlProvider xmlProvider -> additionalCustomizations(xmlProvider.asNode()) }
}

private static mapExtensionToProperty(Object from, String property, Property<String> to) {
to.set(from.getProperty(property) as String)
}

void additionalCustomizations(Node pom) {
if (repositories) {
pom.appendNode('repositories', repositories.collect { makeRepositoryNode(it) })
}
Expand Down Expand Up @@ -120,15 +168,6 @@ class JpiPomCustomizer {
}
}

private Node makeScmNode() {
Node scmNode = new Node(null, 'scm')
scmNode.appendNode('url', jpiExtension.gitHubUrl)
if (jpiExtension.gitHubUrl =~ /^https:\/\/github\.com/) {
scmNode.appendNode('connection', jpiExtension.gitHubUrl.replaceFirst(~/https:/, 'scm:git:git:') + '.git')
}
scmNode
}

private List<MavenArtifactRepository> getRepositories() {
project.repositories.withType(MavenArtifactRepository).findAll {
!(it.name =~ "${DEFAULT_MAVEN_CENTRAL_REPO_NAME}\\d*" || it.name =~ "${DEFAULT_MAVEN_LOCAL_REPO_NAME}\\d*")
Expand All @@ -141,26 +180,4 @@ class JpiPomCustomizer {
repositoryNode.appendNode('url', repository.url)
repositoryNode
}

private static Node makeDeveloperNode(JpiDeveloper developer) {
Node developerNode = new Node(null, 'developer')
JpiDeveloper.LEGAL_FIELDS.each { String key ->
def value = developer[key]
if (value) {
developerNode.appendNode(key, value)
}
}
developerNode
}

private static Node makeLicenseNode(JpiLicense license) {
Node licenseNode = new Node(null, 'license')
JpiLicense.LEGAL_FIELDS.each { String key ->
def value = license[key]
if (value) {
licenseNode.appendNode(key, value)
}
}
licenseNode
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,48 @@ class JpiPomCustomizerIntegrationSpec extends IntegrationSpec {
compareXml('minimal-pom.xml', actualPomIn(projectDir))
}

def 'minimal POM with other publication logic setting the name'() {
setup:
build << """\
apply plugin: 'maven-publish'
jenkinsPlugin {
coreVersion = '1.580.1'
}
publishing.publications.withType(org.gradle.api.publish.maven.MavenPublication) {
it.pom {
name = project.name
}
}
""".stripIndent()

when:
generatePom()

then:
compareXml('minimal-pom.xml', actualPomIn(projectDir))
}

def 'POM with other publication logic setting the description'() {
setup:
build << """\
apply plugin: 'maven-publish'
jenkinsPlugin {
coreVersion = '1.580.1'
}
description = 'this is my description'
publishing.publications.withType(org.gradle.api.publish.maven.MavenPublication) {
it.pom {
description = project.description
}
}
""".stripIndent()

when:
generatePom()
then:
compareXml('minimal-pom-with-description.xml', actualPomIn(projectDir))
}

def 'POM with all metadata'() {
setup:
build << """\
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,8 @@
<version>unspecified</version>
<packaging>hpi</packaging>
<name>test</name>
<url>https://lorem-ipsum.org</url>
<description>lorem ipsum</description>
<scm>
<url>https://github.com/lorem/ipsum</url>
<connection>scm:git:git://github.com/lorem/ipsum.git</connection>
</scm>
<url>https://lorem-ipsum.org</url>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
Expand All @@ -29,6 +25,10 @@
<email>andrew.bayer@gmail.com</email>
</developer>
</developers>
<scm>
<connection>scm:git:git://github.com/lorem/ipsum.git</connection>
<url>https://github.com/lorem/ipsum</url>
</scm>
<repositories>
<repository>
<id>lorem-ipsum</id>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId/>
<artifactId>test</artifactId>
<version>unspecified</version>
<packaging>hpi</packaging>
<name>test</name>
<description>this is my description</description>
<repositories>
<repository>
<id>jenkins</id>
<url>https://repo.jenkins-ci.org/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>jenkins-core</artifactId>
<version>1.580.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>findbugs</groupId>
<artifactId>annotations</artifactId>
<version>1.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

0 comments on commit 792be79

Please sign in to comment.