1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.scm.plugin;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Map.Entry;
28 import java.util.Objects;
29 import java.util.Properties;
30
31 import org.apache.commons.lang3.StringUtils;
32 import org.apache.maven.plugin.AbstractMojo;
33 import org.apache.maven.plugin.MojoExecutionException;
34 import org.apache.maven.plugins.annotations.Component;
35 import org.apache.maven.plugins.annotations.Parameter;
36 import org.apache.maven.scm.ScmBranch;
37 import org.apache.maven.scm.ScmException;
38 import org.apache.maven.scm.ScmFileSet;
39 import org.apache.maven.scm.ScmResult;
40 import org.apache.maven.scm.ScmRevision;
41 import org.apache.maven.scm.ScmTag;
42 import org.apache.maven.scm.ScmVersion;
43 import org.apache.maven.scm.manager.ScmManager;
44 import org.apache.maven.scm.provider.ScmProviderRepository;
45 import org.apache.maven.scm.provider.ScmProviderRepositoryWithHost;
46 import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository;
47 import org.apache.maven.scm.repository.ScmRepository;
48 import org.apache.maven.scm.repository.ScmRepositoryException;
49 import org.apache.maven.settings.Server;
50 import org.apache.maven.settings.Settings;
51 import org.apache.maven.settings.building.SettingsProblem;
52 import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
53 import org.apache.maven.settings.crypto.SettingsDecrypter;
54 import org.apache.maven.settings.crypto.SettingsDecryptionResult;
55 import org.apache.maven.shared.model.fileset.FileSet;
56 import org.apache.maven.shared.model.fileset.util.FileSetManager;
57
58
59
60
61
62 public abstract class AbstractScmMojo extends AbstractMojo {
63
64 protected static final String VERSION_TYPE_BRANCH = "branch";
65
66 protected static final String VERSION_TYPE_REVISION = "revision";
67
68 protected static final String VERSION_TYPE_TAG = "tag";
69
70 protected static final String[] VALID_VERSION_TYPES = {VERSION_TYPE_BRANCH, VERSION_TYPE_REVISION, VERSION_TYPE_TAG
71 };
72
73
74
75
76 @Parameter(property = "connectionUrl", defaultValue = "${project.scm.connection}")
77 private String connectionUrl;
78
79
80
81
82 @Parameter(property = "developerConnectionUrl", defaultValue = "${project.scm.developerConnection}")
83 private String developerConnectionUrl;
84
85
86
87
88 @Parameter(property = "connectionType", defaultValue = "connection")
89 private String connectionType;
90
91
92
93
94 @Parameter(property = "workingDirectory")
95 private File workingDirectory;
96
97
98
99
100 @Parameter(property = "username")
101 private String username;
102
103
104
105
106 @Parameter(property = "password")
107 private String password;
108
109
110
111
112 @Parameter(property = "privateKey")
113 private String privateKey;
114
115
116
117
118 @Parameter(property = "passphrase")
119 private String passphrase;
120
121
122
123
124
125
126 @Parameter(property = "tagBase")
127 private String tagBase;
128
129
130
131
132 @Parameter(property = "includes")
133 private String includes;
134
135
136
137
138 @Parameter(property = "excludes")
139 private String excludes;
140
141 @Component
142 private ScmManager manager;
143
144 @Component
145 private SettingsDecrypter settingsDecrypter;
146
147
148
149
150 @Parameter(property = "basedir", required = true)
151 private File basedir;
152
153 @Parameter(defaultValue = "${settings}", readonly = true)
154 private Settings settings;
155
156
157
158
159 @Parameter
160 private Properties systemProperties;
161
162
163
164
165 @Parameter
166 private Map<String, String> providerImplementations;
167
168
169
170
171
172
173
174
175
176 @Parameter(property = "pushChanges", defaultValue = "true")
177 private boolean pushChanges;
178
179
180
181
182
183
184
185 @Parameter(property = "workItem")
186 @Deprecated
187 private String workItem;
188
189
190 public void execute() throws MojoExecutionException {
191 if (systemProperties != null) {
192
193 Iterator<Object> iter = systemProperties.keySet().iterator();
194
195 while (iter.hasNext()) {
196 String key = (String) iter.next();
197
198 String value = systemProperties.getProperty(key);
199
200 System.setProperty(key, value);
201 }
202 }
203
204 if (providerImplementations != null && !providerImplementations.isEmpty()) {
205 for (Entry<String, String> entry : providerImplementations.entrySet()) {
206 String providerType = entry.getKey();
207 String providerImplementation = entry.getValue();
208 getLog().info("Change the default '" + providerType + "' provider implementation to '"
209 + providerImplementation + "'.");
210 getScmManager().setScmProviderImplementation(providerType, providerImplementation);
211 }
212 }
213 }
214
215 protected void setConnectionType(String connectionType) {
216 this.connectionType = connectionType;
217 }
218
219 public String getConnectionUrl() {
220 boolean requireDeveloperConnection = !"connection".equals(connectionType.toLowerCase());
221 if ((connectionUrl != null && !connectionUrl.isEmpty()) && !requireDeveloperConnection) {
222 return connectionUrl;
223 } else if (developerConnectionUrl != null && !developerConnectionUrl.isEmpty()) {
224 return developerConnectionUrl;
225 }
226 if (requireDeveloperConnection) {
227 throw new NullPointerException("You need to define a developerConnectionUrl parameter");
228 } else {
229 throw new NullPointerException("You need to define a connectionUrl parameter");
230 }
231 }
232
233 public void setConnectionUrl(String connectionUrl) {
234 this.connectionUrl = connectionUrl;
235 }
236
237 public File getWorkingDirectory() {
238 if (workingDirectory == null) {
239 return basedir;
240 }
241
242 return workingDirectory;
243 }
244
245 public File getBasedir() {
246 return this.basedir;
247 }
248
249 public void setWorkingDirectory(File workingDirectory) {
250 this.workingDirectory = workingDirectory;
251 }
252
253 public ScmManager getScmManager() {
254 return manager;
255 }
256
257 public ScmFileSet getFileSet() throws IOException {
258 if (includes != null || excludes != null) {
259 return new ScmFileSet(getWorkingDirectory(), includes, excludes);
260 } else {
261 return new ScmFileSet(getWorkingDirectory());
262 }
263 }
264
265 public ScmRepository getScmRepository() throws ScmException {
266 ScmRepository repository;
267
268 try {
269 repository = getScmManager().makeScmRepository(getConnectionUrl());
270
271 ScmProviderRepository providerRepo = repository.getProviderRepository();
272
273 providerRepo.setPushChanges(pushChanges);
274
275 if (!(workItem == null || workItem.isEmpty())) {
276 providerRepo.setWorkItem(workItem);
277 }
278
279 if (!(username == null || username.isEmpty())) {
280 providerRepo.setUser(username);
281 }
282
283 if (!(password == null || password.isEmpty())) {
284 providerRepo.setPassword(password);
285 }
286
287 if (repository.getProviderRepository() instanceof ScmProviderRepositoryWithHost) {
288 ScmProviderRepositoryWithHost repo = (ScmProviderRepositoryWithHost) repository.getProviderRepository();
289
290 loadInfosFromSettings(repo);
291
292 if (!(username == null || username.isEmpty())) {
293 repo.setUser(username);
294 }
295
296 if (!(password == null || password.isEmpty())) {
297 repo.setPassword(password);
298 }
299
300 if (!(privateKey == null || privateKey.isEmpty())) {
301 repo.setPrivateKey(privateKey);
302 }
303
304 if (!(passphrase == null || passphrase.isEmpty())) {
305 repo.setPassphrase(passphrase);
306 }
307 }
308
309 if (!(tagBase == null || tagBase.isEmpty())
310 && repository.getProvider().equals("svn")) {
311 SvnScmProviderRepository svnRepo = (SvnScmProviderRepository) repository.getProviderRepository();
312
313 svnRepo.setTagBase(tagBase);
314 }
315 } catch (ScmRepositoryException e) {
316 if (!e.getValidationMessages().isEmpty()) {
317 for (String message : e.getValidationMessages()) {
318 getLog().error(message);
319 }
320 }
321
322 throw new ScmException("Can't load the scm provider.", e);
323 } catch (Exception e) {
324 throw new ScmException("Can't load the scm provider.", e);
325 }
326
327 return repository;
328 }
329
330
331
332
333
334
335 private void loadInfosFromSettings(ScmProviderRepositoryWithHost repo) {
336 if (username == null || password == null) {
337 String host = repo.getHost();
338
339 int port = repo.getPort();
340
341 if (port > 0) {
342 host += ":" + port;
343 }
344
345 Server server = this.settings.getServer(host);
346
347 if (server != null) {
348 server = decrypt(server);
349
350 if (username == null) {
351 username = server.getUsername();
352 }
353
354 if (password == null) {
355 password = server.getPassword();
356 }
357
358 if (privateKey == null) {
359 privateKey = server.getPrivateKey();
360 }
361
362 if (passphrase == null) {
363 passphrase = server.getPassphrase();
364 }
365 }
366 }
367 }
368
369 private Server decrypt(Server server) {
370 SettingsDecryptionResult result = settingsDecrypter.decrypt(new DefaultSettingsDecryptionRequest(server));
371 for (SettingsProblem problem : result.getProblems()) {
372 getLog().error(problem.getMessage(), problem.getException());
373 }
374
375 return result.getServer();
376 }
377
378 public void checkResult(ScmResult result) throws MojoExecutionException {
379 if (!result.isSuccess()) {
380 getLog().error("Provider message:");
381
382 getLog().error(result.getProviderMessage() == null ? "" : result.getProviderMessage());
383
384 getLog().error("Command output:");
385
386 getLog().error(result.getCommandOutput() == null ? "" : result.getCommandOutput());
387
388 throw new MojoExecutionException("Command failed: " + Objects.toString(result.getProviderMessage()));
389 }
390 }
391
392 public String getIncludes() {
393 return includes;
394 }
395
396 public void setIncludes(String includes) {
397 this.includes = includes;
398 }
399
400 public String getExcludes() {
401 return excludes;
402 }
403
404 public void setExcludes(String excludes) {
405 this.excludes = excludes;
406 }
407
408 public ScmVersion getScmVersion(String versionType, String version) throws MojoExecutionException {
409 if ((versionType == null || versionType.isEmpty()) && (version != null && !version.isEmpty())) {
410 throw new MojoExecutionException("You must specify the version type.");
411 }
412
413 if (version == null || version.isEmpty()) {
414 return null;
415 }
416
417 if (VERSION_TYPE_BRANCH.equals(versionType)) {
418 return new ScmBranch(version);
419 }
420
421 if (VERSION_TYPE_TAG.equals(versionType)) {
422 return new ScmTag(version);
423 }
424
425 if (VERSION_TYPE_REVISION.equals(versionType)) {
426 return new ScmRevision(version);
427 }
428
429 throw new MojoExecutionException("Unknown '" + versionType + "' version type.");
430 }
431
432 protected void handleExcludesIncludesAfterCheckoutAndExport(File checkoutDirectory) throws MojoExecutionException {
433 List<String> includes = new ArrayList<>();
434
435 if (!StringUtils.isBlank(this.getIncludes())) {
436 String[] tokens = StringUtils.split(this.getIncludes(), ",");
437 for (int i = 0; i < tokens.length; ++i) {
438 includes.add(tokens[i]);
439 }
440 }
441
442 List<String> excludes = new ArrayList<>();
443
444 if (!StringUtils.isBlank(this.getExcludes())) {
445 String[] tokens = StringUtils.split(this.getExcludes(), ",");
446 for (int i = 0; i < tokens.length; ++i) {
447 excludes.add(tokens[i]);
448 }
449 }
450
451 if (includes.isEmpty() && excludes.isEmpty()) {
452 return;
453 }
454
455 FileSetManager fileSetManager = new FileSetManager();
456
457 FileSet fileset = new FileSet();
458 fileset.setDirectory(checkoutDirectory.getAbsolutePath());
459 fileset.setIncludes(excludes);
460 fileset.setExcludes(includes);
461 fileset.setUseDefaultExcludes(false);
462
463 try {
464 fileSetManager.delete(fileset);
465 } catch (IOException e) {
466 throw new MojoExecutionException(
467 "Error found while cleaning up output directory base on " + "excludes/includes configurations.", e);
468 }
469 }
470 }