diff --git a/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/RemoveScmTagPhase.java b/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/RemoveScmTagPhase.java index 485ca03b9..02f087019 100644 --- a/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/RemoveScmTagPhase.java +++ b/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/RemoveScmTagPhase.java @@ -19,6 +19,7 @@ * under the License. */ +import java.io.File; import org.apache.maven.project.MavenProject; import org.apache.maven.shared.release.ReleaseExecutionException; import org.apache.maven.shared.release.ReleaseFailureException; @@ -28,26 +29,105 @@ import org.codehaus.plexus.component.annotations.Component; import java.util.List; +import org.apache.maven.scm.CommandParameter; +import org.apache.maven.scm.CommandParameters; +import org.apache.maven.scm.ScmException; +import org.apache.maven.scm.ScmFileSet; +import org.apache.maven.scm.command.untag.UntagScmResult; +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.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 org.codehaus.plexus.component.annotations.Requirement; /** - * @author Edwin Punzalan + * Remove tag from SCM repository during rollback */ @Component( role = ReleasePhase.class, hint = "remove-scm-tag" ) public class RemoveScmTagPhase extends AbstractReleasePhase { + /** + * Tool that gets a configured SCM repository from release configuration. + */ + @Requirement + private ScmRepositoryConfigurator scmRepositoryConfigurator; + @Override public ReleaseResult execute( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment, List reactorProjects ) throws ReleaseExecutionException, ReleaseFailureException { - ReleaseResult result = new ReleaseResult(); + ReleaseResult releaseResult = new ReleaseResult(); + + validateConfiguration( releaseDescriptor ); + + logInfo( releaseResult, "Removing tag with the label " + releaseDescriptor.getScmReleaseLabel() + " ..." ); + + ReleaseDescriptor basedirAlignedReleaseDescriptor = + ReleaseUtil.createBasedirAlignedReleaseDescriptor( releaseDescriptor, reactorProjects ); + + ScmRepository repository; + ScmProvider provider; + try + { + repository = + scmRepositoryConfigurator.getConfiguredRepository( basedirAlignedReleaseDescriptor.getScmSourceUrl(), + releaseDescriptor, + releaseEnvironment.getSettings() ); + + repository.getProviderRepository().setPushChanges( releaseDescriptor.isPushChanges() ); + + repository.getProviderRepository().setWorkItem( releaseDescriptor.getWorkItem() ); + + 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 ); + } + + UntagScmResult untagScmResult; + try + { + ScmFileSet fileSet = new ScmFileSet( new File( basedirAlignedReleaseDescriptor.getWorkingDirectory() ) ); + String tagName = releaseDescriptor.getScmReleaseLabel(); + String message = releaseDescriptor.getScmCommentPrefix() + "remove tag " + tagName; + CommandParameters commandParameters = new CommandParameters(); + commandParameters.setString( CommandParameter.TAG_NAME, tagName ); + commandParameters.setString( CommandParameter.MESSAGE, message ); + if ( getLogger().isDebugEnabled() ) + { + getLogger().debug( + "RemoveScmTagPhase :: scmUntagParameters tagName " + tagName ); + getLogger().debug( + "RemoveScmTagPhase :: scmUntagParameters message " + message ); + getLogger().debug( "ScmTagPhase :: fileSet " + fileSet ); + } + untagScmResult = provider.untag( repository, fileSet, commandParameters ); + } + catch ( ScmException e ) + { + throw new ReleaseExecutionException( "An error is occurred in the remove tag process: " + + e.getMessage(), e ); + } - // TODO [!]: implement + if ( !untagScmResult.isSuccess() ) + { + throw new ReleaseScmCommandException( "Unable to remove tag ", untagScmResult ); + } - result.setResultCode( ReleaseResult.SUCCESS ); + releaseResult.setResultCode( ReleaseResult.SUCCESS ); - return result; + return releaseResult; } @Override @@ -55,6 +135,25 @@ public ReleaseResult simulate( ReleaseDescriptor releaseDescriptor, ReleaseEnvir List reactorProjects ) throws ReleaseExecutionException, ReleaseFailureException { - return execute( releaseDescriptor, releaseEnvironment, reactorProjects ); + ReleaseResult releaseResult = new ReleaseResult(); + + validateConfiguration( releaseDescriptor ); + + logInfo( releaseResult, "Full run would remove tag with label: '" + releaseDescriptor.getScmReleaseLabel() + + "'" ); + + releaseResult.setResultCode( ReleaseResult.SUCCESS ); + + return releaseResult; } + + private void validateConfiguration( ReleaseDescriptor releaseDescriptor ) + throws ReleaseFailureException + { + if ( releaseDescriptor.getScmReleaseLabel() == null ) + { + throw new ReleaseFailureException( "A release label is required for removal" ); + } + } + } diff --git a/maven-release-manager/src/test/java/org/apache/maven/shared/release/phase/RemoveScmTagPhaseTest.java b/maven-release-manager/src/test/java/org/apache/maven/shared/release/phase/RemoveScmTagPhaseTest.java new file mode 100644 index 000000000..b18a66b75 --- /dev/null +++ b/maven-release-manager/src/test/java/org/apache/maven/shared/release/phase/RemoveScmTagPhaseTest.java @@ -0,0 +1,211 @@ +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 java.util.List; + +import org.apache.maven.project.MavenProject; +import org.apache.maven.scm.CommandParameters; +import org.apache.maven.scm.ScmFileSet; +import org.apache.maven.scm.command.untag.UntagScmResult; +import org.apache.maven.scm.manager.ScmManager; +import org.apache.maven.scm.provider.ScmProvider; +import org.apache.maven.scm.repository.ScmRepository; +import org.apache.maven.shared.release.ReleaseResult; +import org.apache.maven.shared.release.config.ReleaseDescriptorBuilder; +import org.apache.maven.shared.release.config.ReleaseUtils; +import org.apache.maven.shared.release.env.DefaultReleaseEnvironment; +import org.apache.maven.shared.release.scm.ReleaseScmCommandException; +import org.apache.maven.shared.release.stubs.ScmManagerStub; +import org.apache.maven.shared.release.util.ReleaseUtil; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.Matchers; +import org.mockito.Mockito; + +/** + * Test the remove SCM tag phase. + */ +public class RemoveScmTagPhaseTest extends AbstractReleaseTestCase +{ + + @Override + public void setUp() throws Exception + { + + super.setUp(); + + phase = ( ReleasePhase ) lookup( ReleasePhase.class, "remove-scm-tag" ); + + } + + @Test + public void testExecuteOutput() throws Exception + { + + // prepare + ReleaseDescriptorBuilder builder = new ReleaseDescriptorBuilder(); + builder.setScmReleaseLabel( "release-label" ); + builder.setScmSourceUrl( "scm-url" ); + List reactorProjects = createReactorProjects(); + MavenProject rootProject = ReleaseUtil.getRootProject( reactorProjects ); + builder.setWorkingDirectory( getPath( rootProject.getFile().getParentFile() ) ); + builder.setPomFileName( rootProject.getFile().getName() ); + ScmFileSet fileSet = new ScmFileSet( rootProject.getFile().getParentFile() ); + + // mock, only real mather is the file set + ScmProvider scmProviderMock = Mockito.mock( ScmProvider.class ); + Mockito.when( scmProviderMock.untag( Matchers.isA( ScmRepository.class ), + Matchers.argThat( new IsScmFileSetEquals( fileSet ) ), + Matchers.isA( CommandParameters.class ) ) ) + .thenReturn( new UntagScmResult( "...", "...", "...", true ) ); + ScmManagerStub stub = ( ScmManagerStub ) lookup( ScmManager.class ); + stub.setScmProvider( scmProviderMock ); + + // execute + ReleaseResult actual = phase.execute( ReleaseUtils.buildReleaseDescriptor( builder ), + new DefaultReleaseEnvironment(), reactorProjects ); + + // verify, actual contains trailing newline + Assert.assertEquals( "[INFO] Removing tag with the label release-label ...", actual.getOutput().trim() ); + + } + + @Test + public void testExecuteResultCode() throws Exception + { + + // prepare + ReleaseDescriptorBuilder builder = new ReleaseDescriptorBuilder(); + builder.setScmReleaseLabel( "release-label" ); + builder.setScmSourceUrl( "scm-url" ); + List reactorProjects = createReactorProjects(); + MavenProject rootProject = ReleaseUtil.getRootProject( reactorProjects ); + builder.setWorkingDirectory( getPath( rootProject.getFile().getParentFile() ) ); + builder.setPomFileName( rootProject.getFile().getName() ); + ScmFileSet fileSet = new ScmFileSet( rootProject.getFile().getParentFile() ); + + // mock, only real mather is the file set + ScmProvider scmProviderMock = Mockito.mock( ScmProvider.class ); + Mockito.when( scmProviderMock.untag( Matchers.isA( ScmRepository.class ), + Matchers.argThat( new IsScmFileSetEquals( fileSet ) ), + Matchers.isA( CommandParameters.class ) ) ) + .thenReturn( new UntagScmResult( "...", "...", "...", true ) ); + ScmManagerStub stub = ( ScmManagerStub ) lookup( ScmManager.class ); + stub.setScmProvider( scmProviderMock ); + + // execute + ReleaseResult actual = phase.execute( ReleaseUtils.buildReleaseDescriptor( builder ), + new DefaultReleaseEnvironment(), reactorProjects ); + + // verify + Assert.assertEquals( 0, actual.getResultCode() ); + + } + + @Rule + public ExpectedException exceptionRule = ExpectedException.none(); + + @Test + public void testExecuteError() throws Exception + { + + // prepare + ReleaseDescriptorBuilder builder = new ReleaseDescriptorBuilder(); + builder.setScmReleaseLabel( "release-label" ); + builder.setScmSourceUrl( "scm-url" ); + List reactorProjects = createReactorProjects(); + MavenProject rootProject = ReleaseUtil.getRootProject( reactorProjects ); + builder.setWorkingDirectory( getPath( rootProject.getFile().getParentFile() ) ); + builder.setPomFileName( rootProject.getFile().getName() ); + ScmFileSet fileSet = new ScmFileSet( rootProject.getFile().getParentFile() ); + + // mock, only real mather is the file set + ScmProvider scmProviderMock = Mockito.mock( ScmProvider.class ); + Mockito.when( scmProviderMock.untag( Matchers.isA( ScmRepository.class ), + Matchers.argThat( new IsScmFileSetEquals( fileSet ) ), + Matchers.isA( CommandParameters.class ) ) ) + .thenReturn( new UntagScmResult( "command-line", "provider-message", "command-output", false ) ); + ScmManagerStub stub = ( ScmManagerStub ) lookup( ScmManager.class ); + stub.setScmProvider( scmProviderMock ); + + // set up exception rule + exceptionRule.expect( ReleaseScmCommandException.class ); + exceptionRule.expectMessage( + "Unable to remove tag \nProvider message:\nprovider-message\nCommand output:\ncommand-output" ); + + // execute + phase.execute( ReleaseUtils.buildReleaseDescriptor( builder ), + new DefaultReleaseEnvironment(), reactorProjects ); + + } + + @Test + public void testSimulateOutput() throws Exception + { + + // prepare + ReleaseDescriptorBuilder builder = new ReleaseDescriptorBuilder(); + builder.setScmReleaseLabel( "release-label" ); + builder.setScmSourceUrl( "scm-url" ); + List reactorProjects = createReactorProjects(); + MavenProject rootProject = ReleaseUtil.getRootProject( reactorProjects ); + builder.setWorkingDirectory( getPath( rootProject.getFile().getParentFile() ) ); + builder.setPomFileName( rootProject.getFile().getName() ); + + // execute + ReleaseResult actual = phase.simulate(ReleaseUtils.buildReleaseDescriptor( builder ), + new DefaultReleaseEnvironment(), reactorProjects ); + + // verify, actual contains newline + Assert.assertEquals( "[INFO] Full run would remove tag with label: 'release-label'", + actual.getOutput().trim() ); + + } + + @Test + public void testSimulateResultCode() throws Exception + { + + // prepare + ReleaseDescriptorBuilder builder = new ReleaseDescriptorBuilder(); + builder.setScmReleaseLabel( "release-label" ); + builder.setScmSourceUrl( "scm-url" ); + List reactorProjects = createReactorProjects(); + MavenProject rootProject = ReleaseUtil.getRootProject( reactorProjects ); + builder.setWorkingDirectory( getPath( rootProject.getFile().getParentFile() ) ); + builder.setPomFileName( rootProject.getFile().getName() ); + + // execute + ReleaseResult actual = phase.simulate( ReleaseUtils.buildReleaseDescriptor( builder ), + new DefaultReleaseEnvironment(), reactorProjects ); + + Assert.assertEquals( 0, actual.getResultCode() ); + + } + + private List createReactorProjects() throws Exception + { + return createReactorProjects( "scm-commit/single-pom", "" ); + } + +} diff --git a/maven-release-manager/src/test/resources/org/apache/maven/shared/release/phase/RemoveScmTagPhaseTest.xml b/maven-release-manager/src/test/resources/org/apache/maven/shared/release/phase/RemoveScmTagPhaseTest.xml new file mode 100644 index 000000000..1c4370408 --- /dev/null +++ b/maven-release-manager/src/test/resources/org/apache/maven/shared/release/phase/RemoveScmTagPhaseTest.xml @@ -0,0 +1,36 @@ + + + + + + org.apache.maven.scm.manager.ScmManager + org.apache.maven.shared.release.stubs.ScmManagerStub + + + + org.codehaus.plexus.logging.LoggerManager + org.codehaus.plexus.logging.console.ConsoleLoggerManager + basic + + ERROR + + + + diff --git a/pom.xml b/pom.xml index a069e630c..b11c1e6a7 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ - 1.10.0 + 1.11.2 7 3.0 maven-release-archives/maven-release-LATEST