diff --git a/.gitignore b/.gitignore index 2e1c57a45..c6b8d21cd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ target build +.gradle .springBeans .ant-targets-build.xml src/ant/.ant-targets-upload-dist.xml diff --git a/build.gradle b/build.gradle index 9665eaa91..ec4dd0830 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,6 @@ apply plugin: "eclipse" apply plugin: "idea" +apply from: "$rootDir/gradle/docbook.gradle" subprojects { apply plugin: "java" @@ -8,11 +9,21 @@ subprojects { releaseType = "M2" version = "1.0.0.$releaseType" - compileJava.options.compilerArgs = ["-Xlint:unchecked"] + [compileJava, compileTestJava]*.options*.compilerArgs = ["-Xlint:all"] + + // all core projects should be OSGi-compliant bundles + // add the bundlor task to ensure proper manifests + apply from: "$rootDir/gradle/bundlor.gradle" + project.checkForProps = { Map args -> + requiredPropSets.add args + } + // TODO: Finish integrating this stuff with our build + //apply from: "$rootDir/gradle/maven-deployment.gradle" + //apply from: "$rootDir/gradle/dist.gradle" repositories { // Read user's local Maven repo first - mavenRepo name: "mavenLocal", urls: new File(System.getProperty("user.home" ), ".m2/repository").toURL().toString() + mavenRepo name: "mavenLocal", urls: new File(System.getProperty("user.home"), ".m2/repository").toURL().toString() // Public Spring artefacts mavenRepo name: "spring-release", urls: "http://maven.springframework.org/release" mavenRepo name: "spring-milestone", urls: "http://maven.springframework.org/milestone" @@ -43,10 +54,10 @@ subprojects { compile "org.codehaus.jackson:jackson-mapper-asl:$jacksonVersion" // Testing testCompile "junit:junit:$junitVersion" - testCompile "org.springframework:spring-test:$springVersion" + testCompile "org.springframework:spring-test:$springVersion" testCompile "org.mockito:mockito-all:$mockitoVersion" } - + } configurations { @@ -60,3 +71,9 @@ repositories { dependencies { } +ideaProject { + withXml { provider -> + provider.node.component.find { it.@name == 'VcsDirectoryMappings' }.mapping.@vcs = 'Git' + } +} + diff --git a/gradle.properties b/gradle.properties index 9050c3111..0175bcc14 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ springVersion = 3.0.5.RELEASE jacksonVersion = 1.6.4 # Redis support -jedisVersion = 1.5.2-SNAPSHOT +jedisVersion = 1.5.2 jredisVersion = 03122010 # Testing diff --git a/gradle/bundlor.gradle b/gradle/bundlor.gradle new file mode 100644 index 000000000..870159da0 --- /dev/null +++ b/gradle/bundlor.gradle @@ -0,0 +1,91 @@ +/* + * 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. + */ + +// ----------------------------------------------------------------------------- +// Task definitions and configuration relating to the SpringSource 'bundlor' +// OSGi manifest generation utility. +// +// @author cbeams +// see: http://www.springsource.org/bundlor +// ----------------------------------------------------------------------------- + +/** + * Generate an OSGi manifest using the ant bundlor task. + * + * @author ltaylor + * @author cbeams + * @see http://static.springsource.org/s2-bundlor/1.0.x/user-guide/html/ch04s02.html + */ +task bundlor(dependsOn: compileJava) { + description = 'Generates an OSGi-compatibile MANIFEST.MF file.' + + def template = new File(projectDir, 'template.mf') + def bundlorDir = new File("${project.buildDir}/bundlor") + def manifest = file("${bundlorDir}/META-INF/MANIFEST.MF") + + // inform gradle what directory this task writes so that + // it can be removed when issuing `gradle cleanBundlor` + outputs.dir bundlorDir + + // incremental build configuration + // if the $manifest output file already exists, the bundlor + // task will be skipped *unless* any of the following are true + // * template.mf has been changed + // * main classpath dependencies have been changed + // * main java sources for this project have been modified + outputs.files manifest + inputs.files template, project.sourceSets.main.runtimeClasspath + + // tell the jar task to use bundlor manifest instead of the default + jar.manifest.from manifest + + // the bundlor manifest should be evaluated as part of the jar task's + // incremental build + jar.inputs.files manifest + + // configuration that will be used when creating the ant taskdef classpath + configurations { bundlorconf } + dependencies { + bundlorconf 'com.springsource.bundlor:com.springsource.bundlor.ant:1.0.0.RELEASE', + 'com.springsource.bundlor:com.springsource.bundlor:1.0.0.RELEASE', + 'com.springsource.bundlor:com.springsource.bundlor.blint:1.0.0.RELEASE' + } + + doFirst { + ant.taskdef(resource: 'com/springsource/bundlor/ant/antlib.xml', + classpath: configurations.bundlorconf.asPath) + + // the bundlor ant task writes directly to standard out + // redirect it to INFO level logging, which gradle will + // deal with gracefully + logging.captureStandardOutput(LogLevel.INFO) + + // the ant task will throw unless this dir exists + if (!bundlorDir.isDirectory()) + bundlorDir.mkdir() + + // execute the ant task, and write out the $manifest file + ant.bundlor(inputPath: sourceSets.main.classesDir, + outputPath: bundlorDir, manifestTemplatePath: template) { + property(name: 'version', value: project.version) + property(name: 'spring.version', value: project.springVersion) + } + } +} + +// ensure that the bundlor task runs prior to the jar task +jar.dependsOn bundlor + diff --git a/gradle/checks.gradle b/gradle/checks.gradle new file mode 100644 index 000000000..224011128 --- /dev/null +++ b/gradle/checks.gradle @@ -0,0 +1,90 @@ + +/* + * 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. + */ + +/** + * 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) { + group = 'Verification' + 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 != '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/dist.gradle b/gradle/dist.gradle new file mode 100644 index 000000000..0a7597467 --- /dev/null +++ b/gradle/dist.gradle @@ -0,0 +1,133 @@ +/* + * 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. + */ + +// ----------------------------------------------------------------------------- +// Task definitions related to releasing the project +// +// @author cbeams +// ----------------------------------------------------------------------------- + +// ensure that every project has been evaluated before this script +// this allows us to look up tasks below and dereference dynamically +// assigned properties like 'docsSpec' below +project.subprojects.each { project -> + evaluationDependsOn project.path +} + +task check { + group = 'Verification' +} + +task build(dependsOn: [check, assemble]) { + group = 'Build' +} + +/** + * Build the distribution zip file. + * + * @author cbeams + */ +task distArchive(type: Zip) { + group = 'Build' + + destinationDir = buildDir + archiveName = "${project.name}-${project.version}.zip" + checksumPath = "${destinationDir}/${archiveName}.sha1" + def zipRootDir = "${project.name}-${project.version}" + + description = "Builds the distribution zip file at ${project.relativePath(destinationDir)}/${archiveName}" + + // depend on all projects with an assemble task + dependsOn subprojects*.tasks*.matching { task -> task.name == 'assemble' } + + // we need the docsSpec to be defined before evaluating this task + project.evaluationDependsOn(':docs') + + // set up outputs for use by incremental build and by tasks like 'cleanDist' + // the archive zip file will be added automatically to outputs.files + // but we must add the sha1 checksum ourselves + outputs.files file(checksumPath) + + // configure the contents of the zip file. remember that this is a + // configuration phase event. no zip is being created yet. the Zip + // task we extend will do that for us during the execution phase. + into(zipRootDir) { + with(project(':docs').docsSpec) + + // add each subproject, but only add the 'src' dir and 'pom.xml' + project('spring-amqp-samples').subprojects.each { sample -> + into("${zipRootDir}/samples/${sample.name}") { + from(sample.projectDir) { + include 'src/**/*' + include 'pom.xml' + } + } + } + // add all jars and source jars from all core java projects + // (i.e.: don't include sample project jars!) + into('dist') { + from coreprojects.collect { project -> project.libsDir } + } + } + + // once the zip has been written, create a sha1 hash for it + // this will write out the file at ${checksumPath} + doLast { + ant.checksum(file: archivePath, algorithm: 'SHA1', fileext: '.sha1') + assert file(checksumPath).isFile(): "${checksumPath} was not created" + } +} + +/** + * Upload the distribution zip file. + * + * @author ltaylor + * @author cbeams + */ +task uploadArchives(overwrite: true, dependsOn: distArchive) { // base plugin adds one we need to overwrite + group = 'Buildmaster' + 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" + } + + 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) + } + upload(bucketName: 'dist.springframework.org', file: "${distArchive.archivePath}.sha1", + toFile: releaseType + "/AMQP/${distArchive.archiveName}.sha1", publicRead: 'true') + } + } + } +} + + + diff --git a/gradle/docbook.gradle b/gradle/docbook.gradle new file mode 100644 index 000000000..258b5e24f --- /dev/null +++ b/gradle/docbook.gradle @@ -0,0 +1,317 @@ +/* + * 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 ch.qos.logback.classic.Level +import com.icl.saxon.TransformerFactoryImpl +import java.util.zip.ZipEntry +import java.util.zip.ZipFile +import javax.xml.parsers.SAXParserFactory +import javax.xml.transform.Result +import javax.xml.transform.Source +import javax.xml.transform.Transformer +import javax.xml.transform.TransformerFactory +import javax.xml.transform.sax.SAXResult +import javax.xml.transform.sax.SAXSource +import javax.xml.transform.stream.StreamResult +import javax.xml.transform.stream.StreamSource +import org.apache.fop.apps.Fop +import org.apache.fop.apps.FopFactory +import org.apache.fop.apps.MimeConstants +import org.apache.xml.resolver.CatalogManager +import org.apache.xml.resolver.tools.CatalogResolver +import org.slf4j.LoggerFactory +import org.xml.sax.InputSource +import org.xml.sax.XMLReader + +buildscript { + repositories { + mavenCentral() + mavenRepo name: 'Shibboleth Repo', urls: 'http://shibboleth.internet2.edu/downloads/maven2' + } + dependencies { + def fopDeps = ['org.apache.xmlgraphics:fop:0.95-1@jar', + 'org.apache.xmlgraphics:xmlgraphics-commons:1.3', + 'org.apache.xmlgraphics:batik-bridge:1.7@jar', + 'org.apache.xmlgraphics:batik-util:1.7@jar', + 'org.apache.xmlgraphics:batik-css:1.7@jar', + 'org.apache.xmlgraphics:batik-dom:1.7', + 'org.apache.xmlgraphics:batik-svg-dom:1.7@jar', + 'org.apache.avalon.framework:avalon-framework-api:4.3.1'] + + classpath 'org.apache.xerces:resolver:2.9.1', + 'saxon:saxon:6.5.3', + 'org.apache.xerces:xercesImpl:2.9.1', + fopDeps, + 'net.sf.xslthl:xslthl:2.0.1', + 'net.sf.docbook:docbook-xsl:1.75.2:resources@zip' + } + +} + +/** + * Gradle Docbook plugin implementation. + *

+ * Creates three tasks: docbookHtml, docbookHtmlSingle and docbookPdf. + * Each task takes a single File on which it operates. + * + * @author ltaylor + */ +// Add the plugin tasks to the project +task docbookHtml(type: DocbookHtml) { + setDescription('Generates chunked docbook html output.') + xdir = 'html' + classpath = buildscript.configurations.classpath +} + +task docbookHtmlSingle(type: Docbook) { + setDescription('Generates single page docbook html output.') + xdir = 'htmlsingle' + classpath = buildscript.configurations.classpath +} + +task docbookPdf(type: DocbookFoPdf) { + setDescription('Generates PDF docbook output.') + extension = 'fo' + xdir = 'pdf' + classpath = buildscript.configurations.classpath +} + +/** + */ +public class Docbook extends DefaultTask { + @Input + String extension = 'html'; + + @Input + boolean XIncludeAware = true; + + @Input + boolean highlightingEnabled = true; + + String admonGraphicsPath; + + @InputDirectory + File sourceDirectory = new File(project.getProjectDir(), "build/reference-work"); + + @Input + String sourceFileName; + + @InputFile + File stylesheet; + + @OutputDirectory + File docsDir = new File(project.getBuildDir(), "reference"); + + @InputFiles + Configuration classpath + + @TaskAction + public final void transform() { + // the docbook tasks issue spurious content to the console. redirect to INFO level + // so it doesn't show up in the default log level of LIFECYCLE unless the user has + // run gradle with '-d' or '-i' switches -- in that case show them everything + switch (project.gradle.startParameter.logLevel) { + case LogLevel.DEBUG: + case LogLevel.INFO: + break; + default: + logging.captureStandardOutput(LogLevel.INFO) + logging.captureStandardError(LogLevel.INFO) + } + + SAXParserFactory factory = new org.apache.xerces.jaxp.SAXParserFactoryImpl(); + factory.setXIncludeAware(XIncludeAware); + docsDir.mkdirs(); + + File srcFile = new File(sourceDirectory, sourceFileName); + String outputFilename = srcFile.getName().substring(0, srcFile.getName().length() - 4) + '.' + extension; + + File oDir = new File(getDocsDir(), xdir) + File outputFile = new File(oDir, outputFilename); + + Result result = new StreamResult(outputFile.getAbsolutePath()); + CatalogResolver resolver = new CatalogResolver(createCatalogManager()); + InputSource inputSource = new InputSource(srcFile.getAbsolutePath()); + + XMLReader reader = factory.newSAXParser().getXMLReader(); + reader.setEntityResolver(resolver); + TransformerFactory transformerFactory = new TransformerFactoryImpl(); + transformerFactory.setURIResolver(resolver); + URL url = stylesheet.toURL(); + Source source = new StreamSource(url.openStream(), url.toExternalForm()); + Transformer transformer = transformerFactory.newTransformer(source); + + if (highlightingEnabled) { + File highlightingDir = new File(getProject().getBuildDir(), "highlighting"); + if (!highlightingDir.exists()) { + highlightingDir.mkdirs(); + extractHighlightFiles(highlightingDir); + } + + transformer.setParameter("highlight.xslthl.config", new File(highlightingDir, "xslthl-config.xml").toURI().toURL()); + + if (admonGraphicsPath != null) { + transformer.setParameter("admon.graphics", "1"); + transformer.setParameter("admon.graphics.path", admonGraphicsPath); + } + } + + preTransform(transformer, srcFile, outputFile); + + transformer.transform(new SAXSource(reader, inputSource), result); + + postTransform(outputFile); + } + + private void extractHighlightFiles(File toDir) { + File docbookZip = classpath.files.find { file -> file.name.contains('docbook-xsl-')}; + + if (docbookZip == null) { + throw new GradleException("Docbook zip file not found"); + } + + ZipFile zipFile = new ZipFile(docbookZip); + + Enumeration e = zipFile.entries(); + while (e.hasMoreElements()) { + ZipEntry ze = (ZipEntry) e.nextElement(); + if (ze.getName().matches(".*/highlighting/.*\\.xml")) { + String filename = ze.getName().substring(ze.getName().lastIndexOf("/highlighting/") + 14); + copyFile(zipFile.getInputStream(ze), new File(toDir, filename)); + } + } + } + + private void copyFile(InputStream source, File destFile) { + destFile.createNewFile(); + FileOutputStream to = null; + try { + to = new FileOutputStream(destFile); + byte[] buffer = new byte[4096]; + int bytesRead; + + while ((bytesRead = source.read(buffer)) > 0) { + to.write(buffer, 0, bytesRead); + } + } finally { + if (source != null) { + source.close(); + } + if (to != null) { + to.close(); + } + } + } + + protected void preTransform(Transformer transformer, File sourceFile, File outputFile) { + } + + protected void postTransform(File outputFile) { + } + + private CatalogManager createCatalogManager() { + CatalogManager manager = new CatalogManager(); + manager.setIgnoreMissingProperties(true); + ClassLoader classLoader = this.getClass().getClassLoader(); + StringBuilder builder = new StringBuilder(); + String docbookCatalogName = "docbook/catalog.xml"; + URL docbookCatalog = classLoader.getResource(docbookCatalogName); + + if (docbookCatalog == null) { + throw new IllegalStateException("Docbook catalog " + docbookCatalogName + " could not be found in " + classLoader); + } + + builder.append(docbookCatalog.toExternalForm()); + + Enumeration enumeration = classLoader.getResources("/catalog.xml"); + while (enumeration.hasMoreElements()) { + builder.append(';'); + URL resource = (URL) enumeration.nextElement(); + builder.append(resource.toExternalForm()); + } + String catalogFiles = builder.toString(); + manager.setCatalogFiles(catalogFiles); + return manager; + } +} + +/** + */ +class DocbookHtml extends Docbook { + + @Override + protected void preTransform(Transformer transformer, File sourceFile, File outputFile) { + String rootFilename = outputFile.getName(); + rootFilename = rootFilename.substring(0, rootFilename.lastIndexOf('.')); + transformer.setParameter("root.filename", rootFilename); + transformer.setParameter("base.dir", outputFile.getParent() + File.separator); + } +} + +/** + */ +class DocbookFoPdf extends Docbook { + + /** + * From the FOP usage guide + */ + @Override + protected void postTransform(File foFile) { + FopFactory fopFactory = FopFactory.newInstance(); + + OutputStream out = null; + final File pdfFile = getPdfOutputFile(foFile); + logger.debug("Transforming 'fo' file " + foFile + " to PDF: " + pdfFile); + + try { + out = new BufferedOutputStream(new FileOutputStream(pdfFile)); + + Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out); + + TransformerFactory factory = TransformerFactory.newInstance(); + Transformer transformer = factory.newTransformer(); + + Source src = new StreamSource(foFile); + + Result res = new SAXResult(fop.getDefaultHandler()); + + switch (project.gradle.startParameter.logLevel) { + case LogLevel.DEBUG: + case LogLevel.INFO: + break; + default: + // only show verbose fop output if the user has specified 'gradle -d' or 'gradle -i' + LoggerFactory.getILoggerFactory().getLogger('org.apache.fop').level = Level.ERROR + } + + transformer.transform(src, res); + + } finally { + if (out != null) { + out.close(); + } + } + + if (!foFile.delete()) { + logger.warn("Failed to delete 'fo' file " + foFile); + } + } + + private File getPdfOutputFile(File foFile) { + String name = foFile.getAbsolutePath(); + return new File(name.substring(0, name.length() - 2) + "pdf"); + } +} diff --git a/gradle/maven-deployment.gradle b/gradle/maven-deployment.gradle new file mode 100644 index 000000000..224435570 --- /dev/null +++ b/gradle/maven-deployment.gradle @@ -0,0 +1,113 @@ +/* + * 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. + */ + +// ----------------------------------------------------------------------------- +// Tasks related to deploying Maven artifacts. +// +// @author cbeams +// ----------------------------------------------------------------------------- + +// check that upload-related properties are defined and fail early if not +// these properties ("s3AccessKey", etc) should be defined in +// "gradle.properties" in $HOME/.gradle/gradle.properties +def requiredProps = version =~ "([0-9\\.]+)\\.M(.+)" ? ["mavenSyncRepoDir"] : ["s3AccessKey", + "s3SecretAccessKey"] +checkForProps(taskPath: project.path + ":uploadArchives", requiredProps: requiredProps) + +/** + * Builds a source jar artifact for all main java sources. + * + * @author ltaylor + */ +task sourceJar(type: Jar) { + description = "Builds a source jar artifact suitable for maven deployment." + classifier = "sources" + from sourceSets.main.java +} +build.dependsOn sourceJar + +// Add the source jar archive to the set of artifacts for this project. +// Note that the regular "jar" archive is already added by default. +artifacts { + archives sourceJar +} + +/** + * Deploy gradle-built artifacts to a remote maven repository. Overrides and + * further customizes the "uploadArchives" task contributed by the "maven" + * plugin. + * + * The repository that artifacts are deployed to is determined conditionally + * based on the release type of the project version. Snapshot builds will + * be deployed via s3 to the springframework maven snapshot repository; + * milestone builds will happen via s3 as well; release builds will be deployed + * to the local filesystem to be sync"d via sourceforge CVS and ultimately + * deployed to maven central. + * + * Gradle will generate Maven poms on-the-fly during the deployment process. + * This process is customized to add ASL license information, and for projects + * that have the erlangLicense property set to true, the Erlang License will be + * added to the pom as well. + * + * @author cbeams + * @see "mavenSyncRepoDir" in gradle.properties + * @see `gradle install` for deploying artifacts to the local .m2 cache + * @see + */ +uploadArchives { + group = "Buildmaster" + description = "Does a maven deploy of archives artifacts to " // url appended below + + def releaseRepositoryUrl = "file://${project.properties.mavenSyncRepoDir}" + def milestoneRepositoryUrl = "s3://maven.springframework.org/milestone" + def snapshotRepositoryUrl = "s3://maven.springframework.org/snapshot" + + // add a configuration with a classpath that includes our s3 maven deployer + configurations { deployerJars } + dependencies { + deployerJars "org.springframework.build.aws:org.springframework.build.aws.maven:3.0.0.RELEASE" + } + + repositories.mavenDeployer { + s3credentials = [userName: project.properties.s3AccessKey, passphrase: project.properties.s3SecretAccessKey] + if (version.endsWith("GA")) { + repository url: releaseRepositoryUrl + description += releaseRepositoryUrl + } else if (version.endsWith("M[0-9]")) { + description += milestoneRepositoryUrl + configuration = configurations.deployerJars + repository(url: milestoneRepositoryUrl) { + authentication(s3credentials) + } + } else if (version.endsWith("SNAPSHOT")) { + description += snapshotRepositoryUrl + configuration = configurations.deployerJars + snapshotRepository(url: snapshotRepositoryUrl) { + authentication(s3credentials) + } + } + } + + pom.project { + licenses { + license { + name "The Apache Software License, Version 2.0" + url "http://www.apache.org/licenses/LICENSE-2.0.txt" + distribution "repo" + } + } + } +}