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 public void execute()
175 throws MojoExecutionException
176 {
177 if ( systemProperties != null )
178 {
179
180 Iterator<Object> iter = systemProperties.keySet().iterator();
181
182 while ( iter.hasNext() )
183 {
184 String key = (String) iter.next();
185
186 String value = systemProperties.getProperty( key );
187
188 System.setProperty( key, value );
189 }
190 }
191
192 if ( providerImplementations != null && !providerImplementations.isEmpty() )
193 {
194 for ( Entry<String, String> entry : providerImplementations.entrySet() )
195 {
196 String providerType = entry.getKey();
197 String providerImplementation = entry.getValue();
198 getLog().info(
199 "Change the default '" + providerType + "' provider implementation to '"
200 + providerImplementation + "'." );
201 getScmManager().setScmProviderImplementation( providerType, providerImplementation );
202 }
203 }
204 }
205
206 protected void setConnectionType( String connectionType )
207 {
208 this.connectionType = connectionType;
209 }
210
211 public String getConnectionUrl()
212 {
213 boolean requireDeveloperConnection = !"connection".equals( connectionType.toLowerCase() );
214 if ( StringUtils.isNotEmpty( connectionUrl ) && !requireDeveloperConnection )
215 {
216 return connectionUrl;
217 }
218 else if ( StringUtils.isNotEmpty( developerConnectionUrl ) )
219 {
220 return developerConnectionUrl;
221 }
222 if ( requireDeveloperConnection )
223 {
224 throw new NullPointerException( "You need to define a developerConnectionUrl parameter" );
225 }
226 else
227 {
228 throw new NullPointerException( "You need to define a connectionUrl parameter" );
229 }
230 }
231
232 public void setConnectionUrl( String connectionUrl )
233 {
234 this.connectionUrl = connectionUrl;
235 }
236
237 public File getWorkingDirectory()
238 {
239 if ( workingDirectory == null )
240 {
241 return basedir;
242 }
243
244 return workingDirectory;
245 }
246
247 public File getBasedir()
248 {
249 return this.basedir;
250 }
251
252 public void setWorkingDirectory( File workingDirectory )
253 {
254 this.workingDirectory = workingDirectory;
255 }
256
257 public ScmManager getScmManager()
258 {
259 return manager;
260 }
261
262 public ScmFileSet getFileSet()
263 throws IOException
264 {
265 if ( includes != null || excludes != null )
266 {
267 return new ScmFileSet( getWorkingDirectory(), includes, excludes );
268 }
269 else
270 {
271 return new ScmFileSet( getWorkingDirectory() );
272 }
273 }
274
275 public ScmRepository getScmRepository()
276 throws ScmException
277 {
278 ScmRepository repository;
279
280 try
281 {
282 repository = getScmManager().makeScmRepository( getConnectionUrl() );
283
284 ScmProviderRepository providerRepo = repository.getProviderRepository();
285
286 providerRepo.setPushChanges( pushChanges );
287
288 if ( !StringUtils.isEmpty( username ) )
289 {
290 providerRepo.setUser( username );
291 }
292
293 if ( !StringUtils.isEmpty( password ) )
294 {
295 providerRepo.setPassword( password );
296 }
297
298 if ( repository.getProviderRepository() instanceof ScmProviderRepositoryWithHost )
299 {
300 ScmProviderRepositoryWithHost repo = (ScmProviderRepositoryWithHost) repository.getProviderRepository();
301
302 loadInfosFromSettings( repo );
303
304 if ( !StringUtils.isEmpty( username ) )
305 {
306 repo.setUser( username );
307 }
308
309 if ( !StringUtils.isEmpty( password ) )
310 {
311 repo.setPassword( password );
312 }
313
314 if ( !StringUtils.isEmpty( privateKey ) )
315 {
316 repo.setPrivateKey( privateKey );
317 }
318
319 if ( !StringUtils.isEmpty( passphrase ) )
320 {
321 repo.setPassphrase( passphrase );
322 }
323 }
324
325 if ( !StringUtils.isEmpty( tagBase ) && repository.getProvider().equals( "svn" ) )
326 {
327 SvnScmProviderRepository svnRepo = (SvnScmProviderRepository) repository.getProviderRepository();
328
329 svnRepo.setTagBase( tagBase );
330 }
331 }
332 catch ( ScmRepositoryException e )
333 {
334 if ( !e.getValidationMessages().isEmpty() )
335 {
336 for ( String message : e.getValidationMessages() )
337 {
338 getLog().error( message );
339 }
340 }
341
342 throw new ScmException( "Can't load the scm provider.", e );
343 }
344 catch ( Exception e )
345 {
346 throw new ScmException( "Can't load the scm provider.", e );
347 }
348
349 return repository;
350 }
351
352
353
354
355
356
357 private void loadInfosFromSettings( ScmProviderRepositoryWithHost repo )
358 {
359 if ( username == null || password == null )
360 {
361 String host = repo.getHost();
362
363 int port = repo.getPort();
364
365 if ( port > 0 )
366 {
367 host += ":" + port;
368 }
369
370 Server server = this.settings.getServer( host );
371
372 if ( server != null )
373 {
374 if ( username == null )
375 {
376 username = server.getUsername();
377 }
378
379 if ( password == null )
380 {
381 password = decrypt( server.getPassword(), host );
382 }
383
384 if ( privateKey == null )
385 {
386 privateKey = server.getPrivateKey();
387 }
388
389 if ( passphrase == null )
390 {
391 passphrase = decrypt( server.getPassphrase(), host );
392 }
393 }
394 }
395 }
396
397 private String decrypt( String str, String server )
398 {
399 try
400 {
401 return secDispatcher.decrypt( str );
402 }
403 catch ( SecDispatcherException e )
404 {
405 getLog().warn( "Failed to decrypt password/passphrase for server " + server + ", using auth token as is" );
406 return str;
407 }
408 }
409
410 public void checkResult( ScmResult result )
411 throws MojoExecutionException
412 {
413 if ( !result.isSuccess() )
414 {
415 getLog().error( "Provider message:" );
416
417 getLog().error( result.getProviderMessage() == null ? "" : result.getProviderMessage() );
418
419 getLog().error( "Command output:" );
420
421 getLog().error( result.getCommandOutput() == null ? "" : result.getCommandOutput() );
422
423 throw new MojoExecutionException(
424 "Command failed." + StringUtils.defaultString( result.getProviderMessage() ) );
425 }
426 }
427
428 public String getIncludes()
429 {
430 return includes;
431 }
432
433 public void setIncludes( String includes )
434 {
435 this.includes = includes;
436 }
437
438 public String getExcludes()
439 {
440 return excludes;
441 }
442
443 public void setExcludes( String excludes )
444 {
445 this.excludes = excludes;
446 }
447
448 public ScmVersion getScmVersion( String versionType, String version )
449 throws MojoExecutionException
450 {
451 if ( StringUtils.isEmpty( versionType ) && StringUtils.isNotEmpty( version ) )
452 {
453 throw new MojoExecutionException( "You must specify the version type." );
454 }
455
456 if ( StringUtils.isEmpty( version ) )
457 {
458 return null;
459 }
460
461 if ( "branch".equals( versionType ) )
462 {
463 return new ScmBranch( version );
464 }
465
466 if ( "tag".equals( versionType ) )
467 {
468 return new ScmTag( version );
469 }
470
471 if ( "revision".equals( versionType ) )
472 {
473 return new ScmRevision( version );
474 }
475
476 throw new MojoExecutionException( "Unknown '" + versionType + "' version type." );
477 }
478
479 protected void handleExcludesIncludesAfterCheckoutAndExport( File checkoutDirectory )
480 throws MojoExecutionException
481 {
482 List<String> includes = new ArrayList<String>();
483
484 if ( ! StringUtils.isBlank( this.getIncludes() ) )
485 {
486 String[] tokens = StringUtils.split( this.getIncludes(), "," );
487 for ( int i = 0; i < tokens.length; ++i )
488 {
489 includes.add( tokens[i] );
490 }
491 }
492
493 List<String> excludes = new ArrayList<String>();
494
495 if ( ! StringUtils.isBlank( this.getExcludes() ) )
496 {
497 String[] tokens = StringUtils.split( this.getExcludes(), "," );
498 for ( int i = 0; i < tokens.length; ++i )
499 {
500 excludes.add( tokens[i] );
501 }
502 }
503
504 if ( includes.isEmpty() && excludes.isEmpty() )
505 {
506 return;
507 }
508
509 FileSetManager fileSetManager = new FileSetManager();
510
511 FileSet fileset = new FileSet();
512 fileset.setDirectory( checkoutDirectory.getAbsolutePath() );
513 fileset.setIncludes( excludes );
514 fileset.setExcludes( includes );
515 fileset.setUseDefaultExcludes( false );
516
517 try
518 {
519 fileSetManager.delete( fileset );
520 }
521 catch ( IOException e )
522 {
523 throw new MojoExecutionException( "Error found while cleaning up output directory base on "
524 + "excludes/includes configurations.", e );
525 }
526
527 }
528 }