You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2013/09/08 20:46:34 UTC
svn commit: r1520895 - in /httpcomponents/project-release-tools/trunk: ./
buildSrc/src/main/groovy/
Author: olegk
Date: Sun Sep 8 18:46:33 2013
New Revision: 1520895
URL: http://svn.apache.org/r1520895
Log:
Added release and RC tag management tasks
Added:
httpcomponents/project-release-tools/trunk/build.gradle
httpcomponents/project-release-tools/trunk/buildSrc/src/main/groovy/MvnWrapperPlugin.groovy
httpcomponents/project-release-tools/trunk/buildSrc/src/main/groovy/Release.groovy
- copied, changed from r1520537, httpcomponents/project-release-tools/trunk/buildSrc/src/main/groovy/UpgradeVersion.groovy
Removed:
httpcomponents/project-release-tools/trunk/buildSrc/src/main/groovy/ReleaseTag.groovy
httpcomponents/project-release-tools/trunk/buildSrc/src/main/groovy/UpgradeVersion.groovy
Modified:
httpcomponents/project-release-tools/trunk/.gitignore
httpcomponents/project-release-tools/trunk/buildSrc/src/main/groovy/Svn.groovy
Modified: httpcomponents/project-release-tools/trunk/.gitignore
URL: http://svn.apache.org/viewvc/httpcomponents/project-release-tools/trunk/.gitignore?rev=1520895&r1=1520894&r2=1520895&view=diff
==============================================================================
--- httpcomponents/project-release-tools/trunk/.gitignore (original)
+++ httpcomponents/project-release-tools/trunk/.gitignore Sun Sep 8 18:46:33 2013
@@ -5,3 +5,4 @@ build
*.iml
out
gradle.properties
+gradle-app.setting
Added: httpcomponents/project-release-tools/trunk/build.gradle
URL: http://svn.apache.org/viewvc/httpcomponents/project-release-tools/trunk/build.gradle?rev=1520895&view=auto
==============================================================================
--- httpcomponents/project-release-tools/trunk/build.gradle (added)
+++ httpcomponents/project-release-tools/trunk/build.gradle Sun Sep 8 18:46:33 2013
@@ -0,0 +1,188 @@
+/*
+ * ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+apply plugin: MvnWrapperPlugin
+
+/////////////////////////// Release current state /////////////////////////////
+
+Console console = System.console()
+if (!console) {
+ throw new IllegalStateException("Console not available")
+}
+
+File devRepoFile = new File(project.buildDir, 'dev-repo.txt')
+URI devRepo = devRepoFile.exists() ? new URI(devRepoFile.text) : null
+
+File releaseVerFile = new File(project.buildDir, 'release-ver.txt')
+String releaseVer = releaseVerFile.exists() ? releaseVerFile.text : null
+
+File releaseTagFile = new File(project.buildDir, 'release-tag.txt')
+URI releaseTag = releaseTagFile.exists() ? new URI(releaseTagFile.text) : null
+
+File rcQualifierFile = new File(project.buildDir, 'rc-qualifier.txt')
+String rcQualifier = rcQualifierFile.exists() ? rcQualifierFile.text : null
+
+File rcTagFile = new File(project.buildDir, 'rc-tag.txt')
+URI rcTag = rcTagFile.exists() ? new URI(rcTagFile.text) : null
+
+/////////////////////////// Release tasks /////////////////////////////////////
+
+task startRelease() << {
+ console.println("Please enter development repository URL:")
+ String s = console.readLine()
+ if (!s) {
+ throw new InvalidUserDataException("Development repository URL is empty")
+ }
+ devRepo = new URI(s)
+ devRepoFile.text = devRepo.toASCIIString()
+
+ if (project.buildDir.exists()) {
+ GFileUtils.cleanDirectory(project.buildDir)
+ }
+}
+
+if (devRepo) {
+
+ task checkoutSnapshot(type: SvnGet) {
+ repo = devRepo
+ }
+
+ task prepareReleaseVersion(dependsOn: 'checkoutSnapshot') << {
+ if (!releaseVer) {
+ File pomFile = new File(checkoutSnapshot.localDir, 'pom.xml')
+ def pomModel = new XmlSlurper().parse(pomFile)
+ String ver = pomModel.version
+ if (ver.endsWith('-SNAPSHOT')) {
+ ver = ver - '-SNAPSHOT'
+ }
+ releaseVer = ver
+ }
+
+ console.println("Please enter release version: [defaults to ${releaseVer}]")
+ String s = console.readLine()
+ if (s) {
+ releaseVer = s
+ }
+ releaseVerFile.text = releaseVer
+
+ releaseTag = Release.rewriteAsReleaseTag(devRepo, releaseVer)
+ releaseTagFile.text = releaseTag.toASCIIString()
+
+ println "Release tag: ${releaseTag}"
+ }
+
+ task prepareReleasePoms(dependsOn: 'prepareReleaseVersion') << {
+ Release.rewritePom(checkoutSnapshot.localDir, releaseVer, releaseTag)
+ }
+
+ task prepareRCTag(dependsOn: 'prepareReleasePoms') << {
+ if (rcQualifier) {
+ def m = rcQualifier =~ 'RC(\\d)'
+ if (m.find()) {
+ int n = Integer.parseInt(m.group(1))
+ rcQualifier = 'RC' + (++n)
+ }
+ }
+ if (!rcQualifier) {
+ rcQualifier = 'RC1'
+ }
+
+ console.println("Please enter release candidate qualifier: [defaults to ${rcQualifier}]")
+ String s = console.readLine()
+ if (s) {
+ rcQualifier = s
+ }
+ rcQualifierFile.text = rcQualifier
+
+ rcTag = new URI(releaseTag.scheme, releaseTag.userInfo, releaseTag.host, releaseTag.port,
+ releaseTag.path + '-' + rcQualifier, null, null)
+ rcTagFile.text = rcTag.toASCIIString()
+
+ println "RC tag: ${rcTag}"
+ println "Please review local chageset at ${checkoutSnapshot.localDir}"
+
+ Svn.status(checkoutSnapshot.localDir)
+ }
+
+}
+
+if (rcTag) {
+
+ task checkoutRC(type: SvnGet) {
+ repo = rcTag
+ }
+
+ task buildRC(dependsOn: 'checkoutRC') << {
+ File pomFile = new File(checkoutRC.localDir, 'pom.xml')
+ def pomModel = new XmlSlurper().parse(pomFile)
+ String artifactId = pomModel.artifactId
+ String name = getProductName(artifactId)
+
+ println "Building ${name} ${releaseVer} based on ${rcQualifier}"
+ mvn.exec(checkoutRC.localDir, 'clean', 'install')
+ }
+
+ task promoteRC() << {
+ File pomFile = new File(checkoutRC.localDir, 'pom.xml')
+ def pomModel = new XmlSlurper().parse(pomFile)
+ String artifactId = pomModel.artifactId
+ String name = getProductName(artifactId)
+
+ println "Promoting ${name} ${releaseVer} ${rcQualifier } to official release"
+
+ println "Copying ${rcTag} to ${releaseTag}"
+ Svn.copyRemote(rcTag, releaseTag, "${name} ${releaseVer} release tag")
+ }
+
+ task prepareNextVersion() << {
+ String nextVer = Release.upgradeVersion(releaseVer)
+ console.println("Please enter new development version: [defaults to ${nextVer}]")
+ String s = console.readLine()
+ if (s) {
+ nextVer = s
+ }
+ if (!nextVer.endsWith('-SNAPSHOT')) {
+ nextVer = nextVer + '-SNAPSHOT'
+ }
+ Release.rewritePom(checkoutSnapshot.localDir, nextVer, devRepo)
+ println "New development version: ${nextVer}"
+ println "Please review local chageset at ${checkoutSnapshot.localDir}"
+ }
+
+}
+
+/////////////////////////// Helper utilities //////////////////////////////////
+
+static String getProductName(String artifactId) {
+ def projectMap = [
+ 'httpcomponents-core':'HttpCore',
+ 'httpcomponents-client':'HttpClient',
+ 'httpcomponents-asyncclient':'HttpAsyncClient'
+ ]
+ String s = projectMap[artifactId]
+ s ? s : artifactId
+}
Added: httpcomponents/project-release-tools/trunk/buildSrc/src/main/groovy/MvnWrapperPlugin.groovy
URL: http://svn.apache.org/viewvc/httpcomponents/project-release-tools/trunk/buildSrc/src/main/groovy/MvnWrapperPlugin.groovy?rev=1520895&view=auto
==============================================================================
--- httpcomponents/project-release-tools/trunk/buildSrc/src/main/groovy/MvnWrapperPlugin.groovy (added)
+++ httpcomponents/project-release-tools/trunk/buildSrc/src/main/groovy/MvnWrapperPlugin.groovy Sun Sep 8 18:46:33 2013
@@ -0,0 +1,52 @@
+/*
+ * ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+import org.gradle.api.InvalidUserDataException
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+
+/**
+ * This plugin adds the following extensions to the project model:
+ *
+ * 'mvn' - Maven wrapper
+ */
+class MvnWrapperPlugin implements Plugin<Project> {
+
+ void apply(Project project) {
+ String MAVEN_HOME = project.getProperties().get('MAVEN_HOME')
+ if (!MAVEN_HOME) {
+ throw new InvalidUserDataException("MAVEN_HOME not set")
+ }
+ File mvnHomeDir = new File(MAVEN_HOME)
+ if (!mvnHomeDir.exists()) {
+ throw new InvalidUserDataException("Maven not found at ${mvnHomeDir}")
+ }
+ Mvn mvn = new Mvn(project, mvnHomeDir)
+ project.extensions.add('mvn', mvn)
+ }
+
+}
Copied: httpcomponents/project-release-tools/trunk/buildSrc/src/main/groovy/Release.groovy (from r1520537, httpcomponents/project-release-tools/trunk/buildSrc/src/main/groovy/UpgradeVersion.groovy)
URL: http://svn.apache.org/viewvc/httpcomponents/project-release-tools/trunk/buildSrc/src/main/groovy/Release.groovy?p2=httpcomponents/project-release-tools/trunk/buildSrc/src/main/groovy/Release.groovy&p1=httpcomponents/project-release-tools/trunk/buildSrc/src/main/groovy/UpgradeVersion.groovy&r1=1520537&r2=1520895&rev=1520895&view=diff
==============================================================================
--- httpcomponents/project-release-tools/trunk/buildSrc/src/main/groovy/UpgradeVersion.groovy (original)
+++ httpcomponents/project-release-tools/trunk/buildSrc/src/main/groovy/Release.groovy Sun Sep 8 18:46:33 2013
@@ -39,32 +39,10 @@ import org.jdom2.output.XMLOutputter
import java.util.regex.Matcher
-class UpgradeVersion extends DefaultTask {
+class Release {
- File location
-
- @TaskAction
- void generate() {
- if (!location || !location.exists()) {
- return
- }
- rewritePom(location)
- }
-
- private void rewritePom(File dir) {
- File pomFile = new File(dir, 'pom.xml')
- SAXBuilder parser = new SAXBuilder()
-
- Namespace ns = Namespace.getNamespace("http://maven.apache.org/POM/4.0.0")
-
- Document maindoc = parser.build(pomFile)
-
- Element rootEl = maindoc.rootElement
- Element versionEl = rootEl.getChild('version', ns)
- if (!versionEl) {
- throw new InvalidUserDataException("Version not specified")
- }
- ArtifactVersion ver = new DefaultArtifactVersion(versionEl.text)
+ static String upgradeVersion(String version) {
+ ArtifactVersion ver = new DefaultArtifactVersion(version)
int major = ver.majorVersion
int minor = ver.minorVersion
int patch = ver.incrementalVersion
@@ -98,20 +76,52 @@ class UpgradeVersion extends DefaultTask
buf.append('-').append(qualifier)
}
buf.append('-SNAPSHOT')
- String newVer = buf.toString()
+ buf.toString()
+ }
- Console console = System.console()
- if (!console) {
- throw new IllegalStateException("Console not available")
+ static URI rewriteAsReleaseTag(URI uri, String ver) {
+ String path = uri.path
+ Matcher m1 = path =~ '(.*)/trunk'
+ if (m1.find()) {
+ path = m1.group(1) + '/' + 'tags/' + ver
+ } else {
+ Matcher m2 = path =~ '(.*)/branches/[A-Za-z0-9_\\-\\.]'
+ if (m2.find()) {
+ path = m2.group(1) + '/' + 'tags/' + ver
+ }
}
+ new URI(uri.scheme, uri.userInfo, uri.host, uri.port, path, null, null)
+ }
+
+ static void rewritePom(File dir, String version, URI repoUrl) {
+ File pomFile = new File(dir, 'pom.xml')
+ SAXBuilder parser = new SAXBuilder()
+
+ Namespace ns = Namespace.getNamespace("http://maven.apache.org/POM/4.0.0")
+
+ Document maindoc = parser.build(pomFile)
- console.println("Enter new project version [defaults to ${newVer}]:")
- String s = console.readLine()
- if (s) {
- newVer = s
+ Element rootEl = maindoc.rootElement
+ Element versionEl = rootEl.getChild('version', ns)
+ if (versionEl) {
+ versionEl.text = version
}
- versionEl.text = newVer
+ Element scmEl = rootEl.getChild('scm', ns)
+ if (scmEl) {
+ Element connectionEl = scmEl.getChild('connection', ns)
+ if (connectionEl) {
+ connectionEl.text = 'scm:svn:' + repoUrl.toASCIIString()
+ }
+ Element devConnectionEl = scmEl.getChild('developerConnection', ns)
+ if (devConnectionEl) {
+ devConnectionEl.text = 'scm:svn:' + repoUrl.toASCIIString()
+ }
+ Element urlEl = scmEl.getChild('url', ns)
+ if (urlEl) {
+ urlEl.text = repoUrl.toASCIIString()
+ }
+ }
Format format = Format.getRawFormat()
format.lineSeparator = Line.DELIM
@@ -127,27 +137,20 @@ class UpgradeVersion extends DefaultTask
if (moduleParentEl) {
Element moduleVersionEl = moduleParentEl.getChild('version', ns)
if (moduleVersionEl) {
- moduleVersionEl.text = newVer
+ moduleVersionEl.text = version
}
}
XMLOutputter xmlOutputter = new XMLOutputter(format)
- Writer writer = modulePomFile.newWriter('UTF-8')
- try {
+ modulePomFile.withWriter('UTF-8') { Writer writer ->
xmlOutputter.output(doc, writer)
- } finally {
- writer.close()
}
}
}
XMLOutputter xmlOutputter = new XMLOutputter(format)
- Writer writer = pomFile.newWriter('UTF-8')
- try {
+ pomFile.withWriter('UTF-8') { Writer writer ->
xmlOutputter.output(maindoc, writer)
- } finally {
- writer.close()
}
-
}
}
Modified: httpcomponents/project-release-tools/trunk/buildSrc/src/main/groovy/Svn.groovy
URL: http://svn.apache.org/viewvc/httpcomponents/project-release-tools/trunk/buildSrc/src/main/groovy/Svn.groovy?rev=1520895&r1=1520894&r2=1520895&view=diff
==============================================================================
--- httpcomponents/project-release-tools/trunk/buildSrc/src/main/groovy/Svn.groovy (original)
+++ httpcomponents/project-release-tools/trunk/buildSrc/src/main/groovy/Svn.groovy Sun Sep 8 18:46:33 2013
@@ -33,11 +33,15 @@ import org.tmatesoft.svn.core.SVNExcepti
import org.tmatesoft.svn.core.SVNURL
import org.tmatesoft.svn.core.internal.wc17.SVNWCContext
import org.tmatesoft.svn.core.internal.wc2.compat.SvnCodec
+import org.tmatesoft.svn.core.wc.SVNRevision
import org.tmatesoft.svn.core.wc.SVNWCUtil
import org.tmatesoft.svn.core.wc2.ISvnObjectReceiver
import org.tmatesoft.svn.core.wc2.SvnCheckout
+import org.tmatesoft.svn.core.wc2.SvnCopy
+import org.tmatesoft.svn.core.wc2.SvnCopySource
import org.tmatesoft.svn.core.wc2.SvnGetStatus
import org.tmatesoft.svn.core.wc2.SvnOperationFactory
+import org.tmatesoft.svn.core.wc2.SvnRemoteCopy
import org.tmatesoft.svn.core.wc2.SvnScheduleForAddition
import org.tmatesoft.svn.core.wc2.SvnStatus
import org.tmatesoft.svn.core.wc2.SvnTarget
@@ -128,4 +132,38 @@ class Svn {
}
}
+ static void copyLocal(File dir, URI dst, String message) {
+ SVNCommandEnvironment env = getSVNCommandEnvironment()
+ SvnOperationFactory opfactory = createOperationFactory(env)
+ try {
+ SvnRemoteCopy copyOp = opfactory.createRemoteCopy()
+ copyOp.addCopySource(
+ SvnCopySource.create(SvnTarget.fromFile(dir), SVNRevision.WORKING))
+ copyOp.setSingleTarget(SvnTarget.fromURL(SVNURL.parseURIEncoded(dst.toASCIIString())))
+ copyOp.setFailWhenDstExists(true)
+ copyOp.setDisableLocalModifications(false)
+ copyOp.setCommitMessage(message)
+ copyOp.run()
+ } finally {
+ opfactory.dispose()
+ }
+ }
+
+ static void copyRemote(URI src, URI dst, String message) {
+ SVNCommandEnvironment env = getSVNCommandEnvironment()
+ SvnOperationFactory opfactory = createOperationFactory(env)
+ try {
+ SvnRemoteCopy copyOp = opfactory.createRemoteCopy()
+ copyOp.addCopySource(
+ SvnCopySource.create(SvnTarget.fromURL(
+ SVNURL.parseURIEncoded(src.toASCIIString())), SVNRevision.HEAD))
+ copyOp.setSingleTarget(SvnTarget.fromURL(SVNURL.parseURIEncoded(dst.toASCIIString())))
+ copyOp.setFailWhenDstExists(true)
+ copyOp.setCommitMessage(message)
+ copyOp.run()
+ } finally {
+ opfactory.dispose()
+ }
+ }
+
}