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