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