1 package org.apache.maven.plugins.assembly.mojos;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.archiver.MavenArchiveConfiguration;
23 import org.apache.maven.artifact.repository.ArtifactRepository;
24 import org.apache.maven.execution.MavenSession;
25 import org.apache.maven.plugin.AbstractMojo;
26 import org.apache.maven.plugin.MojoExecutionException;
27 import org.apache.maven.plugin.MojoFailureException;
28 import org.apache.maven.plugin.logging.Log;
29 import org.apache.maven.plugins.annotations.Component;
30 import org.apache.maven.plugins.annotations.Parameter;
31 import org.apache.maven.plugins.assembly.AssemblerConfigurationSource;
32 import org.apache.maven.plugins.assembly.InvalidAssemblerConfigurationException;
33 import org.apache.maven.plugins.assembly.archive.ArchiveCreationException;
34 import org.apache.maven.plugins.assembly.archive.AssemblyArchiver;
35 import org.apache.maven.plugins.assembly.format.AssemblyFormattingException;
36 import org.apache.maven.plugins.assembly.io.AssemblyReadException;
37 import org.apache.maven.plugins.assembly.io.AssemblyReader;
38 import org.apache.maven.plugins.assembly.model.Assembly;
39 import org.apache.maven.plugins.assembly.utils.AssemblyFormatUtils;
40 import org.apache.maven.plugins.assembly.utils.InterpolationConstants;
41 import org.apache.maven.project.MavenProject;
42 import org.apache.maven.project.MavenProjectHelper;
43 import org.apache.maven.shared.filtering.MavenReaderFilter;
44 import org.apache.maven.shared.utils.cli.CommandLineUtils;
45 import org.codehaus.plexus.configuration.PlexusConfiguration;
46 import org.codehaus.plexus.interpolation.fixed.FixedStringSearchInterpolator;
47 import org.codehaus.plexus.interpolation.fixed.PrefixedPropertiesValueSource;
48 import org.codehaus.plexus.interpolation.fixed.PropertiesBasedValueSource;
49
50 import javax.annotation.Nonnull;
51 import java.io.File;
52 import java.util.Collections;
53 import java.util.List;
54 import java.util.Properties;
55
56
57
58
59
60
61
62 public abstract class AbstractAssemblyMojo
63 extends AbstractMojo
64 implements AssemblerConfigurationSource
65 {
66 protected FixedStringSearchInterpolator commanndLinePropertiesInterpolator;
67
68 protected FixedStringSearchInterpolator envInterpolator;
69
70 protected FixedStringSearchInterpolator mainProjectInterpolator;
71
72 protected FixedStringSearchInterpolator rootInterpolator;
73
74
75
76
77
78
79 @Parameter( property = "assembly.appendAssemblyId", defaultValue = "true" )
80 boolean appendAssemblyId;
81
82
83
84
85 @Parameter( property = "encoding", defaultValue = "${project.build.sourceEncoding}" )
86 private String encoding;
87
88
89
90
91
92
93
94 @Parameter( property = "assembly.escapeString" )
95 private String escapeString;
96
97
98
99
100
101 @Parameter( property = "assembly.skipAssembly", defaultValue = "false" )
102 private boolean skipAssembly;
103
104
105
106
107 @Parameter( property = "assembly.dryRun", defaultValue = "false" )
108 private boolean dryRun;
109
110
111
112
113
114
115 @Parameter( defaultValue = "true" )
116 private boolean ignoreDirFormatExtensions;
117
118
119
120
121 @Parameter( defaultValue = "${localRepository}", required = true, readonly = true )
122 private ArtifactRepository localRepository;
123
124
125
126 @Parameter( defaultValue = "${project.remoteArtifactRepositories}", required = true, readonly = true )
127 private List<ArtifactRepository> remoteRepositories;
128
129
130
131
132 @Parameter( defaultValue = "${reactorProjects}", required = true, readonly = true )
133 private List<MavenProject> reactorProjects;
134
135
136
137
138 @Parameter( defaultValue = "${project.build.directory}", required = true )
139 private File outputDirectory;
140
141
142
143
144 @Parameter( defaultValue = "${project.build.finalName}", required = true, readonly = true )
145 private String finalName;
146
147
148
149
150 @Parameter( defaultValue = "${project.build.directory}/assembly/work", required = true )
151 private File workDirectory;
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167 @Parameter
168 private List<String> formats;
169
170
171
172
173 @Parameter
174 private String[] descriptors;
175
176
177
178
179
180
181
182 @Parameter
183 private String[] descriptorRefs;
184
185
186
187
188 @Parameter
189 private File descriptorSourceDirectory;
190
191
192
193
194
195 @Parameter
196 private File archiveBaseDirectory;
197
198
199
200
201
202 @Parameter( property = "assembly.tarLongFileMode", defaultValue = "warn" )
203 private String tarLongFileMode;
204
205
206
207
208 @Parameter( defaultValue = "${project.basedir}", required = true, readonly = true )
209 private File basedir;
210
211
212
213
214 @Component
215 private MavenProjectHelper projectHelper;
216
217
218
219
220 @Component
221 private MavenReaderFilter mavenReaderFilter;
222
223
224
225
226 @Parameter( defaultValue = "${session}", readonly = true, required = true )
227 private MavenSession mavenSession;
228
229
230
231
232 @Parameter( defaultValue = "${project.build.directory}/archive-tmp", required = true, readonly = true )
233 private File tempRoot;
234
235
236
237
238 @Parameter( defaultValue = "${project.reporting.outputDirectory}", readonly = true )
239 private File siteDirectory;
240
241
242
243
244 @Parameter( property = "assembly.ignoreMissingDescriptor", defaultValue = "false" )
245 private boolean ignoreMissingDescriptor;
246
247
248
249
250
251
252 @Parameter
253 private MavenArchiveConfiguration archive;
254
255
256
257
258
259
260
261
262 @Parameter
263 private List<String> filters;
264
265
266
267
268
269
270
271 @Parameter( property = "assembly.includeProjectBuildFilters", defaultValue = "true" )
272 private boolean includeProjectBuildFilters;
273
274
275
276
277
278
279 @Parameter( property = "assembly.attach", defaultValue = "true" )
280 private boolean attach;
281
282
283
284
285
286
287
288 @Parameter( defaultValue = "true" )
289 private boolean recompressZippedFiles;
290
291
292
293
294
295 @Parameter
296 private String mergeManifestMode;
297
298
299
300 @Component
301 private AssemblyArchiver assemblyArchiver;
302
303
304
305 @Component
306 private AssemblyReader assemblyReader;
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322 @Parameter
323 private PlexusConfiguration archiverConfig;
324
325
326
327
328
329
330
331 @Parameter( property = "assembly.runOnlyAtExecutionRoot", defaultValue = "false" )
332 private boolean runOnlyAtExecutionRoot;
333
334
335
336
337
338
339
340
341
342
343 @Parameter( property = "assembly.updateOnly", defaultValue = "false" )
344 private boolean updateOnly;
345
346
347
348
349
350
351
352
353
354 @Parameter( property = "assembly.useJvmChmod", defaultValue = "false" )
355 private boolean useJvmChmod;
356
357
358
359
360
361
362
363
364
365
366
367
368
369 @Parameter( property = "assembly.ignorePermissions", defaultValue = "false" )
370 private boolean ignorePermissions;
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393 @Parameter
394 private List<String> delimiters;
395
396 public static FixedStringSearchInterpolator mainProjectInterpolator( MavenProject mainProject )
397 {
398 if ( mainProject != null )
399 {
400
401 return FixedStringSearchInterpolator.create(
402 new org.codehaus.plexus.interpolation.fixed.PrefixedObjectValueSource(
403 InterpolationConstants.PROJECT_PREFIXES, mainProject, true ),
404
405
406 new org.codehaus.plexus.interpolation.fixed.PrefixedPropertiesValueSource(
407 InterpolationConstants.PROJECT_PROPERTIES_PREFIXES, mainProject.getProperties(), true ) );
408 }
409 else
410 {
411 return FixedStringSearchInterpolator.empty();
412 }
413 }
414
415
416
417
418
419
420 @Override
421 public void execute()
422 throws MojoExecutionException, MojoFailureException
423 {
424
425 if ( skipAssembly )
426 {
427 getLog().info( "Assemblies have been skipped per configuration of the skipAssembly parameter." );
428 return;
429 }
430
431
432 if ( runOnlyAtExecutionRoot && !isThisTheExecutionRoot() )
433 {
434 getLog().info( "Skipping the assembly in this project because it's not the Execution Root" );
435 return;
436 }
437
438 List<Assembly> assemblies;
439 try
440 {
441 assemblies = assemblyReader.readAssemblies( this );
442 }
443 catch ( final AssemblyReadException e )
444 {
445 throw new MojoExecutionException( "Error reading assemblies: " + e.getMessage(), e );
446 }
447 catch ( final InvalidAssemblerConfigurationException e )
448 {
449 throw new MojoFailureException( assemblyReader, e.getMessage(),
450 "Mojo configuration is invalid: " + e.getMessage() );
451 }
452
453
454
455
456 boolean warnedAboutMainProjectArtifact = false;
457 for ( final Assembly assembly : assemblies )
458 {
459 try
460 {
461 final String fullName = AssemblyFormatUtils.getDistributionName( assembly, this );
462
463 List<String> effectiveFormats = formats;
464 if ( effectiveFormats == null || effectiveFormats.size() == 0 )
465 {
466 effectiveFormats = assembly.getFormats();
467 }
468 if ( effectiveFormats == null || effectiveFormats.size() == 0 )
469 {
470 throw new MojoFailureException(
471 "No formats specified in the execution parameters or the assembly descriptor." );
472 }
473
474 for ( final String format : effectiveFormats )
475 {
476 final File destFile =
477 assemblyArchiver.createArchive( assembly, fullName, format,
478 this, isRecompressZippedFiles(), getMergeManifestMode() );
479
480 final MavenProject project = getProject();
481 final String type = project.getArtifact().getType();
482
483 if ( attach && destFile.isFile() )
484 {
485 if ( isAssemblyIdAppended() )
486 {
487 projectHelper.attachArtifact( project, format, assembly.getId(), destFile );
488 }
489 else if ( !"pom".equals( type ) && format.equals( type ) )
490 {
491 if ( !warnedAboutMainProjectArtifact )
492 {
493 final StringBuilder message = new StringBuilder();
494
495 message.append( "Configuration option 'appendAssemblyId' is set to false." );
496 message.append( "\nInstead of attaching the assembly file: " ).append( destFile );
497 message.append( ", it will become the file for main project artifact." );
498 message.append( "\nNOTE: If multiple descriptors or descriptor-formats are provided "
499 + "for this project, the value of this file will be "
500 + "non-deterministic!" );
501
502 getLog().warn( message );
503 warnedAboutMainProjectArtifact = true;
504 }
505
506 final File existingFile = project.getArtifact().getFile();
507 if ( ( existingFile != null ) && existingFile.exists() )
508 {
509 getLog().warn( "Replacing pre-existing project main-artifact file: " + existingFile
510 + "\nwith assembly file: " + destFile );
511 }
512
513 project.getArtifact().setFile( destFile );
514 }
515 else
516 {
517 projectHelper.attachArtifact( project, format, null, destFile );
518 }
519 }
520 else if ( attach )
521 {
522 getLog().warn( "Assembly file: " + destFile + " is not a regular file (it may be a directory). "
523 + "It cannot be attached to the project build for installation or "
524 + "deployment." );
525 }
526 }
527 }
528 catch ( final ArchiveCreationException e )
529 {
530 throw new MojoExecutionException( "Failed to create assembly: " + e.getMessage(), e );
531 }
532 catch ( final AssemblyFormattingException e )
533 {
534 throw new MojoExecutionException( "Failed to create assembly: " + e.getMessage(), e );
535 }
536 catch ( final InvalidAssemblerConfigurationException e )
537 {
538 throw new MojoFailureException( assembly, "Assembly is incorrectly configured: " + assembly.getId(),
539 "Assembly: " + assembly.getId() + " is not configured correctly: "
540 + e.getMessage() );
541 }
542 }
543 }
544
545 private FixedStringSearchInterpolator createRepositoryInterpolator()
546 {
547 final Properties settingsProperties = new Properties();
548 final MavenSession session = getMavenSession();
549
550 if ( getLocalRepository() != null )
551 {
552 settingsProperties.setProperty( "localRepository", getLocalRepository().getBasedir() );
553 settingsProperties.setProperty( "settings.localRepository", getLocalRepository().getBasedir() );
554 }
555 else if ( session != null && session.getSettings() != null )
556 {
557 settingsProperties.setProperty( "localRepository", session.getSettings().getLocalRepository() );
558 settingsProperties.setProperty( "settings.localRepository", getLocalRepository().getBasedir() );
559 }
560
561 return FixedStringSearchInterpolator.create( new PropertiesBasedValueSource( settingsProperties ) );
562
563 }
564
565 private FixedStringSearchInterpolator createCommandLinePropertiesInterpolator()
566 {
567 Properties commandLineProperties = System.getProperties();
568 final MavenSession session = getMavenSession();
569
570 if ( session != null )
571 {
572 commandLineProperties = new Properties();
573 commandLineProperties.putAll( session.getSystemProperties() );
574 commandLineProperties.putAll( session.getUserProperties() );
575 }
576
577 PropertiesBasedValueSource cliProps = new PropertiesBasedValueSource( commandLineProperties );
578 return FixedStringSearchInterpolator.create( cliProps );
579
580 }
581
582 private FixedStringSearchInterpolator createEnvInterpolator()
583 {
584 PrefixedPropertiesValueSource envProps = new PrefixedPropertiesValueSource( Collections.singletonList( "env." ),
585 CommandLineUtils.getSystemEnvVars(
586 false ), true );
587 return FixedStringSearchInterpolator.create( envProps );
588 }
589
590
591
592
593
594
595 boolean isThisTheExecutionRoot()
596 {
597 final Log log = getLog();
598 log.debug( "Root Folder:" + mavenSession.getExecutionRootDirectory() );
599 log.debug( "Current Folder:" + basedir );
600 final boolean result = mavenSession.getExecutionRootDirectory().equalsIgnoreCase( basedir.toString() );
601 if ( result )
602 {
603 log.debug( "This is the execution root." );
604 }
605 else
606 {
607 log.debug( "This is NOT the execution root." );
608 }
609
610 return result;
611 }
612
613 @Override
614 public File getBasedir()
615 {
616 return basedir;
617 }
618
619 public void setBasedir( final File basedir )
620 {
621 this.basedir = basedir;
622 }
623
624 @Override
625 public String[] getDescriptorReferences()
626 {
627 return descriptorRefs;
628 }
629
630 @Override
631 public File getDescriptorSourceDirectory()
632 {
633 return descriptorSourceDirectory;
634 }
635
636 @Override
637 public String[] getDescriptors()
638 {
639 return descriptors;
640 }
641
642 public void setDescriptors( final String[] descriptors )
643 {
644 this.descriptors = descriptors;
645 }
646
647 @Override
648 public abstract MavenProject getProject();
649
650 @Override
651 public File getSiteDirectory()
652 {
653 return siteDirectory;
654 }
655
656 public void setSiteDirectory( final File siteDirectory )
657 {
658 this.siteDirectory = siteDirectory;
659 }
660
661 @Override
662 public String getFinalName()
663 {
664 return finalName;
665 }
666
667 public void setFinalName( final String finalName )
668 {
669 this.finalName = finalName;
670 }
671
672 @Override
673 public boolean isAssemblyIdAppended()
674 {
675 return appendAssemblyId;
676 }
677
678 @Override
679 public String getTarLongFileMode()
680 {
681 return tarLongFileMode;
682 }
683
684 public void setTarLongFileMode( final String tarLongFileMode )
685 {
686 this.tarLongFileMode = tarLongFileMode;
687 }
688
689 @Override
690 public File getOutputDirectory()
691 {
692 return outputDirectory;
693 }
694
695 public void setOutputDirectory( final File outputDirectory )
696 {
697 this.outputDirectory = outputDirectory;
698 }
699
700 @Override
701 public MavenArchiveConfiguration getJarArchiveConfiguration()
702 {
703 return archive;
704 }
705
706 @Override
707 public File getWorkingDirectory()
708 {
709 return workDirectory;
710 }
711
712 @Override
713 public ArtifactRepository getLocalRepository()
714 {
715 return localRepository;
716 }
717
718 public void setLocalRepository( final ArtifactRepository localRepository )
719 {
720 this.localRepository = localRepository;
721 }
722
723 @Override
724 public File getTemporaryRootDirectory()
725 {
726 return tempRoot;
727 }
728
729 @Override
730 public File getArchiveBaseDirectory()
731 {
732 return archiveBaseDirectory;
733 }
734
735 @Override
736 public List<String> getFilters()
737 {
738 if ( filters == null )
739 {
740 filters = getProject().getBuild().getFilters();
741 if ( filters == null )
742 {
743 filters = Collections.emptyList();
744 }
745 }
746 return filters;
747 }
748
749 public void setFilters( final List<String> filters )
750 {
751 this.filters = filters;
752 }
753
754 @Override
755 public boolean isIncludeProjectBuildFilters()
756 {
757 return includeProjectBuildFilters;
758 }
759
760 @Override
761 public List<MavenProject> getReactorProjects()
762 {
763 return reactorProjects;
764 }
765
766 public void setReactorProjects( final List<MavenProject> reactorProjects )
767 {
768 this.reactorProjects = reactorProjects;
769 }
770
771 public void setAppendAssemblyId( final boolean appendAssemblyId )
772 {
773 this.appendAssemblyId = appendAssemblyId;
774 }
775
776 public void setArchive( final MavenArchiveConfiguration archive )
777 {
778 this.archive = archive;
779 }
780
781 public void setDescriptorRefs( final String[] descriptorRefs )
782 {
783 this.descriptorRefs = descriptorRefs;
784 }
785
786 public void setTempRoot( final File tempRoot )
787 {
788 this.tempRoot = tempRoot;
789 }
790
791 public void setWorkDirectory( final File workDirectory )
792 {
793 this.workDirectory = workDirectory;
794 }
795
796 @Override
797 public List<ArtifactRepository> getRemoteRepositories()
798 {
799 return remoteRepositories;
800 }
801
802 @Override
803 public boolean isDryRun()
804 {
805 return dryRun;
806 }
807
808 @Override
809 public boolean isIgnoreDirFormatExtensions()
810 {
811 return ignoreDirFormatExtensions;
812 }
813
814 @Override
815 public boolean isIgnoreMissingDescriptor()
816 {
817 return ignoreMissingDescriptor;
818 }
819
820 @Override
821 public MavenSession getMavenSession()
822 {
823 return mavenSession;
824 }
825
826 @Override
827 public String getArchiverConfig()
828 {
829 return archiverConfig == null ? null : archiverConfig.toString();
830 }
831
832 @Override
833 public MavenReaderFilter getMavenReaderFilter()
834 {
835 return mavenReaderFilter;
836 }
837
838 @Override
839 public boolean isUpdateOnly()
840 {
841 return updateOnly;
842 }
843
844 @Override
845 public boolean isUseJvmChmod()
846 {
847 return useJvmChmod;
848 }
849
850 @Override
851 public boolean isIgnorePermissions()
852 {
853 return ignorePermissions;
854 }
855
856 @Override
857 public String getEncoding()
858 {
859 return encoding;
860 }
861
862 boolean isRecompressZippedFiles()
863 {
864 return recompressZippedFiles;
865 }
866
867 public String getMergeManifestMode()
868 {
869 return mergeManifestMode;
870 }
871
872 @Override
873 public String getEscapeString()
874 {
875 return escapeString;
876 }
877
878 @Override
879 public List<String> getDelimiters()
880 {
881 return delimiters;
882 }
883
884 public void setDelimiters( List<String> delimiters )
885 {
886 this.delimiters = delimiters;
887 }
888
889 @Override
890 @Nonnull
891 public FixedStringSearchInterpolator getCommandLinePropsInterpolator()
892 {
893 if ( commanndLinePropertiesInterpolator == null )
894 {
895 this.commanndLinePropertiesInterpolator = createCommandLinePropertiesInterpolator();
896 }
897 return commanndLinePropertiesInterpolator;
898 }
899
900 @Override
901 @Nonnull
902 public FixedStringSearchInterpolator getEnvInterpolator()
903 {
904 if ( envInterpolator == null )
905 {
906 this.envInterpolator = createEnvInterpolator();
907 }
908 return envInterpolator;
909 }
910
911 @Override
912 @Nonnull
913 public FixedStringSearchInterpolator getRepositoryInterpolator()
914 {
915 if ( rootInterpolator == null )
916 {
917 this.rootInterpolator = createRepositoryInterpolator();
918 }
919 return rootInterpolator;
920 }
921
922 @Override
923 @Nonnull
924 public FixedStringSearchInterpolator getMainProjectInterpolator()
925 {
926 if ( mainProjectInterpolator == null )
927 {
928 this.mainProjectInterpolator = mainProjectInterpolator( getProject() );
929 }
930 return mainProjectInterpolator;
931 }
932
933 }