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