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