| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| |
| apply plugin: 'maven-publish' |
| apply plugin: 'signing' |
| |
| task sourcesJar(type: Jar) { |
| from sourceSets.main.allJava |
| classifier = 'sources' |
| } |
| |
| task javadocJar(type: Jar) { |
| from javadoc |
| classifier = 'javadoc' |
| } |
| |
| def apacheLicense = ''' |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| ''' |
| |
| publishing { |
| publications { |
| maven(MavenPublication) { |
| from components.java |
| |
| // use the (possibly empty) Jar tasks above for sources and javadoc |
| artifact sourcesJar |
| artifact javadocJar |
| |
| pom { |
| name = 'Apache Geode' |
| description = 'Apache Geode provides a database-like consistency model, reliable transaction processing and a shared-nothing architecture to maintain very low latency performance with high concurrency processing' |
| url = 'http://geode.apache.org' |
| |
| scm { |
| url = 'https://github.com/apache/geode' |
| connection = 'scm:git:https://github.com:apache/geode.git' |
| developerConnection = 'scm:git:https://github.com:apache/geode.git' |
| } |
| |
| licenses { |
| license { |
| name = 'The Apache Software License, Version 2.0' |
| url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' |
| } |
| } |
| |
| withXml { |
| // This black magic checks to see if a dependency has the flag ext.optional=true |
| // set on it, and if so marks the dependency as optional in the maven pom |
| def depMap = project.configurations.compile.dependencies.collectEntries { [it.name, it] } |
| def runtimeDeps = project.configurations.runtime.dependencies.collectEntries { |
| [it.name, it] |
| } |
| def runtimeOnlyDeps = project.configurations.runtimeOnly.dependencies.collectEntries { |
| [it.name, it] |
| } |
| depMap.putAll(runtimeDeps) |
| depMap.putAll(runtimeOnlyDeps) |
| asNode().dependencies.dependency.findAll { |
| def dep = depMap.get(it.artifactId.text()) |
| return dep?.hasProperty('optional') && dep.optional |
| }.each { |
| if (it.optional) { |
| it.optional.value = 'true' |
| } else { |
| it.appendNode('optional', 'true') |
| } |
| } |
| } |
| |
| withXml { |
| // Geode dependency versions, as with all versions, are locked by the |
| // Spring dependency-management plugin. We remove version specification as injected by |
| // project dependencies, e.g., compile project(':geode-core') |
| asNode().dependencies.dependency.each { dep -> |
| if (dep.toString().contains("org.apache.geode")) { |
| dep.remove(dep["version"]) |
| } |
| } |
| } |
| afterEvaluate { |
| withXml { |
| def providerAsElement = asElement() |
| providerAsElement.insertBefore( |
| providerAsElement.ownerDocument().createComment(apacheLicense), |
| providerAsElement.firstChild) |
| } |
| } |
| } |
| } |
| } |
| repositories { |
| maven { |
| // Use specified mavenRepository if provided, else use release or snapshot defaults. |
| url = project.findProperty("mavenRepository") ?: |
| project.isReleaseVersion ? project.mavenReleaseUrl : project.mavenSnapshotUrl |
| if (url.toString().startsWith("http") || url.toString().startsWith("sftp")) { |
| // Username / password credentials are only supported for http, https, and sftp repos. |
| // See the Gradle documentation on Repository Types for more information. |
| credentials { |
| username project.findProperty("mavenUsername") |
| password project.findProperty("mavenPassword") |
| } |
| } |
| } |
| } |
| } |
| |
| signing { |
| required({project.isReleaseVersion && project.hasProperty('signing.keyId') && project.hasProperty('signing.secretKeyRingFile')}) |
| sign publishing.publications.maven |
| } |
| |
| task install(dependsOn: publishToMavenLocal) {} |
| |
| task('checkPom') { |
| // The XmlParser used below has a strange tendency to return lists of fields rather than the field |
| // you actually want. Be careful with that, future developer. |
| group 'verification' |
| dependsOn('generatePomFileForMavenPublication') |
| description 'Checks the generated POM against an expected POM for dependency changes.' + |
| ' Ignores versions of Apache Geode dependencies.' |
| def expectedPomFile = sourceSets.test.resources.getSourceDirectories().first().toPath().resolve("expected-pom.xml") |
| def actualPomFile = generatePomFileForMavenPublication.outputs.files.first() |
| def thisOutput = project.buildDir.toPath().resolve('reports').resolve('checkPom.out') |
| inputs.files { [expectedPomFile, actualPomFile] } |
| outputs.files { thisOutput } |
| |
| // We impose the following rules on our produced poms: |
| // * Versions are to be specified in the <dependencyManagement> block, not the <dependency> block |
| // * org.apache.geode versions will be ignored, in favor of this build's version |
| // * <dependency> blocks in produced POMs are as expected (ordering ignored) |
| // * <dependencyManagement> blocks in produced POMs are as expected (ordering ignored) |
| // * Published groupId = "org.apache.geode" |
| // * Published artifactId = project.artifactName if it exists, else project.name |
| |
| def anyVersionDefinitionNotInDependencyManagement = { pom -> |
| pom.dependencies.dependency.any { |
| it.get("version")*.value() != [] |
| } |
| } |
| |
| def ignoreGeodeVersionInExpectedPom = { pom -> |
| pom.dependencyManagement.dependencies.dependency.each { dep -> |
| if (dep.toString().contains("org.apache.geode")) { |
| // since the project version is the source of truth, use that for comparison instead of |
| // whatever is stored in the expected pom file |
| dep.get("version")*.setValue([version]) |
| } |
| } |
| } |
| |
| def dependenciesBlocksMatch = { actual, expected -> |
| def actualTreeSet = actual.dependencies.dependency.collect {it.toString()}.toSet() |
| def expectedTreeSet = expected.dependencies.dependency.collect {it.toString()}.toSet() |
| actualTreeSet.equals(expectedTreeSet) |
| } |
| |
| def groupMismatches = { pom -> |
| def groupId = pom["groupId"] |
| groupId*.value().flatten().any { |
| it != project.group |
| } |
| } |
| |
| def artifactMismatches = { pom -> |
| // This work-around for 'artifactName' or 'project.name' is for geode-assembly, which re-names its output |
| def artifactId = pom["artifactId"] |
| artifactId*.value().flatten().any { |
| it != (project.findProperty('artifactName') ?: project.name) |
| } |
| } |
| |
| doLast { |
| if (tasks.getByName("generatePomFileForMavenPublication").enabled) { |
| if (null == expectedPomFile) { |
| throw new RuntimeException("expected-pom.xml not found.") |
| } |
| def expectedPom = new XmlParser().parse(expectedPomFile.toString()) |
| ignoreGeodeVersionInExpectedPom(expectedPom) |
| |
| // Sanity checks against the expected pom. |
| def pathologicalArtifactId = artifactMismatches(expectedPom) |
| def pathologicalGroupId = groupMismatches(expectedPom) |
| def pathologicalVersionedDeps = anyVersionDefinitionNotInDependencyManagement(expectedPom) |
| |
| if (pathologicalArtifactId || pathologicalGroupId || pathologicalVersionedDeps) { |
| def errorSummary = "" |
| errorSummary += pathologicalArtifactId ? "Expected POM header pathologically incorrect. Fix artifactId to match subproject name.\n" : "" |
| errorSummary += pathologicalGroupId ? "Expected POM header pathologically incorrect. Fix groupId to be 'org.apache.geode'.\n" : "" |
| errorSummary += pathologicalVersionedDeps ? "Expected POM should not declare dependency versions outside the Spring dependency-management constraints." : "" |
| throw new GradleException(errorSummary) |
| } |
| |
| def actualPom = new XmlParser().parse(actualPomFile) |
| |
| def badArtifactId = artifactMismatches(actualPom) |
| def badGroupId = groupMismatches(actualPom) |
| def improperlyVersionedDeps = anyVersionDefinitionNotInDependencyManagement(actualPom) |
| def depsMismatch = !dependenciesBlocksMatch(expectedPom, actualPom) |
| def versionMismatch = !dependenciesBlocksMatch(expectedPom.dependencyManagement, actualPom.dependencyManagement) |
| |
| if (badArtifactId || badGroupId || improperlyVersionedDeps || depsMismatch || versionMismatch) { |
| def errorSummary = "" |
| errorSummary += badArtifactId ? "POM header information incorrect. Fix artifactId.\n" : "" |
| errorSummary += badGroupId ? "POM header information incorrect. Fix groupId.\n" : "" |
| errorSummary += improperlyVersionedDeps ? "Version definition should be in the <dependencyManagement> block only.\n" : "" |
| errorSummary += depsMismatch ? "<dependencies> blocks do not match.\n" : "" |
| errorSummary += versionMismatch ? "<dependencyManagement> blocks do not match.\n" : "" |
| |
| def message = """ |
| The POM produced by the ${project.name}'s publication task has changed from expectation. |
| This is typically the result of changing or new dependencies, or dependency versions. |
| The actual publication candidate POM can be found here: ${actualPomFile} |
| The associated expected POM can be found here: ${expectedPomFile} |
| |
| ${errorSummary} |
| Please review the differences between the files indicated above. |
| This task is meant to be comprehensive -- there should be no change in the POM for which you are not responsible. |
| A possible exception is the listed Geode project dependencies, which are modified to reflect the current build's version. |
| |
| Once the differences in the above files are reviewed and confirmed to be intentional, |
| please update the expected POM file to reflect your changes. |
| Alternatively, run './gradlew ${project.name}:updateExpectedPom' to replace the expected POM with the generated POM. |
| """ |
| thisOutput.write(message) |
| throw new RuntimeException(message) |
| } |
| } |
| } |
| } |
| check.dependsOn('checkPom') |
| |
| task updateExpectedPom(dependsOn: generatePomFileForMavenPublication, type: Copy) { |
| description 'After having verified changes with checkPom, this task will perform the copy.' |
| |
| def expectedPomDir = sourceSets.test.resources.getSourceDirectories().first().toURI() |
| def actualPomFile = generatePomFileForMavenPublication.outputs.files.first() |
| if (tasks.getByName("generatePomFileForMavenPublication").enabled) { |
| from actualPomFile |
| into expectedPomDir |
| rename '.*.xml', "expected-pom.xml" |
| } |
| } |
| checkPom.mustRunAfter(updateExpectedPom) |