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