/
CompileMojo.java
360 lines (300 loc) · 9.95 KB
/
CompileMojo.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
/*
* Copyright (c) 2008-2015 Sonatype, Inc. All rights reserved.
*
* This program is licensed to you under the Apache License Version 2.0,
* and you may not use this file except in compliance with the Apache License Version 2.0.
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the Apache License Version 2.0 is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
*/
package org.sonatype.install4j.maven;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Properties;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProjectHelper;
import org.apache.tools.ant.taskdefs.ExecTask;
/**
* Compile installers (via install4jc).
*
* Execution will skip if <code>install4j.home</code> location is invalid.
*
* @see <a href="http://resources.ej-technologies.com/install4j/help/doc/cli/options.html">install4j cli options</a>
* @since 1.0
*/
@Mojo(name = "compile")
public class CompileMojo
extends Install4jcMojoSupport
{
/**
* install4j project file.
*/
@Parameter(property = "install4j.projectFile", required = true)
private File projectFile;
/**
* Enables verbose mode. In verbose mode, install4j prints out information about internal processes.
*/
@Parameter(property = "install4j.verbose", defaultValue = "false")
private boolean verbose;
/**
* Enables quiet mode. In quiet mode, no terminal output short of a fatal error will be printed.
*/
@Parameter(property = "install4j.quiet", defaultValue = "false")
private boolean quiet;
/**
* Enables test mode. In test mode, no media files will be generated in the media file directory.
*/
@Parameter(property = "install4j.test", defaultValue = "false")
private boolean test;
/**
* Create additional debug installers for each media file.
*/
@Parameter(property = "install4j.debug", defaultValue = "false")
private boolean debug;
/**
* Disable LZMA and Pack200 compression.
*/
@Parameter(property = "install4j.faster", defaultValue = "false")
private boolean faster;
/**
* Disable code signing.
*/
@Parameter(property = "install4j.disableSigning", defaultValue = "false")
private boolean disableSigning;
/**
* Preserve temporary staging directory.
*/
@Parameter(property = "install4j.preserve", defaultValue = "false")
private boolean preserve;
/**
* Set the Windows keystore password for the private key that is configured for code signing.
*/
@Parameter(property = "install4j.winKeystorePassword")
private String winKeystorePassword;
/**
* Set the Mac OSX keystore password for the private key that is configured for code signing.
*/
@Parameter(property = "install4j.macKeystorePassword")
private String macKeystorePassword;
/**
* Override the application version.
*/
@Parameter(property = "install4j.release", defaultValue = "${project.version}")
private String release;
/**
* The output directory for the generated media files.
*/
@Parameter(property = "install4j.destination", defaultValue = "${project.build.directory}/media")
private File destination;
/**
* Only build the media files which have been selected in the install4j IDE.
*/
@Parameter(property = "install4j.buildSelected", defaultValue = "false")
private boolean buildSelected;
/**
* Only build the media files with the specified IDs.
*/
@Parameter(property = "install4j.buildIds")
private String buildIds;
/**
* Only build media files of the specified type.
*/
@Parameter(property = "install4j.mediaTypes")
private String mediaTypes;
/**
* Load variable definitions from a file.
*/
@Parameter(property = "install4j.variableFile")
private File variableFile;
/**
* Override compiler variables with a different values.
*/
@Parameter
private Properties variables;
/**
* Set custom jvm arguments on compiler.
*/
@Parameter
private List<String> jvmArguments;
/**
* Attach generated installers.
*
* Uses the media id as the classifier.
*/
@Parameter(property = "install4j.attach", defaultValue = "false")
private boolean attach;
@Component
private MavenProjectHelper projectHelper;
@Override
protected void execute(final AntHelper ant, final ExecTask task) throws Exception {
task.createArg().setFile(projectFile);
// Fail if any error occurs
task.setFailonerror(true);
task.setFailIfExecutionFails(true);
if (jvmArguments != null) {
Iterator<String> iter = jvmArguments.iterator();
while (iter.hasNext()) {
String arg = String.valueOf(iter.next());
task.createArg().setValue("-J" + arg);
}
}
if (verbose) {
task.createArg().setValue("--verbose");
}
if (quiet) {
task.createArg().setValue("--quiet");
}
if (test) {
task.createArg().setValue("--test");
}
if (debug) {
task.createArg().setValue("--debug");
}
if (faster) {
task.createArg().setValue("--faster");
}
if (disableSigning) {
task.createArg().setValue("--disable-signing");
}
if (preserve) {
task.createArg().setValue("--preserve");
}
if (winKeystorePassword != null) {
task.createArg().setValue("--win-keystore-password");
task.createArg().setValue(winKeystorePassword);
}
if (macKeystorePassword != null) {
task.createArg().setValue("--mac-keystore-password");
task.createArg().setValue(macKeystorePassword);
}
if (release != null) {
task.createArg().setValue("--release");
task.createArg().setValue(release);
}
if (destination != null) {
task.createArg().setValue("--destination");
task.createArg().setFile(destination);
}
if (buildSelected) {
task.createArg().setValue("--build-selected");
}
if (buildIds != null) {
task.createArg().setValue("--build-ids");
task.createArg().setValue(buildIds);
}
if (mediaTypes != null) {
task.createArg().setValue("--media-types");
task.createArg().setValue(mediaTypes);
}
if (variableFile != null) {
task.createArg().setValue("--var-file");
task.createArg().setFile(variableFile);
}
if (variables != null) {
task.createArg().setValue("-D");
task.createArg().setValue(getVariablesArgument());
}
task.execute();
if (attach) {
for (AttachedFile attachedFile : parseAttachedFiles()) {
projectHelper.attachArtifact(
project,
attachedFile.type,
attachedFile.classifier,
attachedFile.file
);
}
// attach non-media files which the compiler generates
maybeAttachFile("txt", "output", new File(destination, "output.txt"));
maybeAttachFile("xml", "updates", new File(destination, "updates.xml"));
maybeAttachFile("txt", "md5sums", new File(destination, "md5sums"));
}
}
private void maybeAttachFile(final String type, final String classifier, final File file) {
if (!file.exists()) {
log.warn("File missing; unable to attach file: " + file);
return;
}
projectHelper.attachArtifact(project, type, classifier, file);
}
/**
* Concatenates variable key=value into chain of comma separated for passing to {@code -D} flag.
*/
private String getVariablesArgument() {
StringBuilder buff = new StringBuilder();
Iterator<Entry<Object, Object>> iter = variables.entrySet().iterator();
while (iter.hasNext()) {
Entry<Object, Object> entry = iter.next();
buff.append(entry.getKey()).append('=').append(entry.getValue());
if (iter.hasNext()) {
buff.append(",");
}
}
return buff.toString();
}
private static class AttachedFile
{
public final File file;
public final String type;
public final String classifier;
private AttachedFile(final File file, final String classifier) {
this.file = file;
this.type = getType(file);
// TODO: Should ensure this is a valid classifier (replace spaces, etc).
this.classifier = classifier;
}
private AttachedFile(final String path, final String classifier) {
this(new File(path), classifier);
}
private static String getType(final File file) {
String path = file.getAbsolutePath();
// special case for compound '.' extensions
if (path.endsWith(".tar.gz")) {
return "tar.gz";
}
else if (path.endsWith(".tar.bz2")) {
return "tar.bz2";
}
int i = path.lastIndexOf(".");
return path.substring(i + 1, path.length());
}
}
private List<AttachedFile> parseAttachedFiles() throws Exception {
File file = new File(destination, "output.txt");
if (!file.exists()) {
log.warn("Missing output.txt file: " + file);
return Collections.emptyList();
}
log.debug("Parsing: " + file);
BufferedReader reader = new BufferedReader(new FileReader(file));
List<AttachedFile> files = new ArrayList<AttachedFile>();
String line;
while ((line = reader.readLine()) != null) {
if (line.startsWith("#")) {
// ignore comments
continue;
}
log.debug("Read: " + line);
// fields are tab-delimited:
// id | media file type | display name | media file path
String[] parts = line.split("\t");
AttachedFile attachedFile = new AttachedFile(
parts[3], // media file path
parts[0] // id
);
files.add(attachedFile);
}
return files;
}
}