From a1fe0c72ca14a60773dac73da9482eb54e18f3cf Mon Sep 17 00:00:00 2001 From: Chris Beams Date: Tue, 13 Jul 2010 14:25:10 +0200 Subject: [PATCH] added checks.gradle --- build.gradle | 11 +++- docs/api/build.gradle | 70 +++++++++++------------ docs/reference/build.gradle | 66 +++++++++++----------- gradle.properties | 2 +- gradle/checks.gradle | 92 ++++++++++++++++++++++++++++++ gradle/release.gradle | 108 +++++++++++------------------------- 6 files changed, 203 insertions(+), 146 deletions(-) create mode 100644 gradle/checks.gradle diff --git a/build.gradle b/build.gradle index bb1d7612..b5ff6376 100644 --- a/build.gradle +++ b/build.gradle @@ -231,7 +231,7 @@ project('spring-rabbit-admin') { compile "org.springframework:spring-context:$springVersion" compile "org.springframework:spring-oxm:$springVersion" compile "org.springframework:spring-test:$springVersion" - compile "org.springframework:spring-tx:$springVersion" + compile "org.springframework:spring-tx:3.0.4.BUILD-SNAPSHOT" compile 'junit:junit:4.7' testCompile "org.erlang.otp:jinterface:$erlangVersion" testCompile "org.springframework:spring-beans:$springVersion" @@ -290,6 +290,13 @@ project(':spring-amqp-samples:stocks') { } +// add tasks like 'distArchive' +apply from: "$rootDir/gradle/release.gradle" + +// add tasks like 'snapshotDependencyCheck' +apply from: "${rootDir}/gradle/checks.gradle" + + // ----------------------------------------------------------------------------- // Conditionally import tasks related to releasing and managing the project // depending on the role played by the current user. @@ -297,8 +304,6 @@ project(':spring-amqp-samples:stocks') { // @see gradle.properties for more information on roles // ----------------------------------------------------------------------------- if (project.properties['role'] == 'buildmaster') { - // add tasks for releasing the project such as 'dist', 'uploadDist', etc. - apply from: "$rootDir/gradle/release.gradle" // add management tasks like `wrapper` for generating the gradlew* scripts apply from: "$rootDir/gradle/wrapper.gradle" diff --git a/docs/api/build.gradle b/docs/api/build.gradle index 34a790a6..bb92afb6 100644 --- a/docs/api/build.gradle +++ b/docs/api/build.gradle @@ -80,8 +80,8 @@ docsSpec = copySpec { } } -task build(dependsOn: assemble) { -} + +task build(dependsOn: assemble) task docsArchive(type: Tar, dependsOn: aggregateJavadoc) { @@ -96,47 +96,49 @@ task docsArchive(type: Tar, dependsOn: aggregateJavadoc) { configurations { archives } artifacts { archives docsArchive } -uploadArchives { - def docUrl = "http://${sshHost}/${rootProject.name}/docs/${version.wildcardValue}/api" - def remoteDocsDir = "${remoteSiteDir}/docs/${version.wildcardValue}" - def fqRemoteDir = "${sshUsername}@${sshHost}:${remoteDocsDir}" +if (role == 'buildmaster') { + uploadArchives { + def docUrl = "http://${sshHost}/${rootProject.name}/docs/${version.wildcardValue}/api" + def remoteDocsDir = "${remoteSiteDir}/docs/${version.wildcardValue}" + def fqRemoteDir = "${sshUsername}@${sshHost}:${remoteDocsDir}" - description = "Uploads API documentation to ${docUrl}" + description = "Uploads API documentation to ${docUrl}" - uploadDescriptor = false + uploadDescriptor = false - repositories { - add(new org.apache.ivy.plugins.resolver.SshResolver()) { - name = sshHost // used for debugging - host = sshHost - user = sshUsername - keyFile = sshPrivateKey as File - addArtifactPattern "${remoteDocsDir}/${docsArchive.archiveName}" + repositories { + add(new org.apache.ivy.plugins.resolver.SshResolver()) { + name = sshHost // used for debugging + host = sshHost + user = sshUsername + keyFile = sshPrivateKey as File + addArtifactPattern "${remoteDocsDir}/${docsArchive.archiveName}" + } } - } - configurations { scpAntTask } - dependencies { scpAntTask 'org.apache.ant:ant-jsch:1.8.1' } + configurations { scpAntTask } + dependencies { scpAntTask 'org.apache.ant:ant-jsch:1.8.1' } - doFirst { - println "Uploading: ${docsArchive.archivePath} to ${fqRemoteDir}" - } + doFirst { + println "Uploading: ${docsArchive.archivePath} to ${fqRemoteDir}" + } - doLast { - project.ant { - taskdef(name: 'sshexec', - classname: 'org.apache.tools.ant.taskdefs.optional.ssh.SSHExec', - classpath: configurations.scpAntTask.asPath) + doLast { + project.ant { + taskdef(name: 'sshexec', + classname: 'org.apache.tools.ant.taskdefs.optional.ssh.SSHExec', + classpath: configurations.scpAntTask.asPath) - // copy the archive, unpack it, then delete it - def unpackCommand = "cd ${remoteDocsDir} && tar -xjf ${docsArchive.archiveName}" - def deleteCommand = "rm ${remoteDocsDir}/${docsArchive.archiveName}" + // copy the archive, unpack it, then delete it + def unpackCommand = "cd ${remoteDocsDir} && tar -xjf ${docsArchive.archiveName}" + def deleteCommand = "rm ${remoteDocsDir}/${docsArchive.archiveName}" - println "sshexec ${unpackCommand}" - sshexec(host: sshHost, username: sshUsername, keyfile: sshPrivateKey, command: unpackCommand) - println "sshexec ${deleteCommand}" - sshexec(host: sshHost, username: sshUsername, keyfile: sshPrivateKey, command: deleteCommand) - println "UPLOAD SUCCESSFUL - validate by visiting ${docUrl}" + println "sshexec ${unpackCommand}" + sshexec(host: sshHost, username: sshUsername, keyfile: sshPrivateKey, command: unpackCommand) + println "sshexec ${deleteCommand}" + sshexec(host: sshHost, username: sshUsername, keyfile: sshPrivateKey, command: deleteCommand) + println "UPLOAD SUCCESSFUL - validate by visiting ${docUrl}" + } } } } diff --git a/docs/reference/build.gradle b/docs/reference/build.gradle index 7bd662fb..77b14b2e 100644 --- a/docs/reference/build.gradle +++ b/docs/reference/build.gradle @@ -124,47 +124,49 @@ task docsArchive(type: Tar, dependsOn: [docbookHtml, docbookHtmlSingle, docbookP configurations { archives } artifacts { archives docsArchive } -uploadArchives { - def docUrl = "http://${sshHost}/${rootProject.name}/docs/${version.wildcardValue}/reference" - def remoteDocsDir = "${remoteSiteDir}/docs/${version.wildcardValue}" - def fqRemoteDir = "${sshUsername}@${sshHost}:${remoteDocsDir}" +if (role == 'buildmaster') { + uploadArchives { + def docUrl = "http://${sshHost}/${rootProject.name}/docs/${version.wildcardValue}/reference" + def remoteDocsDir = "${remoteSiteDir}/docs/${version.wildcardValue}" + def fqRemoteDir = "${sshUsername}@${sshHost}:${remoteDocsDir}" - description = "Uploads HTML and PDF reference documentation to ${docUrl}" + description = "Uploads HTML and PDF reference documentation to ${docUrl}" - uploadDescriptor = false + uploadDescriptor = false - repositories { - add(new org.apache.ivy.plugins.resolver.SshResolver()) { - name = sshHost // used for debugging - host = sshHost - user = sshUsername - keyFile = sshPrivateKey as File - addArtifactPattern "${remoteDocsDir}/${docsArchive.archiveName}" + repositories { + add(new org.apache.ivy.plugins.resolver.SshResolver()) { + name = sshHost // used for debugging + host = sshHost + user = sshUsername + keyFile = sshPrivateKey as File + addArtifactPattern "${remoteDocsDir}/${docsArchive.archiveName}" + } } - } - configurations { scpAntTask } - dependencies { scpAntTask 'org.apache.ant:ant-jsch:1.8.1' } + configurations { scpAntTask } + dependencies { scpAntTask 'org.apache.ant:ant-jsch:1.8.1' } - doFirst { - println "Uploading: ${docsArchive.archivePath} to ${fqRemoteDir}" - } + doFirst { + println "Uploading: ${docsArchive.archivePath} to ${fqRemoteDir}" + } - doLast { - project.ant { - taskdef(name: 'sshexec', - classname: 'org.apache.tools.ant.taskdefs.optional.ssh.SSHExec', - classpath: configurations.scpAntTask.asPath) + doLast { + project.ant { + taskdef(name: 'sshexec', + classname: 'org.apache.tools.ant.taskdefs.optional.ssh.SSHExec', + classpath: configurations.scpAntTask.asPath) - // copy the archive, unpack it, then delete it - def unpackCommand = "cd ${remoteDocsDir} && tar -xjf ${docsArchive.archiveName}" - def deleteCommand = "rm ${remoteDocsDir}/${docsArchive.archiveName}" + // copy the archive, unpack it, then delete it + def unpackCommand = "cd ${remoteDocsDir} && tar -xjf ${docsArchive.archiveName}" + def deleteCommand = "rm ${remoteDocsDir}/${docsArchive.archiveName}" - println "sshexec ${unpackCommand}" - sshexec(host: sshHost, username: sshUsername, keyfile: sshPrivateKey, command: unpackCommand) - println "sshexec ${deleteCommand}" - sshexec(host: sshHost, username: sshUsername, keyfile: sshPrivateKey, command: deleteCommand) - println "UPLOAD SUCCESSFUL - validate by visiting ${docUrl}" + println "sshexec ${unpackCommand}" + sshexec(host: sshHost, username: sshUsername, keyfile: sshPrivateKey, command: unpackCommand) + println "sshexec ${deleteCommand}" + sshexec(host: sshHost, username: sshUsername, keyfile: sshPrivateKey, command: deleteCommand) + println "UPLOAD SUCCESSFUL - validate by visiting ${docUrl}" + } } } } diff --git a/gradle.properties b/gradle.properties index 2f6f3163..92631b91 100644 --- a/gradle.properties +++ b/gradle.properties @@ -29,7 +29,7 @@ role = developer # s3AccessKey= # s3SecretAccessKey= # docsHost=static.springsource.org -sshHost=static.springsource.org +# sshHost=static.springsource.org # sshUsername= # sshPrivateKey= diff --git a/gradle/checks.gradle b/gradle/checks.gradle new file mode 100644 index 00000000..cb01fe6f --- /dev/null +++ b/gradle/checks.gradle @@ -0,0 +1,92 @@ + +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed 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. + */ + +import org.springframework.build.Version.ReleaseType + +/** + * Issue a snapshot dependency report across all Java projects. Detects not + * only direct snapshot dependencies, but transitive as well. + * + * @author cbeams + * @see snapshotDependencyCheck + */ +task snapshotDependencyReport { + description = 'Issues a snapshot dependency report across all Java projects' + + doFirst() { + def snapshotDependencies = new HashMap>() + + javaprojects.each { project -> + project.sourceSets.main.compileClasspath.allDependencies.each { dep -> + if (dep.version.endsWith('SNAPSHOT')) { + if (snapshotDependencies[project] == null) + snapshotDependencies[project] = new ArrayList() + snapshotDependencies[project].add(dep) + } + } + } + + project.hasSnapshotDependencies = snapshotDependencies.size() > 0 + + if (project.hasSnapshotDependencies) { + println "The following snapshot dependencies were found:" + snapshotDependencies.each { entry -> + println "${entry.key} depends on:" + entry.value.each { dep -> + println " ${dep}" + } + } + } + } +} + + +/** + * Abort the build if any Java projects have snapshot dependencies. It important + * that any non-snapshot release be checked for snapshot dependencies before + * final publication, as snapshot dependencies may change and thus make the + * release unstable and/or unreproducable. + * + * This task will be added to the build lifecycle automatically if the release + * is non-snapshot. + * + * -PignoreSnapshotDependencies will bypass aborting the build. A use case for + * this option would be if a transitive dependency out of your control is a + * snapshot release and you wish to proceed with releasing anyway. + * + * @author cbeams + * @see snapshotDependencyReport + */ +task snapshotDependencyCheck(dependsOn: snapshotDependencyReport) { + description = 'Aborts the build if any Java project has snapshot dependencies.' + + // bind to build lifecycle if we're a non-snapshot release + if (version.releaseType != ReleaseType.SNAPSHOT) { + check.dependsOn snapshotDependencyCheck + } + + onlyIf { + project.hasSnapshotDependencies && + !project.hasProperty('ignoreSnapshotDependencies') + } + doFirst { + throw new GradleException( + "aborting '${name}' task due to snapshot dependencies. " + + "supply -PignoreSnapshotDependencies to override") + } + +} diff --git a/gradle/release.gradle b/gradle/release.gradle index 11ae530b..1172b0a8 100644 --- a/gradle/release.gradle +++ b/gradle/release.gradle @@ -14,9 +14,6 @@ * limitations under the License. */ -import org.springframework.build.gradle.tasks.UploadDist; -import org.springframework.build.Version.ReleaseType - // ----------------------------------------------------------------------------- // Task definitions related to releasing the project // @@ -30,8 +27,9 @@ project.subprojects.each { project -> evaluationDependsOn project.path } +task check() -task build(dependsOn: assemble) +task build(dependsOn: [check, assemble]) /** * Build the distribution zip file. @@ -96,85 +94,43 @@ task distArchive(type: Zip) { } -/** - * Upload the distribution zip file. - * - * @author ltaylor - * @author cbeams - */ -task uploadArchives(overwrite: true, dependsOn: distArchive) { // base plugin adds one we need to overwrite - description = 'Uploads the distribution zip file.' +if (role == 'buildmaster') { + /** + * Upload the distribution zip file. + * + * @author ltaylor + * @author cbeams + */ + task uploadArchives(overwrite: true, dependsOn: distArchive) { // base plugin adds one we need to overwrite + description = 'Uploads the distribution zip file.' - configurations { antlibs } - dependencies { - antlibs "org.springframework.build:org.springframework.build.aws.ant:3.0.3.RELEASE", - "net.java.dev.jets3t:jets3t:0.6.1" - } + configurations { antlibs } + dependencies { + antlibs "org.springframework.build:org.springframework.build.aws.ant:3.0.3.RELEASE", + "net.java.dev.jets3t:jets3t:0.6.1" + } - def releaseType = version.releaseType.toString().toLowerCase() + def releaseType = version.releaseType.toString().toLowerCase() - doLast() { - println "Uploading: ${distArchive.archivePath} to s3" - project.ant { - taskdef(resource: 'org/springframework/build/aws/ant/antlib.xml', - classpath: configurations.antlibs.asPath) - s3(accessKey: s3AccessKey, secretKey: s3SecretAccessKey) { - upload(bucketName: 'dist.springframework.org', file: distArchive.archivePath, - toFile: releaseType + "/AMQP/${distArchive.archiveName}", publicRead: 'true') { - metadata(name: 'project.name', value: 'Spring AMQP') - metadata(name: 'release.type', value: releaseType) - metadata(name: 'bundle.version', value: version) - metadata(name: 'package.file.name', value: distArchive.archiveName) + doLast() { + println "Uploading: ${distArchive.archivePath} to s3" + project.ant { + taskdef(resource: 'org/springframework/build/aws/ant/antlib.xml', + classpath: configurations.antlibs.asPath) + s3(accessKey: s3AccessKey, secretKey: s3SecretAccessKey) { + upload(bucketName: 'dist.springframework.org', file: distArchive.archivePath, + toFile: releaseType + "/AMQP/${distArchive.archiveName}", publicRead: 'true') { + metadata(name: 'project.name', value: 'Spring AMQP') + metadata(name: 'release.type', value: releaseType) + metadata(name: 'bundle.version', value: version) + metadata(name: 'package.file.name', value: distArchive.archiveName) + } + upload(bucketName: 'dist.springframework.org', file: "${distArchive.archivePath}.sha1", + toFile: releaseType + "/AMQP/${distArchive.archiveName}.sha1", publicRead: 'true') } - upload(bucketName: 'dist.springframework.org', file: "${distArchive.archivePath}.sha1", - toFile: releaseType + "/AMQP/${distArchive.archiveName}.sha1", publicRead: 'true') } } } } -/** - * Check all java projects for dependencies having a SNAPSHOT version and abort - * the build if found. This task can be used standalone at any time, but is - * intended primarily for use during the project release workflow. It is - * important that any non-snapshot build be checked for snapshot dependencies - * before final publication, as snapshot dependencies may change and thus make - * the build unstable and/or unreproducable. - * - * @author cbeams - */ -task checkSnapshotDeps { - description = 'Checks for snapshot dependencies and aborts the build if found.' - - if (version.releaseType == ReleaseType.MILESTONE || - version.releaseType == ReleaseType.RELEASE) { - release.dependsOn checkSnapshotDeps - } - - doFirst() { - def snapshotDependencies = new HashMap>() - javaprojects.each { project -> - project.sourceSets.main.compileClasspath.allDependencies.each { dep -> - if (dep.version.endsWith('SNAPSHOT')) { - if (snapshotDependencies[project] == null) - snapshotDependencies[project] = new ArrayList() - snapshotDependencies[project].add(dep) - } - } - } - if (snapshotDependencies.size() > 0) { - println "you have snapshot dependencies" - snapshotDependencies.each { entry -> - println "${entry.key} depends on:" - entry.value.each { dep -> - println " ${dep}" - } - } - throw new GradleException( - "aborting '${name}' task due to snapshot dependencies. " - + "supply -PignoreSnapshotDependencies to override") - } - } -} -