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