### Eclipse Workspace Patch 1.0 #P maven-release Index: maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/ScmCheckModificationsPhase.java =================================================================== --- maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/ScmCheckModificationsPhase.java (revision 1041768) +++ maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/ScmCheckModificationsPhase.java (working copy) @@ -1,25 +1,26 @@ 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. + * 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 java.io.File; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + import org.apache.commons.lang.StringUtils; +import org.apache.maven.project.MavenProject; import org.apache.maven.scm.ScmException; import org.apache.maven.scm.ScmFile; import org.apache.maven.scm.ScmFileSet; @@ -36,135 +37,165 @@ 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 org.apache.maven.shared.release.util.ReleaseUtil; -import java.io.File; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - /** - * See if there are any local modifications to the files before proceeding with SCM operations and the release. - * + * See if there are any local modifications to the files before proceeding with SCM operations and + * the release. + * * @author Brett Porter - * @plexus.component role="org.apache.maven.shared.release.phase.ReleasePhase" role-hint="scm-check-modifications" + * @plexus.component role="org.apache.maven.shared.release.phase.ReleasePhase" + * role-hint="scm-check-modifications" */ -public class ScmCheckModificationsPhase - extends AbstractReleasePhase -{ +public class ScmCheckModificationsPhase extends AbstractReleasePhase { /** * Tool that gets a configured SCM repository from release configuration. - * + * * @plexus.requirement */ private ScmRepositoryConfigurator scmRepositoryConfigurator; /** * The files to exclude from the status check. - * + * * @todo proper construction of filenames, especially release properties */ - private Set excludedFiles = new HashSet( Arrays.asList( new String[] { "pom.xml.backup", "pom.xml.tag", - "pom.xml.next", "pom.xml.branch", "release.properties", "pom.xml.releaseBackup" } ) ); + private Set excludedFiles = new HashSet(Arrays.asList(new String[] { + "pom.xml.backup", "pom.xml.tag", "pom.xml.next", "pom.xml.branch", + "release.properties", "pom.xml.releaseBackup" })); - public ReleaseResult execute( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment, List reactorProjects ) - throws ReleaseExecutionException, ReleaseFailureException - { + public ReleaseResult execute(ReleaseDescriptor releaseDescriptor, + ReleaseEnvironment releaseEnvironment, List reactorProjects) + throws ReleaseExecutionException, ReleaseFailureException { ReleaseResult relResult = new ReleaseResult(); List additionalExcludes = releaseDescriptor.getCheckModificationExcludes(); - if ( additionalExcludes != null ) - { - for ( int i1 = 0, additionalExcludesSize = additionalExcludes.size(); i1 < additionalExcludesSize; i1++ ) - { + if (additionalExcludes != null) { + for (int i1 = 0, additionalExcludesSize = additionalExcludes.size(); i1 < additionalExcludesSize; i1++) { // fail fast if it is not a string - String exclude = (String) additionalExcludes.get( i1 ); - excludedFiles.add( exclude ); + String exclude = (String) additionalExcludes.get(i1); + excludedFiles.add(exclude); } } - logInfo( relResult, "Verifying that there are no local modifications..." ); - logInfo( relResult, " ignoring changes on: " + StringUtils.join(excludedFiles, ", ")); + logInfo(relResult, "Verifying that there are no local modifications..."); + logInfo(relResult, " ignoring changes on: " + StringUtils.join(excludedFiles, ", ")); ScmRepository repository; ScmProvider provider; - try - { - repository = scmRepositoryConfigurator.getConfiguredRepository( releaseDescriptor, releaseEnvironment.getSettings() ); + List changedFiles = new LinkedList(); + StatusScmResult result = new StatusScmResult(null, null, null, true); + if (releaseDescriptor.isCommitByProject()) { + // flat project structure + String rootProjectBaseDir = ReleaseUtil.getCommonBasedir(reactorProjects); + Iterator reactorProjectsIter = reactorProjects.iterator(); + while (reactorProjectsIter.hasNext() && result.isSuccess()) { + MavenProject mavenProject = (MavenProject) reactorProjectsIter.next(); + File mavenProjectDirectory; + String mavenProjectBaseDir = mavenProject.getBasedir().getAbsolutePath(); + + try { + repository = scmRepositoryConfigurator.getConfiguredRepository(mavenProject + .getScm().getConnection(), releaseDescriptor, releaseEnvironment + .getSettings()); - provider = scmRepositoryConfigurator.getRepositoryProvider( repository ); - } - catch ( ScmRepositoryException e ) - { - throw new ReleaseScmRepositoryException( - e.getMessage() + " for URL: " + releaseDescriptor.getScmSourceUrl(), e.getValidationMessages() ); - } - catch ( NoSuchScmProviderException e ) - { - throw new ReleaseExecutionException( "Unable to configure SCM repository: " + e.getMessage(), e ); - } + provider = scmRepositoryConfigurator.getRepositoryProvider(repository); + } catch (ScmRepositoryException e) { + throw new ReleaseScmRepositoryException(e.getMessage() + " for URL: " + + releaseDescriptor.getScmSourceUrl(), e.getValidationMessages()); + } catch (NoSuchScmProviderException e) { + throw new ReleaseExecutionException("Unable to configure SCM repository: " + + e.getMessage(), e); + } - StatusScmResult result; - try - { - result = - provider.status( repository, new ScmFileSet( new File( releaseDescriptor.getWorkingDirectory() ) ) ); + try { + result = provider.status(repository, new ScmFileSet(new File(mavenProjectBaseDir))); + } catch (ScmException e) { + throw new ReleaseExecutionException( + "An error occurred during the status check process: " + e.getMessage(), + e); + } + + if (!result.isSuccess()) { + throw new ReleaseScmCommandException("Unable to check for local modifications", + result); + } + changedFiles.addAll(result.getChangedFiles()); + } } - catch ( ScmException e ) - { - throw new ReleaseExecutionException( "An error occurred during the status check process: " + e.getMessage(), - e ); - } + else { + try + { + repository = scmRepositoryConfigurator.getConfiguredRepository( releaseDescriptor, releaseEnvironment.getSettings() ); - if ( !result.isSuccess() ) - { - throw new ReleaseScmCommandException( "Unable to check for local modifications", result ); + provider = scmRepositoryConfigurator.getRepositoryProvider( repository ); + } + catch ( ScmRepositoryException e ) + { + throw new ReleaseScmRepositoryException( + e.getMessage() + " for URL: " + releaseDescriptor.getScmSourceUrl(), e.getValidationMessages() ); + } + catch ( NoSuchScmProviderException e ) + { + throw new ReleaseExecutionException( "Unable to configure SCM repository: " + e.getMessage(), e ); + } + + try + { + result = + provider.status( repository, new ScmFileSet( new File( releaseDescriptor.getWorkingDirectory() ) ) ); + } + catch ( ScmException e ) + { + throw new ReleaseExecutionException( "An error occurred during the status check process: " + e.getMessage(), + e ); + } + + if ( !result.isSuccess() ) + { + throw new ReleaseScmCommandException( "Unable to check for local modifications", result ); + } + changedFiles.addAll(result.getChangedFiles()); } - List changedFiles = result.getChangedFiles(); - // TODO: would be nice for SCM status command to do this for me. - for ( Iterator i = changedFiles.iterator(); i.hasNext(); ) - { + for (Iterator i = changedFiles.iterator(); i.hasNext();) { ScmFile f = (ScmFile) i.next(); - String fileName = f.getPath().replace( '\\', '/' ); - fileName = fileName.substring( fileName.lastIndexOf( '/' ) + 1, fileName.length() ); + String fileName = f.getPath().replace('\\', '/'); + fileName = fileName.substring(fileName.lastIndexOf('/') + 1, fileName.length()); - if ( excludedFiles.contains( fileName ) ) - { + if (excludedFiles.contains(fileName)) { i.remove(); } } - if ( !changedFiles.isEmpty() ) - { + if (!changedFiles.isEmpty()) { StringBuffer message = new StringBuffer(); - for ( Iterator i = changedFiles.iterator(); i.hasNext(); ) - { + for (Iterator i = changedFiles.iterator(); i.hasNext();) { ScmFile file = (ScmFile) i.next(); - message.append( file.toString() ); + message.append(file.toString()); - message.append( "\n" ); + message.append("\n"); } throw new ReleaseFailureException( - "Cannot prepare the release because you have local modifications : \n" + message ); + "Cannot prepare the release because you have local modifications : \n" + + message); } - relResult.setResultCode( ReleaseResult.SUCCESS ); + relResult.setResultCode(ReleaseResult.SUCCESS); return relResult; } - public ReleaseResult simulate( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment, List reactorProjects ) - throws ReleaseExecutionException, ReleaseFailureException - { + public ReleaseResult simulate(ReleaseDescriptor releaseDescriptor, + ReleaseEnvironment releaseEnvironment, List reactorProjects) + throws ReleaseExecutionException, ReleaseFailureException { // It makes no modifications, so simulate is the same as execute - return execute( releaseDescriptor, releaseEnvironment, reactorProjects ); + return execute(releaseDescriptor, releaseEnvironment, reactorProjects); } } Index: maven-release-plugin/src/main/java/org/apache/maven/plugins/release/PerformReleaseMojo.java =================================================================== --- maven-release-plugin/src/main/java/org/apache/maven/plugins/release/PerformReleaseMojo.java (revision 1041768) +++ maven-release-plugin/src/main/java/org/apache/maven/plugins/release/PerformReleaseMojo.java (working copy) @@ -91,6 +91,14 @@ } /** + * Commits to do are atomic or by project. + * + * @parameter expression="${commitByProject}" default-value="false" + * @since 2.2 + */ + private boolean commitByProject; + + /** * {@inheritDoc} */ public void execute() @@ -113,7 +121,8 @@ { releaseDescriptor.setScmSourceUrl( connectionUrl ); } - + + releaseDescriptor.setCommitByProject( commitByProject ); releaseDescriptor.setCheckoutDirectory( workingDirectory.getAbsolutePath() ); releaseDescriptor.setUseReleaseProfile( useReleaseProfile ); Index: maven-release-plugin/src/main/java/org/apache/maven/plugins/release/BranchReleaseMojo.java =================================================================== --- maven-release-plugin/src/main/java/org/apache/maven/plugins/release/BranchReleaseMojo.java (revision 1041768) +++ maven-release-plugin/src/main/java/org/apache/maven/plugins/release/BranchReleaseMojo.java (working copy) @@ -190,6 +190,14 @@ * @since 2.0 */ private String developmentVersion; + + /** + * Commits to do are atomic or by project. + * + * @parameter expression="${commitByProject}" default-value="false" + * @since 2.2 + */ + private boolean commitByProject; /** * {@inheritDoc} @@ -214,7 +222,8 @@ config.setDefaultReleaseVersion( releaseVersion ); config.setDefaultDevelopmentVersion( developmentVersion ); config.setSuppressCommitBeforeTagOrBranch( suppressCommitBeforeBranch ); - + config.setCommitByProject( commitByProject ); + // Create a config containing values from the session properties (ie command line properties with cli). ReleaseDescriptor sysPropertiesConfig = ReleaseUtils.copyPropertiesToReleaseDescriptor( session.getExecutionProperties() ); Index: maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/ScmTagPhase.java =================================================================== --- maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/ScmTagPhase.java (revision 1041768) +++ maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/ScmTagPhase.java (working copy) @@ -20,8 +20,10 @@ */ import java.io.File; +import java.util.Iterator; import java.util.List; +import org.apache.maven.project.MavenProject; import org.apache.maven.scm.ScmException; import org.apache.maven.scm.ScmFileSet; import org.apache.maven.scm.ScmTagParameters; @@ -103,11 +105,10 @@ throw new ReleaseExecutionException( "Unable to configure SCM repository: " + e.getMessage(), e ); } - TagScmResult result; + TagScmResult result = new TagScmResult(null, null, null, true); try { // TODO: want includes/excludes? - ScmFileSet fileSet = new ScmFileSet( new File( basedirAlignedReleaseDescriptor.getWorkingDirectory() ) ); String tagName = releaseDescriptor.getScmReleaseLabel(); ScmTagParameters scmTagParameters = new ScmTagParameters( releaseDescriptor.getScmCommentPrefix() + " copy for tag " + tagName ); @@ -116,18 +117,28 @@ if ( getLogger().isDebugEnabled() ) { getLogger().debug( - "ScmTagPhase :: scmTagParameters remotingTag " + releaseDescriptor.isRemoteTagging() ); + "ScmTagPhase :: scmTagParameters remotingTag " + releaseDescriptor.isRemoteTagging() ); getLogger().debug( - "ScmTagPhase :: scmTagParameters scmRevision " + releaseDescriptor.getScmReleasedPomRevision() ); + "ScmTagPhase :: scmTagParameters scmRevision " + releaseDescriptor.getScmReleasedPomRevision() ); } - result = provider.tag( repository, fileSet, tagName, scmTagParameters ); + if (releaseDescriptor.isCommitByProject()) { + Iterator reactorProjectsIter = reactorProjects.iterator(); + while (reactorProjectsIter.hasNext() && result.isSuccess()) { + MavenProject mavenProject = (MavenProject) reactorProjectsIter.next(); + ScmFileSet fileSet = new ScmFileSet( mavenProject.getBasedir() ); + result = provider.tag( repository, fileSet, tagName, scmTagParameters ); + } + } else { + ScmFileSet fileSet = new ScmFileSet( new File( basedirAlignedReleaseDescriptor.getWorkingDirectory() ) ); + result = provider.tag( repository, fileSet, tagName, scmTagParameters ); + } } catch ( ScmException e ) { throw new ReleaseExecutionException( "An error is occurred in the tag process: " + e.getMessage(), e ); } - if ( !result.isSuccess() ) + if ( result == null || !result.isSuccess() ) { throw new ReleaseScmCommandException( "Unable to tag SCM", result ); } Index: maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/ScmBranchPhase.java =================================================================== --- maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/ScmBranchPhase.java (revision 1041768) +++ maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/ScmBranchPhase.java (working copy) @@ -19,6 +19,11 @@ * under the License. */ +import java.io.File; +import java.util.Iterator; +import java.util.List; + +import org.apache.maven.project.MavenProject; import org.apache.maven.scm.ScmBranchParameters; import org.apache.maven.scm.ScmException; import org.apache.maven.scm.ScmFileSet; @@ -36,9 +41,6 @@ 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. * @@ -66,28 +68,10 @@ ScmRepository repository; ScmProvider provider; + BranchScmResult result = new BranchScmResult(null, null, null, true); try { - repository = scmRepositoryConfigurator.getConfiguredRepository( releaseDescriptor, releaseEnvironment.getSettings() ); - - repository.getProviderRepository().setPushChanges( releaseDescriptor.isPushChanges() ); - - 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() ) ); +// ScmFileSet fileSet = new ScmFileSet( new File( releaseDescriptor.getWorkingDirectory() ) ); String branchName = releaseDescriptor.getScmReleaseLabel(); ScmBranchParameters scmBranchParameters = new ScmBranchParameters(); @@ -95,14 +79,62 @@ scmBranchParameters.setRemoteBranching( releaseDescriptor.isRemoteTagging() ); scmBranchParameters.setScmRevision( releaseDescriptor.getScmReleasedPomRevision() ); - result = provider.branch( repository, fileSet, branchName, scmBranchParameters); + if (releaseDescriptor.isCommitByProject()) { + Iterator reactorProjectsIter = reactorProjects.iterator(); + while (reactorProjectsIter.hasNext() && result.isSuccess()) { + MavenProject mavenProject = (MavenProject) reactorProjectsIter.next(); + try + { + repository = scmRepositoryConfigurator.getConfiguredRepository(mavenProject + .getScm().getConnection(), releaseDescriptor, releaseEnvironment.getSettings() ); + + repository.getProviderRepository().setPushChanges( releaseDescriptor.isPushChanges() ); + + 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 ); + } + + + ScmFileSet fileSet = new ScmFileSet( mavenProject.getBasedir() ); + result = provider.branch( repository, fileSet, branchName, scmBranchParameters); + } + } else { + try + { + repository = scmRepositoryConfigurator.getConfiguredRepository( releaseDescriptor, releaseEnvironment.getSettings() ); + + repository.getProviderRepository().setPushChanges( releaseDescriptor.isPushChanges() ); + + 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 ); + } + + ScmFileSet fileSet = new ScmFileSet( new File( releaseDescriptor.getWorkingDirectory() ) ); + result = provider.branch( repository, fileSet, branchName, scmBranchParameters); + } } catch ( ScmException e ) { throw new ReleaseExecutionException( "An error is occurred in the branch process: " + e.getMessage(), e ); } - if ( !result.isSuccess() ) + if ( result == null || !result.isSuccess() ) { throw new ReleaseScmCommandException( "Unable to branch SCM", result ); } Index: maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/CheckoutProjectFromScm.java =================================================================== --- maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/CheckoutProjectFromScm.java (revision 1041768) +++ maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/CheckoutProjectFromScm.java (working copy) @@ -1,26 +1,20 @@ 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. + * 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 java.io.File; import java.io.IOException; +import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import org.apache.maven.project.MavenProject; @@ -47,139 +41,174 @@ /** * @author Emmanuel Venisse * @version $Id$ - * @plexus.component role="org.apache.maven.shared.release.phase.ReleasePhase" role-hint="checkout-project-from-scm" + * @plexus.component role="org.apache.maven.shared.release.phase.ReleasePhase" + * role-hint="checkout-project-from-scm" */ -public class CheckoutProjectFromScm - extends AbstractReleasePhase -{ +public class CheckoutProjectFromScm extends AbstractReleasePhase { /** * Tool that gets a configured SCM repository from release configuration. - * + * * @plexus.requirement */ private ScmRepositoryConfigurator scmRepositoryConfigurator; - public ReleaseResult execute( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment, - List reactorProjects ) - throws ReleaseExecutionException, ReleaseFailureException - { + public ReleaseResult execute(ReleaseDescriptor releaseDescriptor, + ReleaseEnvironment releaseEnvironment, List reactorProjects) + throws ReleaseExecutionException, ReleaseFailureException { ReleaseResult result = new ReleaseResult(); - logInfo( result, "Checking out the project to perform the release ..." ); + logInfo(result, "Checking out the project to perform the release ..."); ScmRepository repository; ScmProvider provider; - if ( releaseDescriptor.isLocalCheckout() ) - { + if (releaseDescriptor.isLocalCheckout()) { // in the release phase we have to change the checkout URL // to do a local checkout instead of going over the network. - // the first step is a bit tricky, we need to know which provider! like e.g. "scm:jgit:http://" + // the first step is a bit tricky, we need to know which provider! like e.g. + // "scm:jgit:http://" // the offset of 4 is because 'scm:' has 4 characters... - String providerPart = releaseDescriptor.getScmSourceUrl().substring( 0, - releaseDescriptor.getScmSourceUrl().indexOf( - ':', 4 ) ); - releaseDescriptor.setScmSourceUrl( providerPart + ":file://" + releaseDescriptor.getWorkingDirectory() ); - getLogger().info( "Performing a LOCAL checkout from " + releaseDescriptor.getScmSourceUrl() ); + String providerPart = releaseDescriptor.getScmSourceUrl().substring(0, + releaseDescriptor.getScmSourceUrl().indexOf(':', 4)); + releaseDescriptor.setScmSourceUrl(providerPart + ":file://" + + releaseDescriptor.getWorkingDirectory()); + getLogger().info( + "Performing a LOCAL checkout from " + releaseDescriptor.getScmSourceUrl()); } - try - { - repository = scmRepositoryConfigurator.getConfiguredRepository( releaseDescriptor, - releaseEnvironment.getSettings() ); + - provider = scmRepositoryConfigurator.getRepositoryProvider( repository ); - } - catch ( ScmRepositoryException e ) - { - result.setResultCode( ReleaseResult.ERROR ); - logError( result, e.getMessage() ); - - throw new ReleaseScmRepositoryException( e.getMessage(), e.getValidationMessages() ); - } - catch ( NoSuchScmProviderException e ) - { - result.setResultCode( ReleaseResult.ERROR ); - logError( result, e.getMessage() ); - - throw new ReleaseExecutionException( "Unable to configure SCM repository: " + e.getMessage(), e ); - } - - MavenProject rootProject = ReleaseUtil.getRootProject( reactorProjects ); + MavenProject rootProject = ReleaseUtil.getRootProject(reactorProjects); // TODO: sanity check that it is not . or .. or lower File checkoutDirectory; - if ( StringUtils.isEmpty( releaseDescriptor.getCheckoutDirectory() ) ) - { - checkoutDirectory = new File( rootProject.getFile().getParentFile(), "target/checkout" ); - releaseDescriptor.setCheckoutDirectory( checkoutDirectory.getAbsolutePath() ); + if (StringUtils.isEmpty(releaseDescriptor.getCheckoutDirectory())) { + checkoutDirectory = new File(rootProject.getFile().getParentFile(), "target/checkout"); + releaseDescriptor.setCheckoutDirectory(checkoutDirectory.getAbsolutePath()); + } else { + checkoutDirectory = new File(releaseDescriptor.getCheckoutDirectory()); } - else - { - checkoutDirectory = new File( releaseDescriptor.getCheckoutDirectory() ); - } - if ( checkoutDirectory.exists() ) - { - try - { - FileUtils.deleteDirectory( checkoutDirectory ); - } - catch ( IOException e ) - { - result.setResultCode( ReleaseResult.ERROR ); - logError( result, e.getMessage() ); + if (checkoutDirectory.exists()) { + try { + FileUtils.deleteDirectory(checkoutDirectory); + } catch (IOException e) { + result.setResultCode(ReleaseResult.ERROR); + logError(result, e.getMessage()); - throw new ReleaseExecutionException( "Unable to remove old checkout directory: " + e.getMessage(), e ); + throw new ReleaseExecutionException("Unable to remove old checkout directory: " + + e.getMessage(), e); } } checkoutDirectory.mkdirs(); - CheckOutScmResult scmResult; + CheckOutScmResult scmResult = new CheckOutScmResult(null, null, null, true); - try - { - scmResult = provider.checkOut( repository, new ScmFileSet( checkoutDirectory ), - new ScmTag( releaseDescriptor.getScmReleaseLabel() ) ); - } - catch ( ScmException e ) - { - result.setResultCode( ReleaseResult.ERROR ); - logError( result, e.getMessage() ); + if (releaseDescriptor.isCommitByProject()) { + // flat project structure + String rootProjectBaseDir = ReleaseUtil.getCommonBasedir(reactorProjects); + Iterator reactorProjectsIter = reactorProjects.iterator(); + while (reactorProjectsIter.hasNext() && scmResult.isSuccess()) { + MavenProject mavenProject = (MavenProject) reactorProjectsIter.next(); + File mavenCheckoutProjectDirectory; + String mavenProjectBaseDir = mavenProject.getBasedir().getAbsolutePath(); + if (mavenProjectBaseDir.length() > rootProjectBaseDir.length()) { + String relativeProjectDir = mavenProjectBaseDir.substring(rootProjectBaseDir + .length() + 1); + mavenCheckoutProjectDirectory = new File(checkoutDirectory, relativeProjectDir); + } else { + mavenCheckoutProjectDirectory = checkoutDirectory; + } + + try { + repository = scmRepositoryConfigurator.getConfiguredRepository(mavenProject.getScm().getConnection(), releaseDescriptor, + releaseEnvironment.getSettings()); - throw new ReleaseExecutionException( "An error is occurred in the checkout process: " + e.getMessage(), e ); + provider = scmRepositoryConfigurator.getRepositoryProvider(repository); + } catch (ScmRepositoryException e) { + result.setResultCode(ReleaseResult.ERROR); + logError(result, e.getMessage()); + + throw new ReleaseScmRepositoryException(e.getMessage(), e.getValidationMessages()); + } catch (NoSuchScmProviderException e) { + result.setResultCode(ReleaseResult.ERROR); + logError(result, e.getMessage()); + + throw new ReleaseExecutionException("Unable to configure SCM repository: " + + e.getMessage(), e); + } + + try { + scmResult = provider.checkOut(repository, new ScmFileSet( + mavenCheckoutProjectDirectory), new ScmTag(releaseDescriptor + .getScmReleaseLabel())); + } catch (ScmException e) { + result.setResultCode(ReleaseResult.ERROR); + logError(result, e.getMessage()); + + throw new ReleaseExecutionException( + "An error is occurred in the checkout process: " + e.getMessage(), e); + } + } + } else { + try { + repository = scmRepositoryConfigurator.getConfiguredRepository(releaseDescriptor, + releaseEnvironment.getSettings()); + + provider = scmRepositoryConfigurator.getRepositoryProvider(repository); + } catch (ScmRepositoryException e) { + result.setResultCode(ReleaseResult.ERROR); + logError(result, e.getMessage()); + + throw new ReleaseScmRepositoryException(e.getMessage(), e.getValidationMessages()); + } catch (NoSuchScmProviderException e) { + result.setResultCode(ReleaseResult.ERROR); + logError(result, e.getMessage()); + + throw new ReleaseExecutionException("Unable to configure SCM repository: " + + e.getMessage(), e); + } + + // standard project structure + try { + scmResult = provider.checkOut(repository, new ScmFileSet(checkoutDirectory), + new ScmTag(releaseDescriptor.getScmReleaseLabel())); + } catch (ScmException e) { + result.setResultCode(ReleaseResult.ERROR); + logError(result, e.getMessage()); + + throw new ReleaseExecutionException( + "An error is occurred in the checkout process: " + e.getMessage(), e); + } } String scmRelativePathProjectDirectory = scmResult.getRelativePathProjectDirectory(); - if ( StringUtils.isEmpty( scmRelativePathProjectDirectory ) ) - { - String basedir = ReleaseUtil.getCommonBasedir( reactorProjects ); + if (StringUtils.isEmpty(scmRelativePathProjectDirectory)) { + String basedir = ReleaseUtil.getCommonBasedir(reactorProjects); String rootProjectBasedir = rootProject.getBasedir().getAbsolutePath(); - if ( rootProjectBasedir.length() > basedir.length() ) - { - scmRelativePathProjectDirectory = rootProjectBasedir.substring( basedir.length() + 1 ); + if (rootProjectBasedir.length() > basedir.length()) { + scmRelativePathProjectDirectory = rootProjectBasedir + .substring(basedir.length() + 1); } } - releaseDescriptor.setScmRelativePathProjectDirectory( scmRelativePathProjectDirectory ); + releaseDescriptor.setScmRelativePathProjectDirectory(scmRelativePathProjectDirectory); - if ( !scmResult.isSuccess() ) - { - result.setResultCode( ReleaseResult.ERROR ); - logError( result, scmResult.getProviderMessage() ); + if (!scmResult.isSuccess()) { + result.setResultCode(ReleaseResult.ERROR); + logError(result, scmResult.getProviderMessage()); - throw new ReleaseScmCommandException( "Unable to checkout from SCM", scmResult ); + throw new ReleaseScmCommandException("Unable to checkout from SCM", scmResult); } - result.setResultCode( ReleaseResult.SUCCESS ); + result.setResultCode(ReleaseResult.SUCCESS); return result; } - public ReleaseResult simulate( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment, - List reactorProjects ) - throws ReleaseExecutionException, ReleaseFailureException - { - return simulate( releaseDescriptor, releaseEnvironment, reactorProjects ); + public ReleaseResult simulate(ReleaseDescriptor releaseDescriptor, + ReleaseEnvironment releaseEnvironment, List reactorProjects) + throws ReleaseExecutionException, ReleaseFailureException { + return simulate(releaseDescriptor, releaseEnvironment, reactorProjects); } }