View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.shared.release.phase;
20  
21  import javax.inject.Inject;
22  import javax.inject.Named;
23  
24  import java.util.Collections;
25  import java.util.List;
26  
27  import org.apache.maven.project.MavenProject;
28  import org.apache.maven.scm.ScmFile;
29  import org.apache.maven.scm.ScmFileSet;
30  import org.apache.maven.scm.ScmFileStatus;
31  import org.apache.maven.scm.ScmVersion;
32  import org.apache.maven.scm.command.checkin.CheckInScmResult;
33  import org.apache.maven.scm.provider.ScmProvider;
34  import org.apache.maven.scm.repository.ScmRepository;
35  import org.apache.maven.shared.release.config.ReleaseDescriptorBuilder;
36  import org.apache.maven.shared.release.config.ReleaseUtils;
37  import org.apache.maven.shared.release.env.DefaultReleaseEnvironment;
38  import org.apache.maven.shared.release.util.ReleaseUtil;
39  import org.codehaus.plexus.testing.PlexusTest;
40  import org.junit.jupiter.api.BeforeEach;
41  import org.junit.jupiter.api.Test;
42  
43  import static org.junit.jupiter.api.Assertions.assertEquals;
44  import static org.mockito.ArgumentMatchers.argThat;
45  import static org.mockito.ArgumentMatchers.eq;
46  import static org.mockito.ArgumentMatchers.isA;
47  import static org.mockito.ArgumentMatchers.isNull;
48  import static org.mockito.Mockito.mock;
49  import static org.mockito.Mockito.verify;
50  import static org.mockito.Mockito.verifyNoMoreInteractions;
51  import static org.mockito.Mockito.when;
52  
53  /**
54   * Test the SCM development commit phase.
55   *
56   * @author <a href="mailto:me@lcorneliussen.de">Lars Corneliussen</a>
57   */
58  @PlexusTest
59  class ScmCommitDevelopmentPhaseTest extends AbstractReleaseTestCase {
60      private static final String COMMIT_MESSAGE = "[maven-release-manager] prepare for next development iteration";
61  
62      private static final String ROLLBACK_PREFIX =
63              "[maven-release-manager] rollback changes from release preparation of ";
64  
65      private List<MavenProject> reactorProjects;
66  
67      private MavenProject rootProject;
68  
69      private ReleaseDescriptorBuilder builder;
70  
71      private ScmProvider scmProviderMock;
72  
73      @Inject
74      @Named("scm-commit-development")
75      private ReleasePhase phase;
76  
77      @BeforeEach
78      void setUp() throws Exception {
79          reactorProjects = createReactorProjects();
80          rootProject = ReleaseUtil.getRootProject(reactorProjects);
81          builder = createReleaseDescriptorBuilder(rootProject);
82      }
83  
84      @Test
85      void testIsCorrectImplementation() {
86          assertEquals(ScmCommitDevelopmentPhase.class, phase.getClass());
87      }
88  
89      @Test
90      void testNoCommitOrRollbackRequired() throws Exception {
91          ReleaseDescriptorBuilder builder = createReleaseDescriptorBuilder(rootProject);
92          List<MavenProject> reactorProjects = createReactorProjects();
93  
94          builder.setRemoteTagging(false);
95          builder.setPinExternals(false);
96          builder.setSuppressCommitBeforeTagOrBranch(true);
97          builder.setUpdateWorkingCopyVersions(false);
98  
99          prepareNoCheckin();
100 
101         phase.execute(ReleaseUtils.buildReleaseDescriptor(builder), new DefaultReleaseEnvironment(), reactorProjects);
102 
103         verifyNoCheckin();
104     }
105 
106     @Test
107     void testCommitsNextVersions() throws Exception {
108         builder.setUpdateWorkingCopyVersions(true);
109 
110         prepareCheckin(COMMIT_MESSAGE);
111 
112         phase.execute(ReleaseUtils.buildReleaseDescriptor(builder), new DefaultReleaseEnvironment(), reactorProjects);
113 
114         verifyCheckin(COMMIT_MESSAGE);
115     }
116 
117     @Test
118     void testCommitsNextVersionsAlternateMessage() throws Exception {
119         builder.setUpdateWorkingCopyVersions(true);
120         builder.setScmCommentPrefix("[release]");
121         builder.setScmDevelopmentCommitComment("@{prefix} Development of @{groupId}:@{artifactId}");
122 
123         prepareCheckin("[release] Development of groupId:artifactId");
124 
125         phase.execute(ReleaseUtils.buildReleaseDescriptor(builder), new DefaultReleaseEnvironment(), reactorProjects);
126 
127         verifyCheckin("[release] Development of groupId:artifactId");
128     }
129 
130     @Test
131     void testCommitsRollbackPrepare() throws Exception {
132         builder.setUpdateWorkingCopyVersions(false);
133 
134         String message = ROLLBACK_PREFIX + "release-label";
135 
136         prepareCheckin(message);
137 
138         phase.execute(ReleaseUtils.buildReleaseDescriptor(builder), new DefaultReleaseEnvironment(), reactorProjects);
139 
140         verifyCheckin(message);
141     }
142 
143     private void prepareCheckin(String message) throws Exception {
144         ScmFileSet fileSet = new ScmFileSet(rootProject.getFile().getParentFile(), rootProject.getFile());
145         scmProviderMock = mock(ScmProvider.class);
146         when(scmProviderMock.checkIn(
147                         isA(ScmRepository.class),
148                         argThat(new IsScmFileSetEquals(fileSet)),
149                         isNull(ScmVersion.class),
150                         eq(message)))
151                 .thenReturn(new CheckInScmResult(
152                         "...",
153                         Collections.singletonList(
154                                 new ScmFile(rootProject.getFile().getPath(), ScmFileStatus.CHECKED_IN))));
155         scmManager.setScmProvider(scmProviderMock);
156     }
157 
158     private void verifyCheckin(String message) throws Exception {
159         ScmFileSet fileSet = new ScmFileSet(rootProject.getFile().getParentFile(), rootProject.getFile());
160         verify(scmProviderMock)
161                 .checkIn(
162                         isA(ScmRepository.class), argThat(new IsScmFileSetEquals(fileSet)),
163                         isNull(ScmVersion.class), eq(message));
164         verifyNoMoreInteractions(scmProviderMock);
165     }
166 
167     private void prepareNoCheckin() throws Exception {
168         scmProviderMock = mock(ScmProvider.class);
169         scmManager.setScmProvider(scmProviderMock);
170     }
171 
172     private void verifyNoCheckin() {
173         verifyNoMoreInteractions(scmProviderMock);
174     }
175 
176     private List<MavenProject> createReactorProjects() throws Exception {
177         String dir = "scm-commit/single-pom";
178         return createReactorProjects(dir, dir, null);
179     }
180 
181     private static ReleaseDescriptorBuilder createReleaseDescriptorBuilder(MavenProject rootProject) {
182         ReleaseDescriptorBuilder builder = new ReleaseDescriptorBuilder();
183         builder.setScmSourceUrl("scm-url");
184         builder.setScmReleaseLabel("release-label");
185         builder.setWorkingDirectory(rootProject.getFile().getParentFile().getAbsolutePath());
186         return builder;
187     }
188 }