1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package io.wcm.devops.conga.tooling.maven.plugin;
21
22 import static io.wcm.devops.conga.tooling.maven.plugin.BuildConstants.CLASSIFIER_CONFIGURATION;
23 import static io.wcm.devops.conga.tooling.maven.plugin.BuildConstants.FILE_EXTENSION_CONFIGURATION;
24 import static io.wcm.devops.conga.tooling.maven.plugin.BuildConstants.PACKAGING_CONFIGURATION;
25
26 import java.io.File;
27 import java.io.IOException;
28 import java.nio.file.Files;
29 import java.util.Arrays;
30 import java.util.List;
31 import java.util.Set;
32 import java.util.stream.Collectors;
33
34 import javax.inject.Inject;
35 import javax.inject.Named;
36
37 import org.apache.commons.lang3.StringUtils;
38 import org.apache.maven.plugin.MojoExecutionException;
39 import org.apache.maven.plugin.MojoFailureException;
40 import org.apache.maven.plugins.annotations.LifecyclePhase;
41 import org.apache.maven.plugins.annotations.Mojo;
42 import org.apache.maven.plugins.annotations.Parameter;
43 import org.apache.maven.project.MavenProject;
44 import org.codehaus.plexus.archiver.ArchiverException;
45 import org.codehaus.plexus.archiver.zip.ZipArchiver;
46
47 import io.wcm.devops.conga.generator.util.FileUtil;
48
49
50
51
52 @Mojo(name = "package", defaultPhase = LifecyclePhase.PACKAGE, requiresProject = true, threadSafe = true)
53 public class PackageMojo extends AbstractCongaMojo {
54
55
56
57
58 @Parameter(property = "conga.environments")
59 private String[] environments;
60
61
62
63
64
65 @Parameter(defaultValue = "true")
66 private boolean artifactPerEnvironment;
67
68 @Inject
69 @Named("zip")
70 private ZipArchiver zipArchiver;
71
72 @Override
73 @SuppressWarnings("PMD.UseStringBufferForStringAppends")
74 public void execute() throws MojoExecutionException, MojoFailureException {
75
76
77 buildGeneratedConfigurationAttachments();
78
79 }
80
81
82 @SuppressWarnings({
83 "PMD.UseStringBufferForStringAppends",
84 "java:S3776"
85 })
86 private void buildGeneratedConfigurationAttachments() throws MojoExecutionException, MojoFailureException {
87 Set<String> selectedEnvironments;
88 if (environments != null && environments.length > 0) {
89 selectedEnvironments = Set.copyOf(Arrays.asList(environments));
90 }
91 else {
92 selectedEnvironments = null;
93 }
94
95
96 File configRootDir = getTargetDir();
97 List<File> environmentDirs = Arrays.stream(configRootDir.listFiles())
98 .filter(File::isDirectory)
99 .filter(dir -> selectedEnvironments == null || selectedEnvironments.contains(dir.getName()))
100 .collect(Collectors.toList());
101
102 MavenProject project = getProject();
103 if (artifactPerEnvironment) {
104
105 for (File environmentDir : environmentDirs) {
106
107
108
109 String classifier = environmentDir.getName();
110 if (!StringUtils.equals(project.getPackaging(), PACKAGING_CONFIGURATION)) {
111 classifier = CLASSIFIER_CONFIGURATION + "-" + classifier;
112 }
113 validateClassifier(classifier);
114
115
116 File outputFile = buildZipFile(environmentDir, classifier);
117
118
119 projectHelper.attachArtifact(project, outputFile, classifier);
120
121 }
122
123
124 buildDefinitionsJarFile();
125
126 }
127 else {
128
129 String classifier = null;
130 if (!StringUtils.equals(project.getPackaging(), PACKAGING_CONFIGURATION)) {
131 classifier = CLASSIFIER_CONFIGURATION;
132 }
133 validateClassifier(classifier);
134
135 File outputFile = buildZipFile(configRootDir, classifier);
136
137 if (StringUtils.equals(project.getPackaging(), PACKAGING_CONFIGURATION)) {
138 project.getArtifact().setFile(outputFile);
139 }
140 else {
141 projectHelper.attachArtifact(project, outputFile, CLASSIFIER_CONFIGURATION);
142 }
143 }
144
145 }
146
147
148
149
150
151
152 private File buildZipFile(File contentDirectory, String classifier) throws MojoExecutionException {
153 File zipFile = new File(getProject().getBuild().getDirectory(), buildZipFileName(classifier));
154
155 String basePath = toZipDirectoryPath(contentDirectory);
156 addZipDirectory(basePath, contentDirectory);
157 zipArchiver.setDestFile(zipFile);
158 try {
159 zipArchiver.createArchive();
160 }
161 catch (ArchiverException | IOException ex) {
162 throw new MojoExecutionException("Unable to build file " + zipFile.getPath() + ": " + ex.getMessage(), ex);
163 }
164
165 return zipFile;
166 }
167
168
169
170
171
172
173
174
175 @SuppressWarnings("java:S3776")
176 private void addZipDirectory(String basePath, File directory) throws MojoExecutionException {
177 String directoryPath = toZipDirectoryPath(directory);
178 if (StringUtils.startsWith(directoryPath, basePath)) {
179 String relativeDirectoryPath = StringUtils.substring(directoryPath, basePath.length());
180 File[] files = directory.listFiles();
181 if (files != null) {
182 for (File file : files) {
183 if (file.isDirectory()) {
184 addZipDirectory(basePath, file);
185 }
186 else if (Files.isSymbolicLink(file.toPath())) {
187
188 try {
189 zipArchiver.addFile(file.toPath().toRealPath().toFile(), relativeDirectoryPath + file.getName());
190 }
191 catch (IOException ex) {
192 throw new MojoExecutionException("Unable to include symlinked file " + FileUtil.getCanonicalPath(file), ex);
193 }
194 }
195 else {
196 zipArchiver.addFile(file, relativeDirectoryPath + file.getName());
197 }
198 }
199 }
200 }
201 }
202
203 private String toZipDirectoryPath(File directory) {
204 String canoncialPath = FileUtil.getCanonicalPath(directory);
205 return StringUtils.replace(canoncialPath, "\\", "/") + "/";
206 }
207
208 private String buildZipFileName(String classifier) {
209 StringBuilder sb = new StringBuilder();
210 sb.append(getProject().getBuild().getFinalName());
211 if (StringUtils.isNotBlank(classifier)) {
212 sb.append("-").append(classifier);
213 }
214 sb.append(".").append(FILE_EXTENSION_CONFIGURATION);
215 return sb.toString();
216 }
217
218 private void validateClassifier(String classifier) throws MojoExecutionException {
219
220 if (StringUtils.contains(classifier, ".")) {
221 throw new MojoExecutionException("Classifier must not contain dots: " + classifier);
222 }
223 }
224
225 }