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