You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ev...@apache.org on 2007/05/03 16:41:46 UTC

svn commit: r534893 - in /maven/release/trunk: maven-release-manager/src/main/java/org/apache/maven/shared/release/ maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/ maven-release-manager/src/main/java/org/apache/maven/shared/r...

Author: evenisse
Date: Thu May  3 07:41:44 2007
New Revision: 534893

URL: http://svn.apache.org/viewvc?view=rev&rev=534893
Log:
[MRELEASE-179] Add release:branch mojo. This mojo create a branch of the current code, ask for versions branch (default is the current versions) then ask for current code versions (default is next snapshots)

Added:
    maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/RewritePomsForBranchPhase.java   (with props)
    maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/ScmBranchPhase.java   (with props)
    maven/release/trunk/maven-release-plugin/src/main/java/org/apache/maven/plugins/release/BranchReleaseMojo.java   (with props)
Modified:
    maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/DefaultReleaseManager.java
    maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/ReleaseManager.java
    maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/MapVersionsPhase.java
    maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/scm/ClearCaseScmTranslator.java
    maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/scm/CvsScmTranslator.java
    maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/scm/ScmTranslator.java
    maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/scm/SubversionScmTranslator.java
    maven/release/trunk/maven-release-manager/src/main/resources/META-INF/plexus/components.xml

Modified: maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/DefaultReleaseManager.java
URL: http://svn.apache.org/viewvc/maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/DefaultReleaseManager.java?view=diff&rev=534893&r1=534892&r2=534893
==============================================================================
--- maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/DefaultReleaseManager.java (original)
+++ maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/DefaultReleaseManager.java Thu May  3 07:41:44 2007
@@ -60,6 +60,11 @@
     private List rollbackPhases;
 
     /**
+     * The phases to create a branch.
+     */
+    private List branchPhases;
+
+    /**
      * The available phases.
      */
     private Map releasePhases;
@@ -321,6 +326,49 @@
         updateListener( listener, "perform", GOAL_END );
     }
 
