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