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 )
98 .replace( "/", File.separator ) );
99 }
100 }
101
102 logInfo( relResult, "Verifying that there are no local modifications..." );
103 logInfo( relResult, " ignoring changes on: " + StringUtils.join( exclusionPatterns.toArray(), ", " ) );
104
105 ScmRepository repository;
106 ScmProvider provider;
107 try
108 {
109 repository =
110 scmRepositoryConfigurator.getConfiguredRepository( releaseDescriptor,
111 releaseEnvironment.getSettings() );
112
113 provider = scmRepositoryConfigurator.getRepositoryProvider( repository );
114 }
115 catch ( ScmRepositoryException e )
116 {
117 throw new ReleaseScmRepositoryException( e.getMessage() + " for URL: "
118 + releaseDescriptor.getScmSourceUrl(), e.getValidationMessages() );
119 }
120 catch ( NoSuchScmProviderException e )
121 {
122 throw new ReleaseExecutionException( "Unable to configure SCM repository: " + e.getMessage(), e );
123 }
124
125 StatusScmResult result;
126 try
127 {
128 result =
129 provider.status( repository, new ScmFileSet( new File( releaseDescriptor.getWorkingDirectory() ) ) );
130 }
131 catch ( ScmException e )
132 {
133 throw new ReleaseExecutionException( "An error occurred during the status check process: " + e.getMessage(),
134 e );
135 }
136
137 if ( !result.isSuccess() )
138 {
139 throw new ReleaseScmCommandException( "Unable to check for local modifications", result );
140 }
141
142 List<ScmFile> changedFiles = result.getChangedFiles();
143
144 if ( !changedFiles.isEmpty() )
145 {
146 ScmTranslator scmTranslator = scmTranslators.get( repository.getProvider() );
147
148
149 for ( Iterator<ScmFile> i = changedFiles.iterator(); i.hasNext(); )
150 {
151 ScmFile f = i.next();
152
153 String path;
154 if ( scmTranslator != null )
155 {
156 path = scmTranslator.toRelativePath( f.getPath() );
157 }
158 else
159 {
160 path = f.getPath();
161 }
162
163
164 String fileName = path.replace( "\\", File.separator ).replace( "/", File.separator );
165
166 for ( String exclusionPattern : exclusionPatterns )
167 {
168 if ( SelectorUtils.matchPath( exclusionPattern, fileName ) )
169 {
170 logDebug( relResult, "Ignoring changed file: " + fileName );
171 i.remove();
172 break;
173 }
174 }
175 }
176 }
177
178 if ( !changedFiles.isEmpty() )
179 {
180 StringBuilder message = new StringBuilder();
181
182 for ( ScmFile file : changedFiles )
183 {
184 message.append( file.toString() );
185 message.append( "\n" );
186 }
187
188 throw new ReleaseFailureException( "Cannot prepare the release because you have local modifications : \n"
189 + message );
190 }
191
192 relResult.setResultCode( ReleaseResult.SUCCESS );
193
194 return relResult;
195 }
196
197 public ReleaseResult simulate( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
198 List<MavenProject> reactorProjects )
199 throws ReleaseExecutionException, ReleaseFailureException
200 {
201
202 return execute( releaseDescriptor, releaseEnvironment, reactorProjects );
203 }
204 }