+    public void branch( ReleaseDescriptor releaseDescriptor, Settings settings, List reactorProjects, boolean dryRun )
+        throws ReleaseExecutionException, ReleaseFailureException
+    {
+        branch( releaseDescriptor, settings, reactorProjects, dryRun, null );
+    }
+
+    public void branch( ReleaseDescriptor releaseDescriptor, Settings settings, List reactorProjects, boolean dryRun,
+                        ReleaseManagerListener listener )
+        throws ReleaseExecutionException, ReleaseFailureException
+    {
+        updateListener( listener, "branch", GOAL_START );
+
+        releaseDescriptor = loadReleaseDescriptor( releaseDescriptor, listener );
+
+        for ( Iterator phases = branchPhases.iterator(); phases.hasNext(); )
+        {
+            String name = (String) phases.next();
+
+            ReleasePhase phase = (ReleasePhase) releasePhases.get( name );
+
+            if ( phase == null )
+            {
+                throw new ReleaseExecutionException( "Unable to find phase '" + name + "' to execute" );
+            }
+
+            updateListener( listener, name, PHASE_START );
+            if ( dryRun )
+            {
+                phase.simulate( releaseDescriptor, settings, reactorProjects );
+            }
+            else
+            {
+                phase.execute( releaseDescriptor, settings, reactorProjects );
+            }
+            updateListener( listener, name, PHASE_END );
+        }
+
+        //call release:clean so that resume will not be possible anymore after a perform
+        clean( releaseDescriptor, listener, reactorProjects );
+
+        updateListener( listener, "branch", GOAL_END );
+    }
+
     /**
      * Determines the path of the working directory. By default, this is the
      * checkout directory. For some SCMs, the project root directory is not the
@@ -429,6 +477,10 @@
         else if ( "rollback".equals( name ) )
         {
             phases.addAll( this.rollbackPhases );
+        }
+        else if ( "branch".equals( name ) )
+        {
+            phases.addAll( this.branchPhases );
         }
 
         return Collections.unmodifiableList( phases );

Modified: maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/ReleaseManager.java
URL: http://svn.apache.org/viewvc/maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/ReleaseManager.java?view=diff&rev=534893&r1=534892&r2=534893
==============================================================================
--- maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/ReleaseManager.java (original)
+++ maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/ReleaseManager.java Thu May  3 07:41:44 2007
@@ -64,6 +64,25 @@
         throws ReleaseExecutionException, ReleaseFailureException;
 
     /**
+     * Prepare a release.
+     *
+     * @param releaseDescriptor the configuration to pass to the preparation steps
+     * @param settings          the settings.xml configuration
+     * @param reactorProjects   the reactor projects
+     * @param resume            resume a previous release, if the properties file exists
+     * @param dryRun            do not commit any changes to the file system or SCM
+     * @param listener          the listener
+     * @throws ReleaseExecutionException if there is a problem performing the release
+     * @throws ReleaseFailureException   if there is a problem performing the release
+     */
+    void prepare( ReleaseDescriptor releaseDescriptor, Settings settings, List reactorProjects, boolean resume,
+                  boolean dryRun, ReleaseManagerListener listener )
+        throws ReleaseExecutionException, ReleaseFailureException;
+
+    ReleaseResult prepareWithResult( ReleaseDescriptor releaseDescriptor, Settings settings, List reactorProjects,
+                                     boolean resume, boolean dryRun, ReleaseManagerListener listener );
+
+    /**
      * Perform a release.
      *
      * @param releaseDescriptor the configuration to use for release
@@ -76,6 +95,23 @@
         throws ReleaseExecutionException, ReleaseFailureException;
 
     /**
+     * Perform a release.
+     *
+     * @param releaseDescriptor the configuration to use for release
+     * @param settings          the settings.xml configuration
+     * @param reactorProjects   the reactor projects
+     * @param listener          the listener
+     * @throws ReleaseExecutionException if there is a problem performing the release
+     * @throws ReleaseFailureException   if there is a problem performing the release
+     */
+    void perform( ReleaseDescriptor releaseDescriptor, Settings settings, List reactorProjects,
+                  ReleaseManagerListener listener )
+        throws ReleaseExecutionException, ReleaseFailureException;
+
+    ReleaseResult performWithResult( ReleaseDescriptor releaseDescriptor, Settings settings, List reactorProjects,
+                                     ReleaseManagerListener listener );
+
+    /**
      * Clean a release.
      *
      * @param releaseDescriptor the configuration to use for release
@@ -95,21 +131,45 @@
     void rollback( ReleaseDescriptor releaseDescriptor, Settings settings, List reactorProjects )
         throws ReleaseExecutionException, ReleaseFailureException;
 
+    /**
+     * Rollback changes made by the previous release
+     *
+     * @param releaseDescriptor the configuration to use for release
+     * @param settings          the settings.xml configuration
+     * @param reactorProjects   the reactor projects
+     * @param listener          the listener
+     * @throws ReleaseExecutionException if there is a problem during release rollback
+     * @throws ReleaseFailureException   if there is a problem during release rollback
+     */
     void rollback( ReleaseDescriptor releaseDescriptor, Settings settings, List reactorProjects,
                    ReleaseManagerListener listener )
         throws ReleaseExecutionException, ReleaseFailureException;
 
-    void prepare( ReleaseDescriptor releaseDescriptor, Settings settings, List reactorProjects, boolean resume,
-                  boolean dryRun, ReleaseManagerListener listener )
+    /**
+     * Branch a project
+     *
+     * @param releaseDescriptor the configuration to use for release
+     * @param settings          the settings.xml configuration
+     * @param reactorProjects   the reactor projects
+     * @param dryRun            do not commit any changes to the file system or SCM
+     * @throws ReleaseExecutionException if there is a problem during release rollback
+     * @throws ReleaseFailureException   if there is a problem during release rollback
+     */
+    void branch( ReleaseDescriptor releaseDescriptor, Settings settings, List reactorProjects, boolean dryRun )
         throws ReleaseExecutionException, ReleaseFailureException;
 
-    ReleaseResult prepareWithResult( ReleaseDescriptor releaseDescriptor, Settings settings, List reactorProjects,
-                                     boolean resume, boolean dryRun, ReleaseManagerListener listener );
-
-    void perform( ReleaseDescriptor releaseDescriptor, Settings settings, List reactorProjects,
-                  ReleaseManagerListener listener )
+    /**
+     * Branch a project
+     *
+     * @param releaseDescriptor the configuration to use for release
+     * @param settings          the settings.xml configuration
+     * @param reactorProjects   the reactor projects
+     * @param dryRun            do not commit any changes to the file system or SCM
+     * @param listener          the listener
+     * @throws ReleaseExecutionException if there is a problem during release rollback
+     * @throws ReleaseFailureException   if there is a problem during release rollback
+     */
+    void branch( ReleaseDescriptor releaseDescriptor, Settings settings, List reactorProjects, boolean dryRun,
+                 ReleaseManagerListener listener )
         throws ReleaseExecutionException, ReleaseFailureException;
