1 package org.apache.maven.shared.release.phase;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.project.MavenProject;
23 import org.apache.maven.scm.ScmException;
24 import org.apache.maven.scm.ScmFile;
25 import org.apache.maven.scm.ScmFileSet;
26 import org.apache.maven.scm.command.status.StatusScmResult;
27 import org.apache.maven.scm.manager.NoSuchScmProviderException;
28 import org.apache.maven.scm.provider.ScmProvider;
29 import org.apache.maven.scm.repository.ScmRepository;
30 import org.apache.maven.scm.repository.ScmRepositoryException;
31 import org.apache.maven.shared.release.ReleaseExecutionException;
32 import org.apache.maven.shared.release.ReleaseFailureException;
33 import org.apache.maven.shared.release.ReleaseResult;
34 import org.apache.maven.shared.release.config.ReleaseDescriptor;
35 import org.apache.maven.shared.release.env.ReleaseEnvironment;
36 import org.apache.maven.shared.release.scm.ReleaseScmCommandException;
37 import org.apache.maven.shared.release.scm.ReleaseScmRepositoryException;
38 import org.apache.maven.shared.release.scm.ScmRepositoryConfigurator;
39 import org.apache.maven.shared.release.scm.ScmTranslator;
40 import org.codehaus.plexus.util.SelectorUtils;
41 import org.codehaus.plexus.util.StringUtils;
42
43 import java.io.File;
44 import java.util.Arrays;
45 import java.util.HashSet;
46 import java.util.Iterator;
47 import java.util.List;
48 import java.util.Map;
49 import java.util.Set;
50
51
52
53
54
55
56
57 public class ScmCheckModificationsPhase
58 extends AbstractReleasePhase
59 {
60
61
62
63
64
65 private ScmRepositoryConfigurator scmRepositoryConfigurator;
66
67
68
69
70
71
72 private Map<String, ScmTranslator> scmTranslators;
73
74
75
76
77
78
79 private Set<String> exclusionPatterns = new HashSet<String>( Arrays.asList(
80 "**" + File.separator + "pom.xml.backup", "**" + File.separator + "pom.xml.tag",
81 "**" + File.separator + "pom.xml.next", "**" + File.separator + "pom.xml.branch",
82 "**" + File.separator + "release.properties", "**" + File.separator + "pom.xml.releaseBackup" ) );
83
84 public ReleaseResult execute( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
85 List<MavenProject> reactorProjects )
86 throws ReleaseExecutionException, ReleaseFailureException
87 {
88 ReleaseResult relResult = new ReleaseResult();
89
90 List<String> additionalExcludes = releaseDescriptor.getCheckModificationExcludes();
91
92 if ( additionalExcludes != null )
93 {
94
95 for ( String additionalExclude : additionalExcludes )
96 {
97 exclusionPatterns.add( additionalExclude.replace( "\\", File.separator ).replace( "/", File.separator ) );
98 }
99 }
100
101 logInfo( relResult, "Verifying that there are no local modifications..." );
102 logInfo( relResult, " ignoring changes on: " + StringUtils.join( exclusionPatterns.toArray(), ", " ) );
103
104 ScmRepository repository;
105 ScmProvider provider;
106 try
107 {
108 repository =
109 scmRepositoryConfigurator.getConfiguredRepository( releaseDescriptor, releaseEnvironment.getSettings() );
110
111 provider = scmRepositoryConfigurator.getRepositoryProvider( repository );
112 }
113 catch ( ScmRepositoryException e )
114 {
115 throw new ReleaseScmRepositoryException( e.getMessage() + " for URL: "
116 + releaseDescriptor.getScmSourceUrl(), e.getValidationMessages() );
117 }
118 catch ( NoSuchScmProviderException e )
119 {
120 throw new ReleaseExecutionException( "Unable to configure SCM repository: " + e.getMessage(), e );
121 }
122
123 StatusScmResult result;
124 try
125 {
126 result =
127 provider.status( repository, new ScmFileSet( new File( releaseDescriptor.getWorkingDirectory() ) ) );
128 }
129 catch ( ScmException e )
130 {
131 throw new ReleaseExecutionException( "An error occurred during the status check process: " + e.getMessage(),
132 e );
133 }
134
135 if ( !result.isSuccess() )
136 {
137 throw new ReleaseScmCommandException( "Unable to check for local modifications", result );
138 }
139
140 List<ScmFile> changedFiles = result.getChangedFiles();
141
142 if ( !changedFiles.isEmpty() )
143 {
144 ScmTranslator scmTranslator = scmTranslators.get( repository.getProvider() );
145
146
147 for ( Iterator<ScmFile> i = changedFiles.iterator(); i.hasNext(); )
148 {
149 ScmFile f = i.next();
150
151 String path;
152 if ( scmTranslator != null )
153 {
154 path = scmTranslator.toRelativePath( f.getPath() );
155 }
156 else
157 {
158 path = f.getPath();
159 }
160
161
162 String fileName = path.replace( "\\", File.separator ).replace( "/", File.separator );
163
164 for ( String exclusionPattern : exclusionPatterns )
165 {
166 if ( SelectorUtils.matchPath( exclusionPattern, fileName ) )
167 {
168 logDebug( relResult, "Ignoring changed file: " + fileName );
169 i.remove();
170 break;
171 }
172 }
173 }
174 }
175
176 if ( !changedFiles.isEmpty() )
177 {
178 StringBuilder message = new StringBuilder();
179
180 for ( ScmFile file : changedFiles )
181 {
182 message.append( file.toString() );
183 message.append( "\n" );
184 }
185
186 throw new ReleaseFailureException( "Cannot prepare the release because you have local modifications : \n"
187 + message );
188 }
189
190 relResult.setResultCode( ReleaseResult.SUCCESS );
191
192 return relResult;
193 }
194
195 public ReleaseResult simulate( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
196 List<MavenProject> reactorProjects )
197 throws ReleaseExecutionException, ReleaseFailureException
198 {
199
200 return execute( releaseDescriptor, releaseEnvironment, reactorProjects );
201 }
202 }