1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package de.smartics.maven.plugin.buildmetadata.scm.maven;
17
18 import java.util.Iterator;
19 import java.util.List;
20
21 import org.apache.commons.lang.StringUtils;
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24 import org.apache.maven.scm.ChangeFile;
25 import org.apache.maven.scm.ChangeSet;
26 import org.apache.maven.scm.ScmFile;
27 import org.apache.maven.scm.ScmFileSet;
28 import org.apache.maven.scm.ScmVersion;
29 import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
30 import org.apache.maven.scm.command.changelog.ChangeLogSet;
31 import org.apache.maven.scm.command.status.StatusScmResult;
32 import org.apache.maven.scm.manager.NoSuchScmProviderException;
33 import org.apache.maven.scm.manager.ScmManager;
34 import org.apache.maven.scm.provider.ScmProvider;
35 import org.apache.maven.scm.repository.ScmRepository;
36
37 import de.smartics.maven.plugin.buildmetadata.scm.LocallyModifiedInfo;
38 import de.smartics.maven.plugin.buildmetadata.scm.Revision;
39 import de.smartics.maven.plugin.buildmetadata.scm.RevisionNumberFetcher;
40 import de.smartics.maven.plugin.buildmetadata.scm.ScmException;
41
42
43
44
45
46
47
48
49 public final class MavenScmRevisionNumberFetcher implements RevisionNumberFetcher
50 {
51
52
53
54
55
56
57
58 private static final Log LOG = LogFactory
59 .getLog(MavenScmRevisionNumberFetcher.class);
60
61
62
63
64
65
66 private final ScmManager scmManager;
67
68
69
70
71 private final ScmConnectionInfo scmConnectionInfo;
72
73
74
75
76
77 private final ScmAccessInfo scmAccessInfo;
78
79
80
81
82
83
84
85
86
87
88
89
90 public MavenScmRevisionNumberFetcher(final ScmManager scmManager,
91 final ScmConnectionInfo scmConnectionInfo,
92 final ScmAccessInfo scmAccessInfo)
93 {
94 this.scmManager = scmManager;
95 this.scmConnectionInfo = scmConnectionInfo;
96 this.scmAccessInfo = scmAccessInfo;
97 }
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114 public Revision fetchLatestRevisionNumber() throws ScmException
115 {
116 if (LOG.isDebugEnabled())
117 {
118 LOG.debug(" Fetching latest revision number.\n "
119 + this.scmConnectionInfo + "\n " + this.scmAccessInfo);
120 }
121
122 final ScmRepository repository =
123 scmConnectionInfo.createRepository(scmManager);
124 final ScmProvider provider = createScmProvider(repository);
125 final ChangeLogScmResult result =
126 scmAccessInfo.fetchChangeLog(repository, provider);
127
128 if (result != null)
129 {
130 final ChangeLogSet changeLogSet = result.getChangeLog();
131 final Revision revision = findEndVersion(changeLogSet);
132 if (LOG.isDebugEnabled())
133 {
134 LOG.debug(" Found revision '" + revision + "'.");
135 }
136 return revision;
137 }
138 else if (LOG.isDebugEnabled())
139 {
140 LOG.debug(" No revision information found.");
141 }
142 return null;
143 }
144
145
146
147
148
149
150 public LocallyModifiedInfo containsModifications(final ScmFileSet fileSet)
151 throws ScmException
152 {
153 if (LOG.isDebugEnabled())
154 {
155 LOG.debug(" Fetching modification information.\n "
156 + this.scmConnectionInfo + "\n " + this.scmAccessInfo);
157 }
158
159 try
160 {
161 final ScmRepository repository =
162 scmConnectionInfo.createRepository(scmManager);
163 final ScmProvider provider = createScmProvider(repository);
164 final StatusScmResult result = provider.status(repository, fileSet);
165
166 if (result.isSuccess())
167 {
168 return createLocallyModifiedInfo(result);
169 }
170 else
171 {
172 final String message =
173 result.getProviderMessage() + ": " + result.getCommandOutput();
174 if (LOG.isDebugEnabled())
175 {
176 LOG.debug(message);
177 }
178
179 throw new ScmException(message);
180 }
181 }
182 catch (final org.apache.maven.scm.ScmException e)
183 {
184 throw new ScmException(e);
185 }
186 }
187
188 @SuppressWarnings("unchecked")
189 private LocallyModifiedInfo createLocallyModifiedInfo(
190 final StatusScmResult result)
191 {
192 final List<ScmFile> changedFiles = filter(result.getChangedFiles());
193 final boolean locallyModified = !changedFiles.isEmpty();
194 if (LOG.isDebugEnabled())
195 {
196 LOG.debug(" Modifications have" + (locallyModified ? "" : " not")
197 + " been found.");
198 }
199 return new LocallyModifiedInfo(locallyModified, locallyModified
200 ? toString(changedFiles) : null);
201 }
202
203 private List<ScmFile> filter(final List<ScmFile> files)
204 {
205 if (this.scmAccessInfo.isIgnoreDotFilesInBaseDir())
206 {
207 filterDotFiles(files);
208 }
209 return files;
210 }
211
212 private void filterDotFiles(final List<ScmFile> files)
213 {
214 for (final Iterator<ScmFile> i = files.iterator(); i.hasNext();)
215 {
216 final ScmFile file = i.next();
217 final String path = file.getPath();
218 if (path.length() > 0 && path.charAt(0) == '.')
219 {
220 i.remove();
221 }
222 }
223 }
224
225
226
227
228
229
230
231 private String toString(final List<?> items)
232 {
233 final StringBuilder buffer = new StringBuilder(512);
234 for (Object item : items)
235 {
236 buffer.append(item).append(' ');
237 }
238 return StringUtils.chomp(buffer.toString());
239 }
240
241
242
243
244
245
246
247
248
249
250
251 @SuppressWarnings("unchecked")
252 private Revision findEndVersion(final ChangeLogSet changeLogSet)
253 {
254 if (changeLogSet != null)
255 {
256 final ScmVersion endVersion = changeLogSet.getEndVersion();
257 if (endVersion != null)
258 {
259 if(LOG.isDebugEnabled())
260 {
261 LOG.debug("End version found.");
262 }
263 return new MavenRevision(endVersion, changeLogSet.getEndDate());
264 }
265
266 final List<ChangeSet> changeSets = changeLogSet.getChangeSets();
267 if (!changeSets.isEmpty())
268 {
269 final int lastIndex = changeSets.size() - 1;
270 for (int index = lastIndex; index >= 0; index--)
271 {
272 final ChangeSet set = changeSets.get(lastIndex);
273 final List<ChangeFile> changeFiles = set.getFiles();
274 if (!changeFiles.isEmpty())
275 {
276 final ChangeFile file = changeFiles.get(0);
277 final String revision = file.getRevision();
278 if (revision != null)
279 {
280 return new StringRevision(revision, set.getDate());
281 }
282 }
283 else
284 {
285 if(LOG.isDebugEnabled())
286 {
287 LOG.debug("No change files found.");
288 }
289 }
290 }
291 }
292 else
293 {
294 if(LOG.isDebugEnabled())
295 {
296 LOG.debug("No change set found.");
297 }
298 }
299 }
300 else
301 {
302 if(LOG.isDebugEnabled())
303 {
304 LOG.debug("No change log set found.");
305 }
306 }
307
308 return null;
309 }
310
311
312
313
314
315
316
317
318 private ScmProvider createScmProvider(final ScmRepository repository)
319 throws ScmException
320 {
321 try
322 {
323 final ScmProvider provider =
324 scmManager.getProviderByRepository(repository);
325 return provider;
326 }
327 catch (final NoSuchScmProviderException e)
328 {
329 throw new ScmException("Cannot create SCM provider.", e);
330 }
331 }
332
333
334
335 }