-
-    ReleaseResult performWithResult( ReleaseDescriptor releaseDescriptor, Settings settings, List reactorProjects,
-                                     ReleaseManagerListener listener );
 }

Modified: maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/MapVersionsPhase.java
URL: http://svn.apache.org/viewvc/maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/MapVersionsPhase.java?view=diff&rev=534893&r1=534892&r2=534893
==============================================================================
--- maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/MapVersionsPhase.java (original)
+++ maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/MapVersionsPhase.java Thu May  3 07:41:44 2007
@@ -50,6 +50,11 @@
     private boolean convertToSnapshot;
 
     /**
+     * Whether to convert to a snapshot or a release.
+     */
+    private boolean convertToBranch;
+
+    /**
      * Component used to prompt for input.
      */
     private Prompter prompter;
@@ -75,10 +80,14 @@
 
             String nextVersion = getNextVersion( project, projectId, releaseDescriptor, result );
 
-            if ( convertToSnapshot )
+            if ( convertToSnapshot && !convertToBranch )
             {
                 releaseDescriptor.mapDevelopmentVersion( projectId, nextVersion );
             }
+            else if ( convertToSnapshot && convertToBranch )
+            {
+                releaseDescriptor.mapDevelopmentVersion( projectId, project.getVersion() );
+            }
             else
             {
                 releaseDescriptor.mapReleaseVersion( projectId, nextVersion );
@@ -89,10 +98,14 @@
                 MavenProject subProject = (MavenProject) i.next();
                 String subProjectId =
                     ArtifactUtils.versionlessKey( subProject.getGroupId(), subProject.getArtifactId() );
-                if ( convertToSnapshot )
+                if ( convertToSnapshot && !convertToBranch )
                 {
                     releaseDescriptor.mapDevelopmentVersion( subProjectId, nextVersion );
                 }
+                else if ( convertToSnapshot && convertToBranch )
+                {
+                    releaseDescriptor.mapReleaseVersion( subProjectId, subProject.getVersion() );
+                }
                 else
                 {
                     releaseDescriptor.mapReleaseVersion( subProjectId, nextVersion );
@@ -109,10 +122,21 @@
 
                 String nextVersion = getNextVersion( project, projectId, releaseDescriptor, result );
 
-                if ( convertToSnapshot )
+                if ( convertToSnapshot && !convertToBranch)
                 {
                     releaseDescriptor.mapDevelopmentVersion( projectId, nextVersion );
                 }
+                else if ( convertToSnapshot && convertToBranch )
+                {
+                    if ( ArtifactUtils.isSnapshot( project.getVersion() ) )
+                    {
+                        releaseDescriptor.mapReleaseVersion( projectId, nextVersion );
+                    }
+                    else
+                    {
+                        releaseDescriptor.mapReleaseVersion( projectId, project.getVersion() );
+                    }
+                }
                 else
                 {
                     if ( ArtifactUtils.isSnapshot( project.getVersion() ) )
@@ -160,7 +184,7 @@
 
         try
         {
-            if ( convertToSnapshot )
+            if ( convertToSnapshot && !convertToBranch )
             {
                 if ( version != null )
                 {
@@ -188,6 +212,35 @@
                     {
                         nextVersion = devVersions.remove( projectId ).toString();
                     }
+                }
+            }
+            else if ( convertToSnapshot && convertToBranch )
+            {
+                if ( ArtifactUtils.isSnapshot( project.getVersion() ) )
+                {
+                    if ( version != null )
+                    {
+                        nextVersion = version.getSnapshotVersionString();
+                    }
+
+                    if ( releaseDescriptor.isInteractive() )
+                    {
+                        nextVersion = prompter.prompt(
+                            "What is the branch version for \"" + project.getName() + "\"? (" + projectId + ")",
+                            nextVersion );
+                    }
+                    else
+                    {
+                        Map relVersions = releaseDescriptor.getDevelopmentVersions();
+                        if ( relVersions.containsKey( projectId ) )
+                        {
+                            nextVersion = relVersions.remove( projectId ).toString();
+                        }
+                    }
+                }
+                else
+                {
+                    nextVersion = project.getVersion();
                 }
             }
             else

Added: maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/RewritePomsForBranchPhase.java
URL: http://svn.apache.org/viewvc/maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/RewritePomsForBranchPhase.java?view=auto&rev=534893
==============================================================================
--- maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/RewritePomsForBranchPhase.java (added)
+++ maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/RewritePomsForBranchPhase.java Thu May  3 07:41:44 2007
@@ -0,0 +1,202 @@
+package org.apache.maven.shared.release.phase;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.model.Scm;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.scm.repository.ScmRepository;
+import org.apache.maven.shared.release.ReleaseResult;
+import org.apache.maven.shared.release.config.ReleaseDescriptor;
+import org.apache.maven.shared.release.scm.ScmTranslator;
+import org.jdom.Element;
+import org.jdom.Namespace;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Rewrite POMs for branch.
+ *
+ * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
+ * @version $Id$
+ */
+public class RewritePomsForBranchPhase
+    extends AbstractRewritePomsPhase
+{
+    /**
+     * SCM URL translators mapped by provider name.
+     */
+    private Map scmTranslators;
+
+    protected void transformScm( MavenProject project, Element rootElement, Namespace namespace,
+                                 ReleaseDescriptor releaseDescriptor, String projectId, ScmRepository scmRepository,
+                                 ReleaseResult result, MavenProject rootProject )
+    {
+        // If SCM is null in original model, it is inherited, no mods needed
+        if ( project.getScm() != null )
+        {
+            Element scmRoot = rootElement.getChild( "scm", namespace );
+            if ( scmRoot != null )
+            {
+                releaseDescriptor.mapOriginalScmInfo( projectId, project.getScm() );
+
+                translateScm( project, releaseDescriptor, scmRoot, namespace, scmRepository, result, rootProject );
+            }
+            else
+            {
+                releaseDescriptor.mapOriginalScmInfo( projectId, null );
+
+                MavenProject parent = project.getParent();
+                if ( parent != null )
+                {
+                    // If the SCM element is not present, only add it if the parent was not mapped (ie, it's external to
+                    // the release process and so has not been modified, so the values will not be correct on the tag),
+                    String parentId = ArtifactUtils.versionlessKey( parent.getGroupId(), parent.getArtifactId() );
+                    if ( !releaseDescriptor.getOriginalScmInfo().containsKey( parentId ) )
+                    {
+                        // we need to add it, since it has changed from the inherited value
+                        scmRoot = new Element( "scm" );
+                        scmRoot.addContent( "\n  " );
+
+                        if ( translateScm( project, releaseDescriptor, scmRoot, namespace, scmRepository, result,
+                                           rootProject ) )
+                        {
+                            rootElement.addContent( "\n  " ).addContent( scmRoot ).addContent( "\n" );
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private boolean translateScm( MavenProject project, ReleaseDescriptor releaseDescriptor, Element scmRoot,
+                                  Namespace namespace, ScmRepository scmRepository, ReleaseResult relResult,
+                                  MavenProject rootProject )
+    {
+        ScmTranslator translator = (ScmTranslator) scmTranslators.get( scmRepository.getProvider() );
+        boolean result = false;
+        if ( translator != null )
+        {
+            Scm scm = project.getScm();
+            String branchName = releaseDescriptor.getScmReleaseLabel();
+            String branchBase = releaseDescriptor.getScmTagBase();
+            String subDirectoryBranch = "";
+
+            // TODO: svn utils should take care of prepending this
+            if ( branchBase != null )
+            {
+                branchBase = "scm:svn:" + branchBase;
+            }
+
+            Scm rootScm = rootProject.getScm();
+            if ( scm.getConnection() != null )
+            {
+                if ( rootScm.getConnection() != null && scm.getConnection().indexOf( rootScm.getConnection() ) == 0 )
+                {
+                    subDirectoryBranch = scm.getConnection().substring( rootScm.getConnection().length() );
+                }
+                String value =
+                    translator.translateBranchUrl( scm.getConnection(), branchName + subDirectoryBranch, branchBase );
+                if ( !value.equals( scm.getConnection() ) )
+                {
+                    rewriteElement( "connection", value, scmRoot, namespace );
+                    result = true;
+                }
+            }
+
+            if ( scm.getDeveloperConnection() != null )
+            {
+                if ( rootScm.getDeveloperConnection() != null &&
+                    scm.getDeveloperConnection().indexOf( rootScm.getDeveloperConnection() ) == 0 )
+                {
+                    subDirectoryBranch =
+                        scm.getDeveloperConnection().substring( rootScm.getDeveloperConnection().length() );
+                }
+                String value =
+                    translator.translateBranchUrl( scm.getDeveloperConnection(), branchName + subDirectoryBranch, branchBase );
+                if ( !value.equals( scm.getDeveloperConnection() ) )
+                {
+                    rewriteElement( "developerConnection", value, scmRoot, namespace );
+                    result = true;
+                }
+            }
+
+            if ( scm.getUrl() != null )
+            {
+                if ( rootScm.getUrl() != null && scm.getUrl().indexOf( rootScm.getUrl() ) == 0 )
+                {
+                    subDirectoryBranch = scm.getUrl().substring( rootScm.getUrl().length() );
+                }
+                // use original tag base without protocol
+                String value = translator.translateBranchUrl( scm.getUrl(), branchName + subDirectoryBranch,
+                                                           releaseDescriptor.getScmTagBase() );
+                if ( !value.equals( scm.getUrl() ) )
+                {
+                    rewriteElement( "url", value, scmRoot, namespace );
+                    result = true;
+                }
+            }
+
+            if ( branchName != null )
+            {
+                String value = translator.resolveTag( branchName );
+                if ( value != null && !value.equals( scm.getTag() ) )
+                {
+                    rewriteElement( "tag", value, scmRoot, namespace );
+                    result = true;
+                }
+            }
+        }
+        else
+        {
+            String message = "No SCM translator found - skipping rewrite";
+
+            relResult.appendDebug( message );
+
+            getLogger().debug( message );
+        }
+        return result;
+    }
+
+    protected Map getOriginalVersionMap( ReleaseDescriptor releaseDescriptor, List reactorProjects )
+    {
+        return releaseDescriptor.getOriginalVersions( reactorProjects );
+    }
+
+    protected Map getNextVersionMap( ReleaseDescriptor releaseDescriptor )
+    {
+        return releaseDescriptor.getReleaseVersions();
+    }
+
+    protected String getResolvedSnapshotVersion( String artifactVersionlessKey, Map resolvedSnapshotsMap )
+    {
+        Map versionsMap = (Map) resolvedSnapshotsMap.get( artifactVersionlessKey );
+
+        if ( versionsMap != null )
+        {
+            return (String) ( versionsMap.get( ReleaseDescriptor.RELEASE_KEY ) );
+        }
+        else
+        {
+            return null;
+        }
+    }
+}

Propchange: maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/RewritePomsForBranchPhase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/RewritePomsForBranchPhase.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/ScmBranchPhase.java
URL: http://svn.apache.org/viewvc/maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/ScmBranchPhase.java?view=auto&rev=534893
==============================================================================
--- maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/ScmBranchPhase.java (added)
+++ maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/ScmBranchPhase.java Thu May  3 07:41:44 2007
@@ -0,0 +1,129 @@
+package org.apache.maven.shared.release.phase;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.scm.ScmException;
+import org.apache.maven.scm.ScmFileSet;
+import org.apache.maven.scm.command.branch.BranchScmResult;
+import org.apache.maven.scm.manager.NoSuchScmProviderException;
+import org.apache.maven.scm.provider.ScmProvider;
+import org.apache.maven.scm.repository.ScmRepository;
+import org.apache.maven.scm.repository.ScmRepositoryException;
+import org.apache.maven.settings.Settings;
+import org.apache.maven.shared.release.ReleaseExecutionException;
+import org.apache.maven.shared.release.ReleaseFailureException;
+import org.apache.maven.shared.release.ReleaseResult;
+import org.apache.maven.shared.release.config.ReleaseDescriptor;
+import org.apache.maven.shared.release.scm.ReleaseScmCommandException;
+import org.apache.maven.shared.release.scm.ReleaseScmRepositoryException;
+import org.apache.maven.shared.release.scm.ScmRepositoryConfigurator;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Branch the SCM repository.
+ *
+ * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
+ * @plexus.component role="org.apache.maven.shared.release.phase.ReleasePhase" role-hint="scm-branch"
+ */
+public class ScmBranchPhase
+    extends AbstractReleasePhase
+{
+    /**
+     * Tool that gets a configured SCM repository from release configuration.
+     *
+     * @plexus.requirement
+     */
+    private ScmRepositoryConfigurator scmRepositoryConfigurator;
+
+    public ReleaseResult execute( ReleaseDescriptor releaseDescriptor, Settings settings, List reactorProjects )
+        throws ReleaseExecutionException, ReleaseFailureException
+    {
+        ReleaseResult relResult = new ReleaseResult();
+
+        validateConfiguration( releaseDescriptor );
+
+        logInfo( relResult, "Branching release with the label " + releaseDescriptor.getScmReleaseLabel() + "..." );
+
+        ScmRepository repository;
+        ScmProvider provider;
+        try
+        {
+            repository = scmRepositoryConfigurator.getConfiguredRepository( releaseDescriptor, settings );
+
+            provider = scmRepositoryConfigurator.getRepositoryProvider( repository );
+        }
+        catch ( ScmRepositoryException e )
+        {
+            throw new ReleaseScmRepositoryException( e.getMessage(), e.getValidationMessages() );
+        }
+        catch ( NoSuchScmProviderException e )
+        {
+            throw new ReleaseExecutionException( "Unable to configure SCM repository: " + e.getMessage(), e );
+        }
+
+        BranchScmResult result;
+        try
+        {
+            ScmFileSet fileSet = new ScmFileSet( new File( releaseDescriptor.getWorkingDirectory() ) );
+            String branchName = releaseDescriptor.getScmReleaseLabel();
+            result = provider.branch( repository, fileSet, branchName,
+                                      releaseDescriptor.getScmCommentPrefix() + " copy for branch " + branchName );
+        }
+        catch ( ScmException e )
+        {
+            throw new ReleaseExecutionException( "An error is occurred in the branch process: " + e.getMessage(), e );
+        }
+
+        if ( !result.isSuccess() )
+        {
+            throw new ReleaseScmCommandException( "Unable to branch SCM", result );
+        }
+
+        relResult.setResultCode( ReleaseResult.SUCCESS );
+
+        return relResult;
+    }
+
+    public ReleaseResult simulate( ReleaseDescriptor releaseDescriptor, Settings settings, List reactorProjects )
+        throws ReleaseExecutionException, ReleaseFailureException
+    {
+        ReleaseResult result = new ReleaseResult();
+
+        validateConfiguration( releaseDescriptor );
+
+        logInfo( result, "Full run would be branching " + releaseDescriptor.getWorkingDirectory() + " with label: '" +
+            releaseDescriptor.getScmReleaseLabel() + "'" );
+
+        result.setResultCode( ReleaseResult.SUCCESS );
+
+        return result;
+    }
+
+    private static void validateConfiguration( ReleaseDescriptor releaseDescriptor )
+        throws ReleaseFailureException
+    {
+        if ( releaseDescriptor.getScmReleaseLabel() == null )
+        {
+            throw new ReleaseFailureException( "A release label is required for committing" );
+        }
+    }
+}

Propchange: maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/ScmBranchPhase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/ScmBranchPhase.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/scm/ClearCaseScmTranslator.java
URL: http://svn.apache.org/viewvc/maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/scm/ClearCaseScmTranslator.java?view=diff&rev=534893&r1=534892&r2=534893
==============================================================================
--- maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/scm/ClearCaseScmTranslator.java (original)
+++ maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/scm/ClearCaseScmTranslator.java Thu May  3 07:41:44 2007
@@ -28,6 +28,11 @@
 public class ClearCaseScmTranslator
     implements ScmTranslator
 {
+    public String translateBranchUrl( String url, String branchName, String branchBase )
+    {
+        return url;
+    }
+
     public String translateTagUrl( String url, String tag, String tagBase )
     {
         return url;

Modified: maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/scm/CvsScmTranslator.java
URL: http://svn.apache.org/viewvc/maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/scm/CvsScmTranslator.java?view=diff&rev=534893&r1=534892&r2=534893
==============================================================================
--- maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/scm/CvsScmTranslator.java (original)
+++ maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/scm/CvsScmTranslator.java Thu May  3 07:41:44 2007
@@ -28,6 +28,11 @@
 public class CvsScmTranslator
     implements ScmTranslator
 {
+    public String translateBranchUrl( String url, String branchName, String branchBase )
+    {
+        return url;
+    }
+
     public String translateTagUrl( String url, String tag, String tagBase )
     {
         return url;

Modified: maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/scm/ScmTranslator.java
URL: http://svn.apache.org/viewvc/maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/scm/ScmTranslator.java?view=diff&rev=534893&r1=534892&r2=534893
==============================================================================
--- maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/scm/ScmTranslator.java (original)
+++ maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/scm/ScmTranslator.java Thu May  3 07:41:44 2007
@@ -33,6 +33,16 @@
     String ROLE = ScmTranslator.class.getName();
 
     /**
+     * Take an URL and find the correct replacement URL for a given branch.
+     *
+     * @param url        the source URL
+     * @param branchName the branch name
+     * @param branchBase the branch base for providers that support it
+     * @return the replacement URL
+     */
+    String translateBranchUrl( String url, String branchName, String branchBase );
+
+    /**
      * Take an URL and find the correct replacement URL for a given tag.
      *
      * @param url     the source URL

Modified: maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/scm/SubversionScmTranslator.java
URL: http://svn.apache.org/viewvc/maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/scm/SubversionScmTranslator.java?view=diff&rev=534893&r1=534892&r2=534893
==============================================================================
--- maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/scm/SubversionScmTranslator.java (original)
+++ maven/release/trunk/maven-release-manager/src/main/java/org/apache/maven/shared/release/scm/SubversionScmTranslator.java Thu May  3 07:41:44 2007
@@ -19,6 +19,7 @@
  * under the License.
  */
 
+import org.apache.maven.scm.ScmBranch;
 import org.apache.maven.scm.ScmTag;
 import org.apache.maven.scm.provider.svn.SvnTagBranchUtils;
 
@@ -31,6 +32,12 @@
 public class SubversionScmTranslator
     implements ScmTranslator
 {
+    public String translateBranchUrl( String url, String branchName, String branchBase )
+    {
+        return SvnTagBranchUtils.resolveUrl( url, branchBase, SvnTagBranchUtils.SVN_BRANCHES,
+                                             new ScmBranch( branchName ) );
+    }
+
     public String translateTagUrl( String url, String tag, String tagBase )
     {
         return SvnTagBranchUtils.resolveUrl( url, tagBase, SvnTagBranchUtils.SVN_TAGS, new ScmTag( tag ) );

Modified: maven/release/trunk/maven-release-manager/src/main/resources/META-INF/plexus/components.xml
URL: http://svn.apache.org/viewvc/maven/release/trunk/maven-release-manager/src/main/resources/META-INF/plexus/components.xml?view=diff&rev=534893&r1=534892&r2=534893
==============================================================================
--- maven/release/trunk/maven-release-manager/src/main/resources/META-INF/plexus/components.xml (original)
+++ maven/release/trunk/maven-release-manager/src/main/resources/META-INF/plexus/components.xml Thu May  3 07:41:44 2007
@@ -67,6 +67,19 @@
           <phase>scm-commit-rollback</phase>
           <phase>remove-scm-tag</phase>
         </rollbackPhases>
+        <branchPhases>
+          <phase>create-backup-poms</phase>
+          <phase>check-poms</phase>
+          <phase>scm-check-modifications</phase>
+          <phase>map-branch-versions</phase>
+          <phase>map-development-versions</phase>
+          <phase>rewrite-poms-for-branch</phase>
+          <phase>scm-commit-branch</phase>
+          <phase>scm-branch</phase>
+          <phase>rewrite-poms-for-development</phase>
+          <phase>scm-commit-release</phase>
+          <phase>end-release</phase>
+        </branchPhases>
       </configuration>
     </component>
     <component>
@@ -99,6 +112,21 @@
     </component>
     <component>
       <role>org.apache.maven.shared.release.phase.ReleasePhase</role>
+      <role-hint>map-branch-versions</role-hint>
+      <implementation>org.apache.maven.shared.release.phase.MapVersionsPhase</implementation>
+      <configuration>
+        <convertToSnapshot>true</convertToSnapshot>
+        <convertToBranch>true</convertToBranch>
+      </configuration>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.components.interactivity.Prompter</role>
+          <role-hint>default</role-hint>
+        </requirement>
+      </requirements>
+    </component>
+    <component>
+      <role>org.apache.maven.shared.release.phase.ReleasePhase</role>
       <role-hint>rewrite-poms-for-release</role-hint>
       <implementation>org.apache.maven.shared.release.phase.RewritePomsForReleasePhase</implementation>
       <configuration>
@@ -142,6 +170,19 @@
     </component>
     <component>
       <role>org.apache.maven.shared.release.phase.ReleasePhase</role>
+      <role-hint>scm-commit-branch</role-hint>
+      <implementation>org.apache.maven.shared.release.phase.ScmCommitPhase</implementation>
+      <requirements>
+        <requirement>
+          <role>org.apache.maven.shared.release.scm.ScmRepositoryConfigurator</role>
+        </requirement>
+      </requirements>
+      <configuration>
+        <messageFormat>prepare branch {0}</messageFormat>
+      </configuration>
+    </component>
+    <component>
+      <role>org.apache.maven.shared.release.phase.ReleasePhase</role>
       <role-hint>rewrite-poms-for-development</role-hint>
       <implementation>org.apache.maven.shared.release.phase.RewritePomsForDevelopmentPhase</implementation>
       <configuration>
@@ -169,6 +210,23 @@
       <configuration>
         <messageFormat>rollback the release of {0}</messageFormat>
       </configuration>
+    </component>
+    <component>
+      <role>org.apache.maven.shared.release.phase.ReleasePhase</role>
+      <role-hint>rewrite-poms-for-branch</role-hint>
+      <implementation>org.apache.maven.shared.release.phase.RewritePomsForBranchPhase</implementation>
+      <configuration>
+        <pomSuffix>branch</pomSuffix>
+      </configuration>
+      <requirements>
+        <requirement>
+          <role>org.apache.maven.shared.release.scm.ScmRepositoryConfigurator</role>
+        </requirement>
+        <requirement>
+          <role>org.apache.maven.shared.release.scm.ScmTranslator</role>
+          <field-name>scmTranslators</field-name>
+        </requirement>
+      </requirements>
     </component>
   </components>
 </component-set>

Added: maven/release/trunk/maven-release-plugin/src/main/java/org/apache/maven/plugins/release/BranchReleaseMojo.java
URL: http://svn.apache.org/viewvc/maven/release/trunk/maven-release-plugin/src/main/java/org/apache/maven/plugins/release/BranchReleaseMojo.java?view=auto&rev=534893
==============================================================================
--- maven/release/trunk/maven-release-plugin/src/main/java/org/apache/maven/plugins/release/BranchReleaseMojo.java (added)
+++ maven/release/trunk/maven-release-plugin/src/main/java/org/apache/maven/plugins/release/BranchReleaseMojo.java Thu May  3 07:41:44 2007
@@ -0,0 +1,113 @@
+package org.apache.maven.plugins.release;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.shared.release.ReleaseExecutionException;
+import org.apache.maven.shared.release.ReleaseFailureException;
+import org.apache.maven.shared.release.config.ReleaseDescriptor;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * Branch a project in SCM.
+ *
+ * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
+ * @version $Id$
+ * @aggregator
+ * @goal branch
+ */
+public class BranchReleaseMojo
+    extends AbstractReleaseMojo
+{
+    /**
+     * The branch name to use.
+     *
+     * @parameter expression="${branchName}"
+     */
+    private String branchName;
+
+    /**
+     * Whether to use "edit" mode on the SCM, to lock the file for editing during SCM operations.
+     *
+     * @parameter expression="${useEditMode}" default-value="false"
+     */
+    private boolean useEditMode;
+
+    /**
+     * Whether to update dependencies version to the next development version.
+     *
+     * @parameter expression="${updateDependencies}" default-value="true"
+     */
+    private boolean updateDependencies;
+
+    /**
+     * Whether to automatically assign submodules the parent version.  If set to false,
+     * the user will be prompted for the version of each submodules.
+     *
+     * @parameter expression="${autoVersionSubmodules}" default-value="false"
+     */
+    private boolean autoVersionSubmodules;
+
+    /**
+     * Dry run: don't checkin or tag anything in the scm repository, or modify the checkout.
+     * Running <code>mvn -DdryRun=true release:prepare</code> is useful in order to check that modifications to
+     * poms and scm operations (only listed on the console) are working as expected.
+     * Modified POMs are written alongside the originals without modifying them.
+     *
+     * @parameter expression="${dryRun}" default-value="false"
+     */
+    private boolean dryRun;
+
+    /**
+     * Whether to add a schema to the POM if it was previously missing on release.
+     *
+     * @parameter expression="${addSchema}" default-value="true"
+     */
+    private boolean addSchema;
+
+    public void execute()
+        throws MojoExecutionException, MojoFailureException
+    {
+        if ( StringUtils.isEmpty( branchName ) )
+        {
+            throw new MojoExecutionException( "The branch name is required." );
+        }
+
+        ReleaseDescriptor config = createReleaseDescriptor();
+        config.setAddSchema( addSchema );
+        config.setScmUseEditMode( useEditMode );
+        config.setUpdateDependencies( updateDependencies );
+        config.setAutoVersionSubmodules( autoVersionSubmodules );
+        config.setScmReleaseLabel( branchName );
+        try
+        {
+            releaseManager.branch( config, settings, reactorProjects, dryRun );
+        }
+        catch ( ReleaseExecutionException e )
+        {
+            throw new MojoExecutionException( e.getMessage(), e );
+        }
+        catch ( ReleaseFailureException e )
+        {
+            throw new MojoFailureException( e.getMessage() );
+        }
+    }
+}

Propchange: maven/release/trunk/maven-release-plugin/src/main/java/org/apache/maven/plugins/release/BranchReleaseMojo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/release/trunk/maven-release-plugin/src/main/java/org/apache/maven/plugins/release/BranchReleaseMojo.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision