1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.assembly.mojos;
20
21 import java.io.File;
22 import java.nio.file.attribute.FileTime;
23 import java.util.Collections;
24 import java.util.List;
25 import java.util.Properties;
26
27 import org.apache.maven.archiver.MavenArchiveConfiguration;
28 import org.apache.maven.archiver.MavenArchiver;
29 import org.apache.maven.execution.MavenSession;
30 import org.apache.maven.plugin.AbstractMojo;
31 import org.apache.maven.plugin.MojoExecutionException;
32 import org.apache.maven.plugin.MojoFailureException;
33 import org.apache.maven.plugin.logging.Log;
34 import org.apache.maven.plugins.annotations.Component;
35 import org.apache.maven.plugins.annotations.Parameter;
36 import org.apache.maven.plugins.assembly.AssemblerConfigurationSource;
37 import org.apache.maven.plugins.assembly.InvalidAssemblerConfigurationException;
38 import org.apache.maven.plugins.assembly.archive.ArchiveCreationException;
39 import org.apache.maven.plugins.assembly.archive.AssemblyArchiver;
40 import org.apache.maven.plugins.assembly.format.AssemblyFormattingException;
41 import org.apache.maven.plugins.assembly.io.AssemblyReadException;
42 import org.apache.maven.plugins.assembly.io.AssemblyReader;
43 import org.apache.maven.plugins.assembly.model.Assembly;
44 import org.apache.maven.plugins.assembly.utils.AssemblyFormatUtils;
45 import org.apache.maven.plugins.assembly.utils.InterpolationConstants;
46 import org.apache.maven.project.MavenProject;
47 import org.apache.maven.project.MavenProjectHelper;
48 import org.apache.maven.shared.filtering.MavenReaderFilter;
49 import org.codehaus.plexus.configuration.PlexusConfiguration;
50 import org.codehaus.plexus.interpolation.fixed.FixedStringSearchInterpolator;
51 import org.codehaus.plexus.interpolation.fixed.PrefixedPropertiesValueSource;
52 import org.codehaus.plexus.interpolation.fixed.PropertiesBasedValueSource;
53 import org.codehaus.plexus.util.cli.CommandLineUtils;
54
55
56
57
58
59 public abstract class AbstractAssemblyMojo extends AbstractMojo implements AssemblerConfigurationSource {
60
61 protected FixedStringSearchInterpolator commandLinePropertiesInterpolator;
62
63 protected FixedStringSearchInterpolator envInterpolator;
64
65 protected FixedStringSearchInterpolator mainProjectInterpolator;
66
67 protected FixedStringSearchInterpolator rootInterpolator;
68
69
70
71
72
73
74 @Parameter(property = "assembly.appendAssemblyId", defaultValue = "true")
75 boolean appendAssemblyId;
76
77
78
79
80 @Parameter(property = "encoding", defaultValue = "${project.build.sourceEncoding}")
81 private String encoding;
82
83
84
85
86
87
88
89 @Parameter(property = "assembly.escapeString")
90 private String escapeString;
91
92
93
94
95
96 @Parameter(property = "assembly.skipAssembly", defaultValue = "false")
97 private boolean skipAssembly;
98
99
100
101
102 @Parameter(property = "assembly.dryRun", defaultValue = "false")
103 private boolean dryRun;
104
105
106
107
108
109
110 @Parameter(defaultValue = "true")
111 private boolean ignoreDirFormatExtensions;
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
129
130 @Parameter(defaultValue = "${project.build.finalName}", required = true)
131 private String finalName;
132
133
134
135
136 @Parameter(defaultValue = "${project.build.directory}/assembly/work", required = true)
137 private File workDirectory;
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154 @Parameter
155 private List<String> formats;
156
157
158
159
160 @Parameter
161 private String[] descriptors;
162
163
164
165
166
167
168
169 @Parameter
170 private String[] descriptorRefs;
171
172
173
174
175
176
177
178
179 @Parameter
180 private List<Assembly> inlineDescriptors;
181
182
183
184
185 @Parameter
186 private File descriptorSourceDirectory;
187
188
189
190
191
192 @Parameter
193 private File archiveBaseDirectory;
194
195
196
197
198
199 @Parameter(property = "assembly.tarLongFileMode", defaultValue = "warn")
200 private String tarLongFileMode;
201
202
203
204
205 @Parameter(defaultValue = "${project.basedir}", required = true, readonly = true)
206 private File basedir;
207
208
209
210
211 @Component
212 private MavenProjectHelper projectHelper;
213
214
215
216
217 @Component
218 private MavenReaderFilter mavenReaderFilter;
219
220
221
222
223 @Parameter(defaultValue = "${session}", readonly = true, required = true)
224 private MavenSession mavenSession;
225
226
227
228
229 @Parameter(defaultValue = "${project.build.directory}/archive-tmp", required = true, readonly = true)
230 private File tempRoot;
231
232
233
234
235 @Parameter(defaultValue = "${project.reporting.outputDirectory}", readonly = true)
236 private File siteDirectory;
237
238
239
240
241 @Parameter(property = "assembly.ignoreMissingDescriptor", defaultValue = "false")
242 private boolean ignoreMissingDescriptor;
243
244
245
246
247
248
249 @Parameter
250 private MavenArchiveConfiguration archive;
251
252
253
254
255
256
257
258 @Parameter
259 private List<String> filters;
260
261
262
263
264
265
266 @Parameter
267 private Properties additionalProperties;
268
269
270
271
272
273
274
275 @Parameter(property = "assembly.includeProjectBuildFilters", defaultValue = "true")
276 private boolean includeProjectBuildFilters;
277
278
279
280
281
282
283 @Parameter(property = "assembly.attach", defaultValue = "true")
284 private boolean attach;
285
286
287
288
289
290
291
292 @Parameter(defaultValue = "true")
293 private boolean recompressZippedFiles;
294
295
296
297
298
299
300 @Parameter
301 private String mergeManifestMode;
302
303
304
305
306 @Component
307 private AssemblyArchiver assemblyArchiver;
308
309
310
311
312 @Component
313 private AssemblyReader assemblyReader;
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332 @Parameter
333 private PlexusConfiguration archiverConfig;
334
335
336
337
338
339
340
341 @Parameter(property = "assembly.runOnlyAtExecutionRoot", defaultValue = "false")
342 private boolean runOnlyAtExecutionRoot;
343
344
345
346
347
348
349
350
351
352
353 @Parameter(property = "assembly.updateOnly", defaultValue = "false")
354 private boolean updateOnly;
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
406
407
408 @Parameter
409 private Integer overrideUid;
410
411
412
413
414 @Parameter
415 private String overrideUserName;
416
417
418
419
420 @Parameter
421 private Integer overrideGid;
422
423
424
425
426 @Parameter
427 private String overrideGroupName;
428
429 public static FixedStringSearchInterpolator mainProjectInterpolator(MavenProject mainProject) {
430 if (mainProject != null) {
431
432 return FixedStringSearchInterpolator.create(
433 new org.codehaus.plexus.interpolation.fixed.PrefixedObjectValueSource(
434 InterpolationConstants.PROJECT_PREFIXES, mainProject, true),
435
436
437 new org.codehaus.plexus.interpolation.fixed.PrefixedPropertiesValueSource(
438 InterpolationConstants.PROJECT_PROPERTIES_PREFIXES, mainProject.getProperties(), true));
439 } else {
440 return FixedStringSearchInterpolator.empty();
441 }
442 }
443
444
445
446
447 @Override
448 public void execute() throws MojoExecutionException, MojoFailureException {
449
450 if (skipAssembly) {
451 getLog().info("Assemblies have been skipped per configuration of the skipAssembly parameter.");
452 return;
453 }
454
455
456 if (runOnlyAtExecutionRoot && !isThisTheExecutionRoot()) {
457 getLog().info("Skipping the assembly in this project because it's not the Execution Root");
458 return;
459 }
460
461 List<Assembly> assemblies;
462 try {
463 assemblies = assemblyReader.readAssemblies(this);
464 } catch (final AssemblyReadException e) {
465 throw new MojoExecutionException("Error reading assemblies: " + e.getMessage(), e);
466 } catch (final InvalidAssemblerConfigurationException e) {
467 throw new MojoFailureException(
468 assemblyReader, e.getMessage(), "Mojo configuration is invalid: " + e.getMessage());
469 }
470
471
472
473
474 FileTime outputDate = MavenArchiver.parseBuildOutputTimestamp(outputTimestamp)
475 .map(FileTime::from)
476 .orElse(null);
477
478 boolean warnedAboutMainProjectArtifact = false;
479 for (final Assembly assembly : assemblies) {
480 try {
481 final String fullName = AssemblyFormatUtils.getDistributionName(assembly, this);
482
483 List<String> effectiveFormats = formats;
484 if (effectiveFormats == null || effectiveFormats.isEmpty()) {
485 effectiveFormats = assembly.getFormats();
486 }
487 if (effectiveFormats == null || effectiveFormats.isEmpty()) {
488 throw new MojoFailureException(
489 "No formats specified in the execution parameters or the assembly descriptor.");
490 }
491
492 for (final String format : effectiveFormats) {
493 final File destFile = assemblyArchiver.createArchive(assembly, fullName, format, this, outputDate);
494
495 final MavenProject project = getProject();
496 final String type = project.getArtifact().getType();
497
498 if (attach && destFile.isFile()) {
499 if (isAssemblyIdAppended()) {
500 projectHelper.attachArtifact(project, format, assembly.getId(), destFile);
501 } else if (!"pom".equals(type) && format.equals(type)) {
502 if (!warnedAboutMainProjectArtifact) {
503 final StringBuilder message = new StringBuilder();
504
505 message.append("Configuration option 'appendAssemblyId' is set to false.");
506 message.append("\nInstead of attaching the assembly file: ")
507 .append(destFile);
508 message.append(", it will become the file for main project artifact.");
509 message.append("\nNOTE: If multiple descriptors or descriptor-formats are provided "
510 + "for this project, the value of this file will be "
511 + "non-deterministic!");
512
513 getLog().warn(message);
514 warnedAboutMainProjectArtifact = true;
515 }
516
517 final File existingFile = project.getArtifact().getFile();
518 if ((existingFile != null) && existingFile.exists()) {
519 getLog().warn("Replacing pre-existing project main-artifact file: " + existingFile
520 + "\nwith assembly file: " + destFile);
521 }
522
523 project.getArtifact().setFile(destFile);
524 } else {
525 projectHelper.attachArtifact(project, format, null, destFile);
526 }
527 } else if (attach) {
528 getLog().warn("Assembly file: " + destFile + " is not a regular file (it may be a directory). "
529 + "It cannot be attached to the project build for installation or "
530 + "deployment.");
531 }
532 }
533 } catch (final ArchiveCreationException | AssemblyFormattingException e) {
534 throw new MojoExecutionException("Failed to create assembly: " + e.getMessage(), e);
535 } catch (final InvalidAssemblerConfigurationException e) {
536 throw new MojoFailureException(
537 assembly,
538 "Assembly is incorrectly configured: " + assembly.getId(),
539 "Assembly: " + assembly.getId() + " is not configured correctly: " + e.getMessage());
540 }
541 }
542 }
543
544 private FixedStringSearchInterpolator createRepositoryInterpolator() {
545 final Properties settingsProperties = new Properties();
546 final MavenSession session = getMavenSession();
547 final File basedir = session.getRepositorySession()
548 .getLocalRepositoryManager()
549 .getRepository()
550 .getBasedir();
551
552 settingsProperties.setProperty("localRepository", basedir.toString());
553 settingsProperties.setProperty("settings.localRepository", basedir.toString());
554
555 return FixedStringSearchInterpolator.create(new PropertiesBasedValueSource(settingsProperties));
556 }
557
558 private FixedStringSearchInterpolator createCommandLinePropertiesInterpolator() {
559 Properties commandLineProperties = System.getProperties();
560 final MavenSession session = getMavenSession();
561
562 if (session != null) {
563 commandLineProperties = new Properties();
564 commandLineProperties.putAll(session.getSystemProperties());
565 commandLineProperties.putAll(session.getUserProperties());
566 }
567
568 PropertiesBasedValueSource cliProps = new PropertiesBasedValueSource(commandLineProperties);
569 return FixedStringSearchInterpolator.create(cliProps);
570 }
571
572 private FixedStringSearchInterpolator createEnvInterpolator() {
573 PrefixedPropertiesValueSource envProps = new PrefixedPropertiesValueSource(
574 Collections.singletonList("env."), CommandLineUtils.getSystemEnvVars(false), true);
575 return FixedStringSearchInterpolator.create(envProps);
576 }
577
578
579
580
581
582
583 boolean isThisTheExecutionRoot() {
584 final Log log = getLog();
585 log.debug("Root Folder:" + mavenSession.getExecutionRootDirectory());
586 log.debug("Current Folder:" + basedir);
587 final boolean result = mavenSession.getExecutionRootDirectory().equalsIgnoreCase(basedir.toString());
588 if (result) {
589 log.debug("This is the execution root.");
590 } else {
591 log.debug("This is NOT the execution root.");
592 }
593
594 return result;
595 }
596
597 @Override
598 public File getBasedir() {
599 return basedir;
600 }
601
602 public void setBasedir(final File basedir) {
603 this.basedir = basedir;
604 }
605
606 @Override
607 public String[] getDescriptorReferences() {
608 return descriptorRefs;
609 }
610
611 public List<Assembly> getInlineDescriptors() {
612 return inlineDescriptors;
613 }
614
615 @Override
616 public File getDescriptorSourceDirectory() {
617 return descriptorSourceDirectory;
618 }
619
620 @Override
621 public String[] getDescriptors() {
622 return descriptors;
623 }
624
625 public void setDescriptors(final String[] descriptors) {
626 this.descriptors = descriptors;
627 }
628
629 @Override
630 public File getSiteDirectory() {
631 return siteDirectory;
632 }
633
634 public void setSiteDirectory(final File siteDirectory) {
635 this.siteDirectory = siteDirectory;
636 }
637
638 @Override
639 public String getFinalName() {
640 return finalName;
641 }
642
643 public void setFinalName(final String finalName) {
644 this.finalName = finalName;
645 }
646
647 @Override
648 public boolean isAssemblyIdAppended() {
649 return appendAssemblyId;
650 }
651
652 @Override
653 public String getTarLongFileMode() {
654 return tarLongFileMode;
655 }
656
657 public void setTarLongFileMode(final String tarLongFileMode) {
658 this.tarLongFileMode = tarLongFileMode;
659 }
660
661 @Override
662 public File getOutputDirectory() {
663 return outputDirectory;
664 }
665
666 public void setOutputDirectory(final File outputDirectory) {
667 this.outputDirectory = outputDirectory;
668 }
669
670 @Override
671 public MavenArchiveConfiguration getJarArchiveConfiguration() {
672 return archive;
673 }
674
675 @Override
676 public File getWorkingDirectory() {
677 return workDirectory;
678 }
679
680 @Override
681 public File getTemporaryRootDirectory() {
682 return tempRoot;
683 }
684
685 @Override
686 public File getArchiveBaseDirectory() {
687 return archiveBaseDirectory;
688 }
689
690 @Override
691 public List<String> getFilters() {
692 if (filters == null) {
693 filters = getProject().getBuild().getFilters();
694 if (filters == null) {
695 filters = Collections.emptyList();
696 }
697 }
698 return filters;
699 }
700
701 public void setFilters(final List<String> filters) {
702 this.filters = filters;
703 }
704
705 public Properties getAdditionalProperties() {
706 return additionalProperties;
707 }
708
709 @Override
710 public boolean isIncludeProjectBuildFilters() {
711 return includeProjectBuildFilters;
712 }
713
714 @Override
715 public List<MavenProject> getReactorProjects() {
716 return reactorProjects;
717 }
718
719 public void setReactorProjects(final List<MavenProject> reactorProjects) {
720 this.reactorProjects = reactorProjects;
721 }
722
723 public void setAppendAssemblyId(final boolean appendAssemblyId) {
724 this.appendAssemblyId = appendAssemblyId;
725 }
726
727 public void setArchive(final MavenArchiveConfiguration archive) {
728 this.archive = archive;
729 }
730
731 public void setDescriptorRefs(final String[] descriptorRefs) {
732 this.descriptorRefs = descriptorRefs;
733 }
734
735 public void setTempRoot(final File tempRoot) {
736 this.tempRoot = tempRoot;
737 }
738
739 public void setWorkDirectory(final File workDirectory) {
740 this.workDirectory = workDirectory;
741 }
742
743 @Override
744 public boolean isDryRun() {
745 return dryRun;
746 }
747
748 @Override
749 public boolean isIgnoreDirFormatExtensions() {
750 return ignoreDirFormatExtensions;
751 }
752
753 @Override
754 public boolean isIgnoreMissingDescriptor() {
755 return ignoreMissingDescriptor;
756 }
757
758 @Override
759 public MavenSession getMavenSession() {
760 return mavenSession;
761 }
762
763 @Override
764 public String getArchiverConfig() {
765 return archiverConfig == null ? null : archiverConfig.toString();
766 }
767
768 @Override
769 public MavenReaderFilter getMavenReaderFilter() {
770 return mavenReaderFilter;
771 }
772
773 @Override
774 public boolean isUpdateOnly() {
775 return updateOnly;
776 }
777
778 @Override
779 public boolean isIgnorePermissions() {
780 return ignorePermissions;
781 }
782
783 @Override
784 public String getEncoding() {
785 return encoding;
786 }
787
788 @Override
789 public boolean isRecompressZippedFiles() {
790 return recompressZippedFiles;
791 }
792
793 @Override
794 public String getMergeManifestMode() {
795 return mergeManifestMode;
796 }
797
798 @Override
799 public String getEscapeString() {
800 return escapeString;
801 }
802
803 @Override
804 public List<String> getDelimiters() {
805 return delimiters;
806 }
807
808 public void setDelimiters(List<String> delimiters) {
809 this.delimiters = delimiters;
810 }
811
812 @Override
813 public synchronized FixedStringSearchInterpolator getCommandLinePropsInterpolator() {
814 if (commandLinePropertiesInterpolator == null) {
815 this.commandLinePropertiesInterpolator = createCommandLinePropertiesInterpolator();
816 }
817 return commandLinePropertiesInterpolator;
818 }
819
820 @Override
821 public synchronized FixedStringSearchInterpolator getEnvInterpolator() {
822 if (envInterpolator == null) {
823 this.envInterpolator = createEnvInterpolator();
824 }
825 return envInterpolator;
826 }
827
828 @Override
829 public synchronized FixedStringSearchInterpolator getRepositoryInterpolator() {
830 if (rootInterpolator == null) {
831 this.rootInterpolator = createRepositoryInterpolator();
832 }
833 return rootInterpolator;
834 }
835
836 @Override
837 public synchronized FixedStringSearchInterpolator getMainProjectInterpolator() {
838 if (mainProjectInterpolator == null) {
839 this.mainProjectInterpolator = mainProjectInterpolator(getProject());
840 }
841 return mainProjectInterpolator;
842 }
843
844 @Override
845 public Integer getOverrideUid() {
846 return this.overrideUid;
847 }
848
849 @Override
850 public String getOverrideUserName() {
851 return this.overrideUserName;
852 }
853
854 @Override
855 public Integer getOverrideGid() {
856 return this.overrideGid;
857 }
858
859 @Override
860 public String getOverrideGroupName() {
861 return this.overrideGroupName;
862 }
863 }