mirror of
https://github.com/ethauvin/bld.git
synced 2025-04-25 08:17:11 -07:00
Merge pull request #45 from ethauvin/main
implementations of JpackageOperation, JmodOperation and JlinkOperation
This commit is contained in:
commit
c70b4f1c43
30 changed files with 2784 additions and 0 deletions
|
@ -0,0 +1,218 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Erik C. Thauvin (https://erik.thauvin.net/)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.operations;
|
||||||
|
|
||||||
|
import rife.bld.operations.exceptions.ExitStatusException;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.spi.ToolProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides common features for tool providers.
|
||||||
|
*
|
||||||
|
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
|
||||||
|
* @since 2.0.2
|
||||||
|
*/
|
||||||
|
public abstract class AbstractToolProviderOperation<T extends AbstractToolProviderOperation<T>>
|
||||||
|
extends AbstractOperation<AbstractToolProviderOperation<T>> {
|
||||||
|
private final List<String> toolArgs_ = new ArrayList<>();
|
||||||
|
private final String toolName_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the name of the tool.
|
||||||
|
*
|
||||||
|
* @param toolName the tool name
|
||||||
|
*/
|
||||||
|
public AbstractToolProviderOperation(String toolName) {
|
||||||
|
toolName_ = toolName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs an instance of the tool.
|
||||||
|
* <p>
|
||||||
|
* On success, command line arguments are automatically cleared.
|
||||||
|
*
|
||||||
|
* @throws Exception if an error occurred
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void execute() throws Exception {
|
||||||
|
if (toolArgs_.isEmpty()) {
|
||||||
|
System.err.println("No " + toolName_ + " command line arguments specified.");
|
||||||
|
throw new ExitStatusException(ExitStatusException.EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
var tool = ToolProvider.findFirst(toolName_).orElseThrow(() ->
|
||||||
|
new IllegalStateException("No " + toolName_ + " tool found."));
|
||||||
|
|
||||||
|
var status = tool.run(System.out, System.err, toolArgs_.toArray(new String[0]));
|
||||||
|
if (status != 0) {
|
||||||
|
System.out.println(tool.name() + ' ' + String.join(" ", toolArgs_));
|
||||||
|
}
|
||||||
|
|
||||||
|
ExitStatusException.throwOnFailure(status);
|
||||||
|
|
||||||
|
toolArgs_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds arguments to pass to the tool.
|
||||||
|
*
|
||||||
|
* @param arg one or more argument
|
||||||
|
* @return this operation
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public T toolArgs(String... arg) {
|
||||||
|
toolArgs(List.of(arg));
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds arguments to pass to the tool.
|
||||||
|
*
|
||||||
|
* @param args the argument to add
|
||||||
|
* @return this operation
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"unchecked", "UnusedReturnValue"})
|
||||||
|
public T toolArgs(List<String> args) {
|
||||||
|
toolArgs_.addAll(args);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the tool's arguments.
|
||||||
|
*
|
||||||
|
* @return the arguments
|
||||||
|
*/
|
||||||
|
public List<String> toolArgs() {
|
||||||
|
return toolArgs_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses arguments to pass to the tool from the given files.
|
||||||
|
*
|
||||||
|
* @param files the list of files
|
||||||
|
* @return this operation instance
|
||||||
|
* @throws FileNotFoundException if a file cannot be found
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"unchecked", "UnusedReturnValue"})
|
||||||
|
public T toolArgsFromFile(List<String> files) throws IOException {
|
||||||
|
var args = new ArrayList<String>();
|
||||||
|
|
||||||
|
for (var file : files) {
|
||||||
|
try (var reader = Files.newBufferedReader(Paths.get(file), Charset.defaultCharset())) {
|
||||||
|
var tokenizer = new CommandLineTokenizer(reader);
|
||||||
|
String token;
|
||||||
|
while ((token = tokenizer.nextToken()) != null) {
|
||||||
|
args.add(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toolArgs(args);
|
||||||
|
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds arguments to pass to the tool.
|
||||||
|
*
|
||||||
|
* @param args the argument-value pairs to add
|
||||||
|
* @return this operation
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"unchecked", "UnusedReturnValue"})
|
||||||
|
protected T toolArgs(Map<String, String> args) {
|
||||||
|
args.forEach((k, v) -> {
|
||||||
|
toolArgs_.add(k);
|
||||||
|
if (v != null && !v.isEmpty()) {
|
||||||
|
toolArgs_.add(v);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tokenize command line arguments.
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>Arguments containing spaces should be quoted</li>
|
||||||
|
* <li>Escape sequences and comments are supported</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public static class CommandLineTokenizer {
|
||||||
|
private final StringBuilder buf_ = new StringBuilder();
|
||||||
|
private final Reader input_;
|
||||||
|
private int ch_;
|
||||||
|
|
||||||
|
public CommandLineTokenizer(Reader input) throws IOException {
|
||||||
|
input_ = input;
|
||||||
|
ch_ = input.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String nextToken() throws IOException {
|
||||||
|
trimWhitespaceOrComments();
|
||||||
|
if (ch_ == -1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf_.setLength(0); // reset buffer
|
||||||
|
|
||||||
|
char quote = 0;
|
||||||
|
while (ch_ != -1) {
|
||||||
|
if (ch_ == '\'' || ch_ == '"') { // quotes
|
||||||
|
if (quote == 0) { // begin quote
|
||||||
|
quote = (char) ch_;
|
||||||
|
} else if (quote == ch_) { // end quote
|
||||||
|
quote = 0;
|
||||||
|
} else {
|
||||||
|
buf_.append((char) ch_);
|
||||||
|
}
|
||||||
|
} else if (ch_ == '\\') { // escaped
|
||||||
|
ch_ = input_.read();
|
||||||
|
buf_.append(handleEscapeSequence());
|
||||||
|
} else if (quote == 0 && Character.isWhitespace(ch_)) { // whitespaces
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
buf_.append((char) ch_);
|
||||||
|
}
|
||||||
|
ch_ = input_.read();
|
||||||
|
}
|
||||||
|
return buf_.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private char handleEscapeSequence() {
|
||||||
|
return switch (ch_) {
|
||||||
|
case -1 -> '\\';
|
||||||
|
case 'n' -> '\n';
|
||||||
|
case 'r' -> '\r';
|
||||||
|
case 't' -> '\t';
|
||||||
|
case 'f' -> '\f';
|
||||||
|
default -> (char) ch_;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void trimWhitespaceOrComments() throws IOException {
|
||||||
|
while (ch_ != -1) {
|
||||||
|
if (Character.isWhitespace(ch_)) { // Skip whitespaces
|
||||||
|
ch_ = input_.read();
|
||||||
|
} else if (ch_ == '#') {
|
||||||
|
// Skip the entire comment until a new line or end of input
|
||||||
|
do {
|
||||||
|
ch_ = input_.read();
|
||||||
|
} while (ch_ != -1 && ch_ != '\n' && ch_ != '\r');
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
89
src/main/java/rife/bld/operations/JlinkOperation.java
Normal file
89
src/main/java/rife/bld/operations/JlinkOperation.java
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Erik C. Thauvin (https://erik.thauvin.net/)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.operations;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create run-time images using the jlink tool.
|
||||||
|
*
|
||||||
|
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
|
||||||
|
* @since 2.0.2
|
||||||
|
*/
|
||||||
|
public class JlinkOperation extends AbstractToolProviderOperation<JlinkOperation> {
|
||||||
|
private final List<String> cmdFiles_ = new ArrayList<>();
|
||||||
|
private final List<String> disabledPlugins_ = new ArrayList<>();
|
||||||
|
private final JlinkOptions jlinkOptions_ = new JlinkOptions();
|
||||||
|
|
||||||
|
public JlinkOperation() {
|
||||||
|
super("jlink");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read options and/or mode from file(s).
|
||||||
|
*
|
||||||
|
* @param file one or more file
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
public JlinkOperation cmdFiles(String... file) {
|
||||||
|
cmdFiles_.addAll(List.of(file));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of files containing options or mode.
|
||||||
|
*
|
||||||
|
* @return the list of files
|
||||||
|
*/
|
||||||
|
public List<String> cmdFiles() {
|
||||||
|
return cmdFiles_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable the plugin mentioned.
|
||||||
|
*
|
||||||
|
* @param plugin the plugin name
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOperation disablePlugin(String... plugin) {
|
||||||
|
disabledPlugins_.addAll(List.of(plugin));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() throws Exception {
|
||||||
|
toolArgsFromFile(cmdFiles_);
|
||||||
|
disabledPlugins_.forEach(plugin -> toolArgs("--disable-plugin", plugin));
|
||||||
|
toolArgs(jlinkOptions_);
|
||||||
|
super.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a list of options to provide to the jlink tool.
|
||||||
|
* <p>
|
||||||
|
* A copy will be created to allow this list to be independently modifiable.
|
||||||
|
*
|
||||||
|
* @param options the argument-value pairs
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
public JlinkOperation jlinkOptions(Map<String, String> options) {
|
||||||
|
jlinkOptions_.putAll(options);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of options for the jlink tool.
|
||||||
|
* <p>
|
||||||
|
* This is a modifiable list that can be retrieved and changed.
|
||||||
|
*
|
||||||
|
* @return the map of jlink options
|
||||||
|
*/
|
||||||
|
public JlinkOptions jlinkOptions() {
|
||||||
|
return jlinkOptions_;
|
||||||
|
}
|
||||||
|
}
|
329
src/main/java/rife/bld/operations/JlinkOptions.java
Normal file
329
src/main/java/rife/bld/operations/JlinkOptions.java
Normal file
|
@ -0,0 +1,329 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Erik C. Thauvin (https://erik.thauvin.net/)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.operations;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for jlink tool.
|
||||||
|
*
|
||||||
|
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
|
||||||
|
* @since 2.0.2
|
||||||
|
*/
|
||||||
|
public class JlinkOptions extends HashMap<String, String> {
|
||||||
|
/**
|
||||||
|
* All Modules Path.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public final static String ALL_MODULE_PATH = "ALL-MODULE-PATH";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Root modules to resolve in addition to the initial modules.
|
||||||
|
* <p>
|
||||||
|
* Module can also be {@link #ALL_MODULE_PATH}
|
||||||
|
*
|
||||||
|
* @param modules one or more module
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions addModules(String... modules) {
|
||||||
|
put("--add-modules", String.join(",", modules));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link in service provider modules and their dependencies.
|
||||||
|
*
|
||||||
|
* @param bindServices {@code true} to bind services, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions bindServices(boolean bindServices) {
|
||||||
|
if (bindServices) {
|
||||||
|
put("--bind-services");
|
||||||
|
} else {
|
||||||
|
remove("--bind-services");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compression to use in compressing resources.
|
||||||
|
* <p>
|
||||||
|
* <b>Requires Java 21 or higher</b>. Use {@link #compress(CompressionLevel)} for lower versions.
|
||||||
|
* <p>
|
||||||
|
* Where {@link ZipCompression#ZIP_0 ZIP_0} provides no compression and {@link ZipCompression#ZIP_9 ZIP_9} provides
|
||||||
|
* the best compression.
|
||||||
|
* <p>Default is {@link ZipCompression#ZIP_6 ZIP_6}
|
||||||
|
*
|
||||||
|
* @param compression the {@link ZipCompression compression} level
|
||||||
|
* @return this map of options
|
||||||
|
* @see #compress(ZipCompression)
|
||||||
|
*/
|
||||||
|
public JlinkOptions compress(ZipCompression compression) {
|
||||||
|
put("--compress", compression.level);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable compression of resources.
|
||||||
|
* <p>
|
||||||
|
* Use {@link #compress(ZipCompression)} on Java 21 or higher.
|
||||||
|
*
|
||||||
|
* @param compression the {@link CompressionLevel compression} level
|
||||||
|
* @return this map of options
|
||||||
|
* @see #compress(CompressionLevel)
|
||||||
|
*/
|
||||||
|
public JlinkOptions compress(CompressionLevel compression) {
|
||||||
|
put("--compress", compression.level);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Byte order of generated jimage.
|
||||||
|
* <p>
|
||||||
|
* Default: native
|
||||||
|
*
|
||||||
|
* @param endian the byte order
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions endian(Endian endian) {
|
||||||
|
put("--endian", endian.byteOrder);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suppress a fatal error when signed modular JARs are linked in the image.
|
||||||
|
*
|
||||||
|
* @param ignoreSigningInformation {@code true} to ignore signing information, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions ignoreSigningInformation(boolean ignoreSigningInformation) {
|
||||||
|
if (ignoreSigningInformation) {
|
||||||
|
put("--ignore-signing-information");
|
||||||
|
} else {
|
||||||
|
remove("--ignore-signing-information");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a launcher command of the given name for the module.
|
||||||
|
*
|
||||||
|
* @param name the name
|
||||||
|
* @param module the module
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("UnusedReturnValue")
|
||||||
|
public JlinkOptions launcher(String name, String module) {
|
||||||
|
put("--launcher", name + "=" + module);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a launcher command of the given name for the module and the main class.
|
||||||
|
*
|
||||||
|
* @param name the name
|
||||||
|
* @param module the module
|
||||||
|
* @param mainClass the main class
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions launcher(String name, String module, String mainClass) {
|
||||||
|
put("--launcher", name + "=" + module + "/" + mainClass);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Limit the universe of observable modules.
|
||||||
|
*
|
||||||
|
* @param module one or more module
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions limitModule(String... module) {
|
||||||
|
put("--limit-modules", String.join(",", module));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module path.
|
||||||
|
* <p>
|
||||||
|
* If not specified, the JDKs jmods directory will be used, if it exists. If specified, but it does not contain the
|
||||||
|
* java.base module, the JDKs jmods directory will be added, if it exists.
|
||||||
|
*
|
||||||
|
* @param path the module path
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions modulePath(String path) {
|
||||||
|
put("--module-path", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exclude include header files.
|
||||||
|
*
|
||||||
|
* @param noHeaderFiles {@code true} to exclude header files, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions noHeaderFiles(boolean noHeaderFiles) {
|
||||||
|
if (noHeaderFiles) {
|
||||||
|
put("--no-header-files");
|
||||||
|
} else {
|
||||||
|
remove("--no-header-files");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exclude man pages.
|
||||||
|
*
|
||||||
|
* @param noManPages {@code true} to exclude man pages, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions noManPages(boolean noManPages) {
|
||||||
|
if (noManPages) {
|
||||||
|
put("--no-man-pages");
|
||||||
|
} else {
|
||||||
|
remove("--no-man-pages");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of output path.
|
||||||
|
*
|
||||||
|
* @param path the output path
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions output(String path) {
|
||||||
|
put("--output", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Associates {@code null} with the specified key in this map. If the map previously contained a mapping for the
|
||||||
|
* key, the old value is replaced.
|
||||||
|
*
|
||||||
|
* @param key key with which the specified value is to be associated
|
||||||
|
*/
|
||||||
|
public void put(String key) {
|
||||||
|
put(key, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suggest providers that implement the given service types from the module path.
|
||||||
|
*
|
||||||
|
* @param filename the filename
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions saveOpts(String filename) {
|
||||||
|
put("--save-opts", filename);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strip debug information.
|
||||||
|
*
|
||||||
|
* @param stripDebug {@code true} to strip debug info, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions stripDebug(boolean stripDebug) {
|
||||||
|
if (stripDebug) {
|
||||||
|
put("--strip-debug");
|
||||||
|
} else {
|
||||||
|
remove("--strip-debug");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strip native commands.
|
||||||
|
*
|
||||||
|
* @param stripNativeCommands {@code true} to strip, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions stripNativeCommands(boolean stripNativeCommands) {
|
||||||
|
if (stripNativeCommands) {
|
||||||
|
put("--strip-native-commands");
|
||||||
|
} else {
|
||||||
|
remove("--strip-native-commands");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suggest providers that implement the given service types from the module path.
|
||||||
|
*
|
||||||
|
* @param name one or more provider name
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions suggestProviders(String... name) {
|
||||||
|
put("--suggest-providers", String.join(",", name));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> toList() {
|
||||||
|
var list = new ArrayList<String>();
|
||||||
|
forEach((k, v) -> {
|
||||||
|
list.add(k);
|
||||||
|
if (v != null && !v.isEmpty()) {
|
||||||
|
list.add(v);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable verbose tracing.
|
||||||
|
*
|
||||||
|
* @param verbose {@code true} to enable verbose tracing, {@code false} otherwise.
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions verbose(boolean verbose) {
|
||||||
|
if (verbose) {
|
||||||
|
put("--verbose");
|
||||||
|
} else {
|
||||||
|
remove("--verbose");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The byte orders.
|
||||||
|
*/
|
||||||
|
public enum Endian {
|
||||||
|
BIG("big"), LITTLE("little");
|
||||||
|
|
||||||
|
public final String byteOrder;
|
||||||
|
|
||||||
|
Endian(String byteOrder) {
|
||||||
|
this.byteOrder = byteOrder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resources compression levels.
|
||||||
|
*/
|
||||||
|
public enum CompressionLevel {
|
||||||
|
/**
|
||||||
|
* Level 0: No compression
|
||||||
|
*/
|
||||||
|
NO_COMPRESSION("0"),
|
||||||
|
/**
|
||||||
|
* Level 1: Constant string sharing
|
||||||
|
*/
|
||||||
|
CONSTANT_STRING_SHARING("1"),
|
||||||
|
/**
|
||||||
|
* Level 2: ZIP
|
||||||
|
*/
|
||||||
|
ZIP("2");
|
||||||
|
|
||||||
|
public final String level;
|
||||||
|
|
||||||
|
CompressionLevel(String level) {
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
153
src/main/java/rife/bld/operations/JmodOperation.java
Normal file
153
src/main/java/rife/bld/operations/JmodOperation.java
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Erik C. Thauvin (https://erik.thauvin.net/)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.operations;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create JMOD files with the jmod tool.
|
||||||
|
*
|
||||||
|
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
|
||||||
|
* @since 2.0.2
|
||||||
|
*/
|
||||||
|
public class JmodOperation extends AbstractToolProviderOperation<JmodOperation> {
|
||||||
|
private final List<String> cmdFiles = new ArrayList<>();
|
||||||
|
private final JmodOptions jmodOptions_ = new JmodOptions();
|
||||||
|
private String jmodFile_;
|
||||||
|
private OperationMode operationMode_;
|
||||||
|
|
||||||
|
public JmodOperation() {
|
||||||
|
super("jmod");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of files containing options or mode.
|
||||||
|
*
|
||||||
|
* @return the list of files
|
||||||
|
*/
|
||||||
|
public List<String> cmdFiles() {
|
||||||
|
return cmdFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read options and/or mode from file(s).
|
||||||
|
*
|
||||||
|
* @param file one or more file
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
public JmodOperation cmdFiles(String... file) {
|
||||||
|
cmdFiles.addAll(List.of(file));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() throws Exception {
|
||||||
|
if (operationMode_ != null) {
|
||||||
|
toolArgs(operationMode_.mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
toolArgsFromFile(cmdFiles);
|
||||||
|
toolArgs(jmodOptions_);
|
||||||
|
|
||||||
|
if (jmodFile_ != null) {
|
||||||
|
toolArgs(jmodFile_);
|
||||||
|
}
|
||||||
|
|
||||||
|
super.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the name of the JMOD file to create or from which to retrieve information.
|
||||||
|
*
|
||||||
|
* @return the JMOD file
|
||||||
|
*/
|
||||||
|
public String jmodFile() {
|
||||||
|
return jmodFile_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies name of the JMOD file to create or from which to retrieve information.
|
||||||
|
* <p>
|
||||||
|
* The JMOD file is <b>required</b>.
|
||||||
|
*
|
||||||
|
* @param file the JMOD file
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
public JmodOperation jmodFile(String file) {
|
||||||
|
jmodFile_ = file;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of options for the jmod tool.
|
||||||
|
* <p>
|
||||||
|
* This is a modifiable list that can be retrieved and changed.
|
||||||
|
*
|
||||||
|
* @return the map of jmod options
|
||||||
|
*/
|
||||||
|
public JmodOptions jmodOptions() {
|
||||||
|
return jmodOptions_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a list of options to provide to the jmod tool.
|
||||||
|
* <p>
|
||||||
|
* A copy will be created to allow this list to be independently modifiable.
|
||||||
|
*
|
||||||
|
* @param options the list of jmod options
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
public JmodOperation jmodOptions(Map<String, String> options) {
|
||||||
|
jmodOptions_.putAll(options);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the {@link OperationMode operation mode}.
|
||||||
|
* <p>
|
||||||
|
* The operation mode is <b>required</b>.
|
||||||
|
*
|
||||||
|
* @param mode the mode
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
public JmodOperation operationMode(OperationMode mode) {
|
||||||
|
operationMode_ = mode;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The operation modes.
|
||||||
|
*/
|
||||||
|
public enum OperationMode {
|
||||||
|
/**
|
||||||
|
* Creates a new JMOD archive file.
|
||||||
|
*/
|
||||||
|
CREATE("create"),
|
||||||
|
/**
|
||||||
|
* Prints the module details.
|
||||||
|
*/
|
||||||
|
DESCRIBE("describe"),
|
||||||
|
/**
|
||||||
|
* Extracts all the files from the JMOD archive file.
|
||||||
|
*/
|
||||||
|
EXTRACT("extract"),
|
||||||
|
/**
|
||||||
|
* Determines leaf modules and records the hashes of the dependencies that directly and indirectly require them.
|
||||||
|
*/
|
||||||
|
HASH("hash"),
|
||||||
|
/**
|
||||||
|
* Prints the names of all the entries.
|
||||||
|
*/
|
||||||
|
LIST("list");
|
||||||
|
|
||||||
|
final String mode;
|
||||||
|
|
||||||
|
OperationMode(String mode) {
|
||||||
|
this.mode = mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
294
src/main/java/rife/bld/operations/JmodOptions.java
Normal file
294
src/main/java/rife/bld/operations/JmodOptions.java
Normal file
|
@ -0,0 +1,294 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Erik C. Thauvin (https://erik.thauvin.net/)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.operations;
|
||||||
|
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for jmod tool.
|
||||||
|
*
|
||||||
|
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
|
||||||
|
* @since 2.0.2
|
||||||
|
*/
|
||||||
|
public class JmodOptions extends HashMap<String, String> {
|
||||||
|
/**
|
||||||
|
* Application jar files|dir containing classes.
|
||||||
|
*
|
||||||
|
* @param classpath the classpath
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions classpath(String classpath) {
|
||||||
|
put("--class-path", classpath);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of native commands.
|
||||||
|
*
|
||||||
|
* @param path the location
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions cmds(String path) {
|
||||||
|
put("--cmds", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compression to use when creating the JMOD archive.
|
||||||
|
* <p>
|
||||||
|
* <b>Requires Java 20 or higher</b>.
|
||||||
|
* <p>
|
||||||
|
* Where {@link ZipCompression#ZIP_0 ZIP_0} provides no compression and {@link ZipCompression#ZIP_9 ZIP_9} provides the
|
||||||
|
* best compression.
|
||||||
|
* <p>
|
||||||
|
* Default is {@link ZipCompression#ZIP_6 ZIP_6}
|
||||||
|
*
|
||||||
|
* @param compression the {@link ZipCompression compression} level
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions compress(ZipCompression compression) {
|
||||||
|
put("--compress", compression.level);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of user-editable config files
|
||||||
|
*
|
||||||
|
* @param path the path to the config files
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions config(String path) {
|
||||||
|
put("--config", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Date and time for the timestamps of entries.
|
||||||
|
*
|
||||||
|
* @param date the date
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions date(ZonedDateTime date) {
|
||||||
|
put("--date", date.truncatedTo(ChronoUnit.SECONDS).format(DateTimeFormatter.ISO_INSTANT));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Target directory for extract
|
||||||
|
*
|
||||||
|
* @param path the directory path
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions dir(String path) {
|
||||||
|
put("--dir", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exclude from the default root set of modules.
|
||||||
|
*
|
||||||
|
* @param doNotResolveByDefault {@code true} to not resolve, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions doNotResolveByDefault(boolean doNotResolveByDefault) {
|
||||||
|
if (doNotResolveByDefault) {
|
||||||
|
put("--do-not-resolve-by-default");
|
||||||
|
} else {
|
||||||
|
remove("--do-not-resolve-by-default");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dry run of hash mode.
|
||||||
|
*
|
||||||
|
* @param dryRun {@code true} for dry run, {@code false} otherwise
|
||||||
|
* @return this list of operation
|
||||||
|
*/
|
||||||
|
public JmodOptions dryRun(boolean dryRun) {
|
||||||
|
if (dryRun) {
|
||||||
|
put("--dry-run");
|
||||||
|
} else {
|
||||||
|
remove("--dry-run");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exclude files matching the supplied pattern list.
|
||||||
|
*
|
||||||
|
* @param pattern one or more pattern
|
||||||
|
* @return the map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions exclude(FilePattern... pattern) {
|
||||||
|
var args = new ArrayList<String>();
|
||||||
|
for (var p : pattern) {
|
||||||
|
if (p.type == FilePatternType.GLOB) {
|
||||||
|
args.add("glob:" + p.pattern);
|
||||||
|
} else if (p.type == FilePatternType.REGEX) {
|
||||||
|
args.add("regex:" + p.pattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
put("--exclude", String.join(",", args));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute and record hashes to tie a packaged module with modules matching the given regular expression pattern and
|
||||||
|
* depending upon it directly or indirectly. The hashes are recorded in the JMOD file being created, or a JMOD file
|
||||||
|
* or modular JAR on the module path specified the jmod hash command.
|
||||||
|
*
|
||||||
|
* @param regexPattern the regular expression pattern
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions hashModules(String regexPattern) {
|
||||||
|
put("--hash-modules", regexPattern);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of header files.
|
||||||
|
*
|
||||||
|
* @param path the location
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions headerFiles(String path) {
|
||||||
|
put("--header-files", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of legal notices.
|
||||||
|
*
|
||||||
|
* @param path the location
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions legalNotices(String path) {
|
||||||
|
put("--legal-notices", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of native libraries.
|
||||||
|
*
|
||||||
|
* @param path the location
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions libs(String path) {
|
||||||
|
put("--libs", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main class.
|
||||||
|
*
|
||||||
|
* @param name the class name
|
||||||
|
* @return this list of operation
|
||||||
|
*/
|
||||||
|
public JmodOptions mainClass(String name) {
|
||||||
|
put("--main-class", name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of man pages.
|
||||||
|
*
|
||||||
|
* @param path the location
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions manPages(String path) {
|
||||||
|
put("--man-pages", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module path.
|
||||||
|
*
|
||||||
|
* @param path the module path
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions modulePath(String path) {
|
||||||
|
put("--module-path", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module version.
|
||||||
|
*
|
||||||
|
* @param version the module version.
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions moduleVersion(String version) {
|
||||||
|
put("--module-version", version);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Associates {@code null} with the specified key in this map. If the map previously contained a mapping for the
|
||||||
|
* key, the old value is replaced.
|
||||||
|
*
|
||||||
|
* @param key key with which the specified value is to be associated
|
||||||
|
*/
|
||||||
|
public void put(String key) {
|
||||||
|
put(key, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Target platform.
|
||||||
|
*
|
||||||
|
* @param platform the platform
|
||||||
|
* @return this list of operation
|
||||||
|
*/
|
||||||
|
public JmodOptions targetPlatform(String platform) {
|
||||||
|
put("--target-platform", platform);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hint for a tool to issue a warning if the module is resolved.
|
||||||
|
*
|
||||||
|
* @param reason the reason
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions warnIfResolved(ResolvedReason reason) {
|
||||||
|
put("--warn-if-resolved", reason.reason);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The resolved reasons.
|
||||||
|
*/
|
||||||
|
public enum ResolvedReason {
|
||||||
|
DEPRECATED("deprecated"),
|
||||||
|
DEPRECATED_FOR_REMOVAL("deprecated-for-removal"),
|
||||||
|
INCUBATING("incubating");
|
||||||
|
|
||||||
|
final String reason;
|
||||||
|
|
||||||
|
ResolvedReason(String reason) {
|
||||||
|
this.reason = reason;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The file pattern types.
|
||||||
|
*/
|
||||||
|
public enum FilePatternType {
|
||||||
|
GLOB, REGEX
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines a file pattern and pattern type.
|
||||||
|
*
|
||||||
|
* @param type the pattern type
|
||||||
|
* @param pattern the pattern
|
||||||
|
*/
|
||||||
|
public record FilePattern(FilePatternType type, String pattern) {
|
||||||
|
}
|
||||||
|
}
|
75
src/main/java/rife/bld/operations/JpackageOperation.java
Normal file
75
src/main/java/rife/bld/operations/JpackageOperation.java
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Erik C. Thauvin (https://erik.thauvin.net/)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.operations;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Package self-contained Java applications with the jpackage tool.
|
||||||
|
*
|
||||||
|
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
|
||||||
|
* @since 2.0.2
|
||||||
|
*/
|
||||||
|
public class JpackageOperation extends AbstractToolProviderOperation<JpackageOperation> {
|
||||||
|
private final List<String> cmdFiles_ = new ArrayList<>();
|
||||||
|
private final JpackageOptions jpackageOptions_ = new JpackageOptions();
|
||||||
|
|
||||||
|
public JpackageOperation() {
|
||||||
|
super("jpackage");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() throws Exception {
|
||||||
|
toolArgs(cmdFiles_.stream().map(opt -> '@' + opt).toList());
|
||||||
|
toolArgs(jpackageOptions_);
|
||||||
|
super.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of files containing options or mode.
|
||||||
|
*
|
||||||
|
* @return the list of files
|
||||||
|
*/
|
||||||
|
public List<String> fileOptions() {
|
||||||
|
return cmdFiles_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read options and/or mode from file(s).
|
||||||
|
*
|
||||||
|
* @param file one or more file
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
public JpackageOperation cmdFiles(String... file) {
|
||||||
|
cmdFiles_.addAll(List.of(file));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of options for the jpackage tool.
|
||||||
|
* <p>
|
||||||
|
* This is a modifiable list that can be retrieved and changed.
|
||||||
|
*
|
||||||
|
* @return the map of jpackage options
|
||||||
|
*/
|
||||||
|
public JpackageOptions jpackageOptions() {
|
||||||
|
return jpackageOptions_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a list of options to provide to the jpackage tool.
|
||||||
|
* <p>
|
||||||
|
* A copy will be created to allow this list to be independently modifiable.
|
||||||
|
*
|
||||||
|
* @param options the map of jpackage options
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
public JpackageOperation jpackageOptions(Map<String, String> options) {
|
||||||
|
jpackageOptions_.putAll(options);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
888
src/main/java/rife/bld/operations/JpackageOptions.java
Normal file
888
src/main/java/rife/bld/operations/JpackageOptions.java
Normal file
|
@ -0,0 +1,888 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Erik C. Thauvin (https://erik.thauvin.net/)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.operations;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for jpackage tool.
|
||||||
|
*
|
||||||
|
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
|
||||||
|
* @since 2.0.2
|
||||||
|
*/
|
||||||
|
public class JpackageOptions extends HashMap<String, String> {
|
||||||
|
/**
|
||||||
|
* URL of the application's home page.
|
||||||
|
*
|
||||||
|
* @param url the URL
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions aboutUrl(String url) {
|
||||||
|
put("--about-url", url);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of application launchers.
|
||||||
|
* <p>
|
||||||
|
* The main application launcher will be built from the command line options.
|
||||||
|
* <p>
|
||||||
|
* Additional alternative launchers can be built using this option, and this option can be used to build multiple
|
||||||
|
* additional launchers.
|
||||||
|
*
|
||||||
|
* @param launcher one or more {@link Launcher}
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions addLauncher(Launcher... launcher) {
|
||||||
|
for (var l : launcher) {
|
||||||
|
put("--add-launcher", l.name + '=' + l.path);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of modules to add.
|
||||||
|
* <p>
|
||||||
|
* This module list, along with the main module (if specified) will be passed to jlink as the
|
||||||
|
* {@link JlinkOptions#addModules(String...) addModules} argument. If not specified, either just the main module
|
||||||
|
* (if {@link #module(String, String) module} is specified), or the default set of modules (if
|
||||||
|
* {@link #mainJar(String) mainJar} is specified) are used.
|
||||||
|
*
|
||||||
|
* @param modules one or more module
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions addModules(String... modules) {
|
||||||
|
put("--add-modules", String.join(",", modules));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of paths to files and/or directories to add to the application payload.
|
||||||
|
* <p>
|
||||||
|
* <b>Requires Java 20 or higher</b>.
|
||||||
|
*
|
||||||
|
* @param additionalContent one or more path
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions appContent(String... additionalContent) {
|
||||||
|
put("--app-content", String.join(",", additionalContent));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of the predefined application image that is used to build an installable package.
|
||||||
|
*
|
||||||
|
* @param path absolute path or relative to the current directory
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions appImage(String path) {
|
||||||
|
put("--app-image", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version of the application and/or package.
|
||||||
|
*
|
||||||
|
* @param version the version
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions appVersion(String version) {
|
||||||
|
put("--app-version", version);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Command line arguments to pass to main class if no command line arguments are given to the launcher.
|
||||||
|
*
|
||||||
|
* @param argument one or more argument
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions arguments(String... argument) {
|
||||||
|
put("--arguments", String.join(" ", argument));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright of the application.
|
||||||
|
*
|
||||||
|
* @param copyright the copyright
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions copyright(String copyright) {
|
||||||
|
put("--copyright", copyright);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the application.
|
||||||
|
*
|
||||||
|
* @param description the description
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions description(String description) {
|
||||||
|
put("--description", description);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path where generated output file is placed.
|
||||||
|
* <p>
|
||||||
|
* Defaults to the current working directory.
|
||||||
|
*
|
||||||
|
* @param path absolute path or relative to the current directory
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions dest(String path) {
|
||||||
|
put("--dest", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path to a Properties file that contains list of key, value pairs.
|
||||||
|
* <p>
|
||||||
|
* The keys {@code extension}, {@code mime-type}, {@code icon}, and {@code description} can be used to describe the
|
||||||
|
* association.
|
||||||
|
*
|
||||||
|
* @param path absolute path or relative to the current directory
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions fileAssociations(String... path) {
|
||||||
|
put("--file-associations", String.join(",", path));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path of the icon of the application package.
|
||||||
|
*
|
||||||
|
* @param path absolute path or relative to the current directory
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions icon(String path) {
|
||||||
|
put("--icon", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path of the input directory that contains the files to be packaged.
|
||||||
|
* <p>
|
||||||
|
* All files in the input directory will be packaged into the application image.
|
||||||
|
*
|
||||||
|
* @param path absolute path or relative to the current directory
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions input(String path) {
|
||||||
|
put("--input", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Absolute path of the installation directory of the application.
|
||||||
|
*
|
||||||
|
* @param path the absolute directory path
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions installDir(String path) {
|
||||||
|
put("--install-dir", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options to pass to the Java runtime.
|
||||||
|
*
|
||||||
|
* @param options the options
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions javaOptions(String... options) {
|
||||||
|
put("--java-options", String.join(" ", options));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of options to pass to jlink.
|
||||||
|
* <p>
|
||||||
|
* If not specified, defaults to {@link JlinkOptions#stripNativeCommands(boolean) stripNativeCommands}
|
||||||
|
* {@link JlinkOptions#stripDebug(boolean) stripDebug} {@link JlinkOptions#noManPages(boolean) noManPages}
|
||||||
|
* {@link JlinkOptions#noHeaderFiles(boolean) noHeaderFiles}.
|
||||||
|
*
|
||||||
|
* @param options the {@link JlinkOptions}
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions jlinkOptions(JlinkOptions options) {
|
||||||
|
put("--jlink-options", String.join(" ", options.toList()));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request to create an installer that will register the main application launcher as a background service-type
|
||||||
|
* application.
|
||||||
|
* <p>
|
||||||
|
* <b>Requires Java 20 or higher</b>.
|
||||||
|
*
|
||||||
|
* @param launcherAsService {@code true} to register the launcher as a service; {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions launcherAsService(boolean launcherAsService) {
|
||||||
|
if (launcherAsService) {
|
||||||
|
put("--launcher-as-service");
|
||||||
|
} else {
|
||||||
|
remove("--launcher-as-service");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path to the license file.
|
||||||
|
*
|
||||||
|
* @param path absolute path or relative to the current directory
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions licenseFile(String path) {
|
||||||
|
put("--license-file", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group value of the RPM {@code <name>.spec} file or Section value of DEB control file.
|
||||||
|
*
|
||||||
|
* @param appCategory the application category
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions linuxAppCategory(String appCategory) {
|
||||||
|
put("--linux-app-category", appCategory);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release value of the RPM {@code <name>.spec} file or Debian revision value of the DEB control file.
|
||||||
|
*
|
||||||
|
* @param appRelease the release value
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions linuxAppRelease(String appRelease) {
|
||||||
|
put("--linux-app-release", appRelease);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maintainer for {@code .deb} package.
|
||||||
|
*
|
||||||
|
* @param maintainer the maintainer
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions linuxDebMaintainer(String maintainer) {
|
||||||
|
put("--linux-deb-maintainer", maintainer);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Menu group this application is placed in.
|
||||||
|
*
|
||||||
|
* @param menuGroup the menu group
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions linuxMenuGroup(String menuGroup) {
|
||||||
|
put("--linux-menu-group", menuGroup);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Required packages or capabilities for the application.
|
||||||
|
*
|
||||||
|
* @param packageDeps {@code true} if required, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions linuxPackageDeps(boolean packageDeps) {
|
||||||
|
if (packageDeps) {
|
||||||
|
put("--linux-package-deps");
|
||||||
|
} else {
|
||||||
|
remove("--linux-package-deps");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name for Linux package, defaults to the application name.
|
||||||
|
*
|
||||||
|
* @param packageName the package name
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions linuxPackageName(String packageName) {
|
||||||
|
put("--linux-package-name", packageName);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type of the license.
|
||||||
|
* <p>
|
||||||
|
* {@code License: <value>} of the RPM {@code .spec}
|
||||||
|
*
|
||||||
|
* @param licenseType the license type
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions linuxRpmLicenseType(String licenseType) {
|
||||||
|
put("--linux-rpm-license-type", licenseType);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a shortcut for the application.
|
||||||
|
*
|
||||||
|
* @param shortcut {@code true| to create a shortcut, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions linuxShortcut(boolean shortcut) {
|
||||||
|
if (shortcut) {
|
||||||
|
put("--linux-shortcut");
|
||||||
|
} else {
|
||||||
|
remove("--linux-shortcut");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String used to construct {@code LSApplicationCategoryType} in application plist.
|
||||||
|
* <p>
|
||||||
|
* The default value is {@code utilities}.
|
||||||
|
*
|
||||||
|
* @param appCategory the category
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions macAppCategory(String appCategory) {
|
||||||
|
put("--mac-app-category", appCategory);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identity used to sign application image.
|
||||||
|
* <p>
|
||||||
|
* This value will be passed directly to {@code --sign} option of {@code codesign} tool.
|
||||||
|
* <p>
|
||||||
|
* This option cannot be combined with {@link #macSigningKeyUserName(String) macSignKeyUserName}.
|
||||||
|
*
|
||||||
|
* @param identity the identity
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions macAppImageSignIdentity(String identity) {
|
||||||
|
put("--mac-app-image-sign-identity", identity);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the jpackage output is intended for the Mac App Store.
|
||||||
|
*
|
||||||
|
* @param appStore {@code true} if intended for the Mac App Store, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions macAppStore(boolean appStore) {
|
||||||
|
if (appStore) {
|
||||||
|
put("--mac-app-store");
|
||||||
|
} else {
|
||||||
|
remove("--mac-app-store");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include all the referenced content in the dmg.
|
||||||
|
*
|
||||||
|
* @param additionalContent one or more path
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions macDmgContent(String... additionalContent) {
|
||||||
|
put("--mac-dmg-content", String.join(",", additionalContent));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path to file containing entitlements to use when signing executables and libraries in the bundle.
|
||||||
|
*
|
||||||
|
* @param path the fie path
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions macEntitlements(String path) {
|
||||||
|
put("--mac-entitlements", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identity used to sign "pkg" installer.
|
||||||
|
* <p>
|
||||||
|
* This value will be passed directly to {@code --sign} option of {@code productbuild} tool.
|
||||||
|
* <p>
|
||||||
|
* This option cannot be combined with {@link #macSigningKeyUserName(String) macSignKeyUserName}.
|
||||||
|
*
|
||||||
|
* @param identity the identity
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions macInstallerSignIdentity(String identity) {
|
||||||
|
put("--mac-installer-sign-identity", identity);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An identifier that uniquely identifies the application for macOS.
|
||||||
|
* <p>
|
||||||
|
* Defaults to the main class name.
|
||||||
|
* <p>
|
||||||
|
* May only use alphanumeric ({@code A-Z,a-z,0-9}), hyphen ({@code -}), and period ({@code .}) characters.
|
||||||
|
*
|
||||||
|
* @param packageIdentifier the package identifier
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions macPackageIdentifier(String packageIdentifier) {
|
||||||
|
put("--mac-package-identifier", packageIdentifier);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the application as it appears in the Menu Bar.
|
||||||
|
* <p>
|
||||||
|
* This can be different from the application name.
|
||||||
|
* <p>
|
||||||
|
* This name must be less than 16 characters long and be suitable for displaying in the menu bar and the application
|
||||||
|
* Info window.
|
||||||
|
* <p>
|
||||||
|
* Defaults to the application name.
|
||||||
|
*
|
||||||
|
* @param name the package name
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions macPackageName(String name) {
|
||||||
|
put("--mac-package-name", name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When signing the application package, this value is prefixed to all components that need to be signed that don't
|
||||||
|
* have an existing package identifier.
|
||||||
|
*
|
||||||
|
* @param prefix the signing prefix
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions macPackageSigningPrefix(String prefix) {
|
||||||
|
put("--mac-package-signing-prefix", prefix);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request that the package or the predefined application image be signed.
|
||||||
|
*
|
||||||
|
* @param sign {@code true} to sign, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions macSign(boolean sign) {
|
||||||
|
if (sign) {
|
||||||
|
put("--mac-sign");
|
||||||
|
} else {
|
||||||
|
remove("--mac-sign");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Team or user name portion in Apple signing identities.
|
||||||
|
* <p>
|
||||||
|
* For direct control of the signing identity used to sign application images or installers use
|
||||||
|
* {@link #macAppImageSignIdentity(String) macAppImageSignIdentity} and/or
|
||||||
|
* {@link #macInstallerSignIdentity(String) macInstallerSignIdentity}.
|
||||||
|
* <p>
|
||||||
|
* This option cannot be combined with {@link #macAppImageSignIdentity(String) macAppImageSignIdentity} or
|
||||||
|
* {@link #macInstallerSignIdentity(String) macInstallerSignIdentity}.
|
||||||
|
*
|
||||||
|
* @param username the username
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions macSigningKeyUserName(String username) {
|
||||||
|
put("--mac-signing-key-user-name", username);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the keychain to search for the signing identity.
|
||||||
|
* <p>
|
||||||
|
* If not specified, the standard keychains are used.
|
||||||
|
*
|
||||||
|
* @param keychain the keychain name
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions macSigningKeychain(String keychain) {
|
||||||
|
put("--mac-signing-keychain", keychain);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Qualified name of the application main class to execute.
|
||||||
|
* <p>
|
||||||
|
* This option can only be used if {@link #mainJar(String) mainJar} is specified.
|
||||||
|
*
|
||||||
|
* @param mainClass the main class
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions mainClass(String mainClass) {
|
||||||
|
put("--main-class", mainClass);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main JAR of the application; containing the main class.
|
||||||
|
* <p>
|
||||||
|
* Either {@link #module(String, String) module} or {@link #mainJar(String) mainJar} option can be specified but
|
||||||
|
* not both.
|
||||||
|
*
|
||||||
|
* @param jar the path relative to the input path
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("JavadocDeclaration")
|
||||||
|
public JpackageOptions mainJar(String jar) {
|
||||||
|
put("--main-jar", jar);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main module and main class of the application.
|
||||||
|
* <p>
|
||||||
|
* This module must be located on the {@link #modulePath(String...) module path}.
|
||||||
|
* <p>
|
||||||
|
* When this option is specified, the main module will be linked in the Java runtime image.
|
||||||
|
* <p>
|
||||||
|
* Either {@link #module(String, String) module} or {@link #mainJar(String) mainJar} option can be specified but
|
||||||
|
* not both.
|
||||||
|
*
|
||||||
|
* @param name the module name
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions module(String name) {
|
||||||
|
put("--module", name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main module and main class of the application.
|
||||||
|
* <p>
|
||||||
|
* This module must be located on the {@link #modulePath(String...) module path}.
|
||||||
|
* <p>
|
||||||
|
* When this option is specified, the main module will be linked in the Java runtime image.
|
||||||
|
* <p>
|
||||||
|
* Either {@link #module(String, String) module} or {@link #mainJar(String) mainJar} option can be specified but
|
||||||
|
* not both.
|
||||||
|
*
|
||||||
|
* @param name the module name
|
||||||
|
* @param mainClass the main class
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("JavadocDeclaration")
|
||||||
|
public JpackageOptions module(String name, String mainClass) {
|
||||||
|
put("--module-name", name + "/" + mainClass);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of module paths.
|
||||||
|
* <p>
|
||||||
|
* Each path is either a directory of modules or the path to a modular jar.
|
||||||
|
* <p>
|
||||||
|
* Each path is absolute or relative to the current directory.
|
||||||
|
*
|
||||||
|
* @param path one or more path
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions modulePath(String... path) {
|
||||||
|
put("--module-path", String.join(":", path));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the application and/or package.
|
||||||
|
*
|
||||||
|
* @param name the name
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions name(String name) {
|
||||||
|
put("--name", name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Associates {@code null} with the specified key in this map. If the map previously contained a mapping for the
|
||||||
|
* key, the old value is replaced.
|
||||||
|
*
|
||||||
|
* @param key key with which the specified value is to be associated
|
||||||
|
*/
|
||||||
|
public void put(String key) {
|
||||||
|
put(key, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path to override jpackage resources.
|
||||||
|
* <p>
|
||||||
|
* Icons, template files, and other resources of jpackage can be over-ridden by adding replacement resources to
|
||||||
|
* this directory.
|
||||||
|
*
|
||||||
|
* @param path absolute path or relative to the current directory
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions resourceDir(String path) {
|
||||||
|
put("--resource-dir", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path of the predefined runtime image that will be copied into the application image.
|
||||||
|
* <p>
|
||||||
|
* If not specified, jpackage will run jlink to create the runtime image using options:
|
||||||
|
* {@link JlinkOptions#stripNativeCommands(boolean) stripNativeCommands}
|
||||||
|
* {@link JlinkOptions#stripDebug(boolean) stripDebug} {@link JlinkOptions#noManPages(boolean) noManPages}
|
||||||
|
* {@link JlinkOptions#noHeaderFiles(boolean) noHeaderFiles}
|
||||||
|
* <p>
|
||||||
|
* Option is required when creating a runtime package.
|
||||||
|
*
|
||||||
|
* @param path absolute path or relative to the current directory
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions runtimeImage(String path) {
|
||||||
|
put("--runtime-image", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strip debug information.
|
||||||
|
*
|
||||||
|
* @param stripDebug {@code true} to strip debug info, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions stripDebug(boolean stripDebug) {
|
||||||
|
if (stripDebug) {
|
||||||
|
put("--strip-debug");
|
||||||
|
} else {
|
||||||
|
remove("--strip-debug");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path of a new or empty directory used to create temporary files.
|
||||||
|
* <p>
|
||||||
|
* If specified, the temp dir will not be removed upon the task completion and must be removed manually.
|
||||||
|
* <p>
|
||||||
|
* If not specified, a temporary directory will be created and removed upon the task completion.
|
||||||
|
*
|
||||||
|
* @param path absolute path or relative to the current directory
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions temp(String path) {
|
||||||
|
put("--temp", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of package to create.
|
||||||
|
* <p>
|
||||||
|
* If this option is not specified a platform dependent default type will be created.
|
||||||
|
*
|
||||||
|
* @param type the package type
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions type(PackageType type) {
|
||||||
|
put("--type", type.type);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vendor of the application.
|
||||||
|
*
|
||||||
|
* @param vendor the vendor
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions vendor(String vendor) {
|
||||||
|
put("--vendor", vendor);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables verbose output.
|
||||||
|
*
|
||||||
|
* @param verbose {@code true} to enable verbose tracing, {@code false} otherwise.
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions verbose(boolean verbose) {
|
||||||
|
if (verbose) {
|
||||||
|
put("--verbose");
|
||||||
|
} else {
|
||||||
|
remove("--verbose");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a console launcher for the application, should be specified for application which requires console
|
||||||
|
* interactions.
|
||||||
|
*
|
||||||
|
* @param winConsole {@code true} to create a console launcher, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions winConsole(boolean winConsole) {
|
||||||
|
if (winConsole) {
|
||||||
|
put("--win-console");
|
||||||
|
} else {
|
||||||
|
remove("--win-console");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a dialog to enable the user to choose a directory in which the product is installed.
|
||||||
|
*
|
||||||
|
* @param winDirChooser {@code true} to let the user choose a directory, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions winDirChooser(boolean winDirChooser) {
|
||||||
|
if (winDirChooser) {
|
||||||
|
put("--win-dir-chooser");
|
||||||
|
} else {
|
||||||
|
remove("--win-dir-chooser");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URL where user can obtain further information or technical support.
|
||||||
|
*
|
||||||
|
* @param helpUrl the help URL
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions winHelpUrl(String helpUrl) {
|
||||||
|
put("--win-help-url", helpUrl);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request to add a Start Menu shortcut for this application.
|
||||||
|
*
|
||||||
|
* @param winMenu {@code true} to add a start menu shortcut, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions winMenu(boolean winMenu) {
|
||||||
|
if (winMenu) {
|
||||||
|
put("--win-menu");
|
||||||
|
} else {
|
||||||
|
remove("--win-menu");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start Menu group this application is placed in.
|
||||||
|
*
|
||||||
|
* @param menuGroup the menu group
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions winMenuGroup(String menuGroup) {
|
||||||
|
put("--win-menu-group", menuGroup);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request to perform an install on a per-user basis.
|
||||||
|
*
|
||||||
|
* @param winPerUserInstall {@code true} for per-user install, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions winPerUserInstall(boolean winPerUserInstall) {
|
||||||
|
if (winPerUserInstall) {
|
||||||
|
put("--win-per-user-install");
|
||||||
|
} else {
|
||||||
|
remove("--win-per-user-install");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request to create a desktop shortcut for this application.
|
||||||
|
*
|
||||||
|
* @param winShortcut {@code true} to create a shortcut, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions winShortcut(boolean winShortcut) {
|
||||||
|
if (winShortcut) {
|
||||||
|
put("--win-shortcut");
|
||||||
|
} else {
|
||||||
|
remove("--win-shortcut");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a dialog to enable the user to choose if shortcuts will be created by installer.
|
||||||
|
*
|
||||||
|
* @param shortcutPrompt {@code true} to add a prompt; {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions winShortcutPrompt(boolean shortcutPrompt) {
|
||||||
|
if (shortcutPrompt) {
|
||||||
|
put("--win-shortcut-prompt");
|
||||||
|
} else {
|
||||||
|
remove("--win-shortcut-prompt");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URL of available application update information.
|
||||||
|
*
|
||||||
|
* @param url the URL
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions winUpdateUrl(String url) {
|
||||||
|
put("--win-update-url", url);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UUID associated with upgrades for this package.
|
||||||
|
*
|
||||||
|
* @param uuid the uuid
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JpackageOptions winUpgradeUuid(String uuid) {
|
||||||
|
put("--win-upgrade-uuid", uuid);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The package types.
|
||||||
|
*/
|
||||||
|
public enum PackageType {
|
||||||
|
APP_IMAGE("app_image"),
|
||||||
|
DEB("deb"),
|
||||||
|
DMG("dmg"),
|
||||||
|
EXE("exe"),
|
||||||
|
MSI("msi"),
|
||||||
|
PKG("pkg"),
|
||||||
|
RPM("rpm");
|
||||||
|
|
||||||
|
final String type;
|
||||||
|
|
||||||
|
PackageType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of launcher, and a path to a Properties file that contains a list of key, value pairs.
|
||||||
|
* <p>
|
||||||
|
* The keys {@code module}, {@code main-jar}, {@code main-class}, {@code description},
|
||||||
|
* {@code arguments}, {@code java-options}, {@code app-version}, {@code icon},
|
||||||
|
* {@code launcher-as-service}, {@code win-console}, {@code win-shortcut}, {@code win-menu},
|
||||||
|
* {@code linux-app-category}, and {@code linux-shortcut} can be used.
|
||||||
|
* <p>
|
||||||
|
* These options are added to, or used to overwrite, the original command line options to build an additional
|
||||||
|
* alternative launcher.
|
||||||
|
*
|
||||||
|
* @param name the name
|
||||||
|
* @param path absolute path or relative to the current directory
|
||||||
|
*/
|
||||||
|
public record Launcher(String name, String path) {
|
||||||
|
}
|
||||||
|
}
|
30
src/main/java/rife/bld/operations/ZipCompression.java
Normal file
30
src/main/java/rife/bld/operations/ZipCompression.java
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2024 Erik C. Thauvin (https://erik.thauvin.net/)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.operations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The zip compression levels for jlink and jmod.
|
||||||
|
*
|
||||||
|
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
|
||||||
|
* @since 2.0.2
|
||||||
|
*/
|
||||||
|
public enum ZipCompression {
|
||||||
|
ZIP_0("zip-0"),
|
||||||
|
ZIP_1("zip-1"),
|
||||||
|
ZIP_2("zip-2"),
|
||||||
|
ZIP_3("zip-3"),
|
||||||
|
ZIP_4("zip-4"),
|
||||||
|
ZIP_5("zip-5"),
|
||||||
|
ZIP_6("zip-6"),
|
||||||
|
ZIP_7("zip-7"),
|
||||||
|
ZIP_8("zip-8"),
|
||||||
|
ZIP_9("zip-9");
|
||||||
|
|
||||||
|
public final String level;
|
||||||
|
|
||||||
|
ZipCompression(String level) {
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
}
|
163
src/test/java/rife/bld/operations/TestJlinkOperation.java
Normal file
163
src/test/java/rife/bld/operations/TestJlinkOperation.java
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Erik C. Thauvin (https://erik.thauvin.net/)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.operations;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import rife.bld.operations.exceptions.ExitStatusException;
|
||||||
|
import rife.tools.FileUtils;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static rife.bld.operations.JlinkOptions.CompressionLevel;
|
||||||
|
|
||||||
|
public class TestJlinkOperation {
|
||||||
|
private final ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream();
|
||||||
|
private final PrintStream stdout = System.out;
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void tearDown() {
|
||||||
|
System.setOut(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testArguments() {
|
||||||
|
var args = new HashMap<String, String>();
|
||||||
|
args.put("--add-modules", "module-1,module-2");
|
||||||
|
args.put("--bind-services", null);
|
||||||
|
args.put("--compress", "2");
|
||||||
|
args.put("--endian", "big");
|
||||||
|
args.put("--ignore-signing-information", null);
|
||||||
|
args.put("--launcher", "name=module/mainclass");
|
||||||
|
args.put("--limit-modules", "module-1,module-2");
|
||||||
|
args.put("--module-path", "module-path");
|
||||||
|
args.put("--no-header-files", null);
|
||||||
|
args.put("--no-man-pages", null);
|
||||||
|
args.put("--output", "output");
|
||||||
|
args.put("--save-opts", "save-opts");
|
||||||
|
args.put("--strip-debug", null);
|
||||||
|
args.put("--suggest-providers", "provider-1,provider-2");
|
||||||
|
args.put("--verbose", null);
|
||||||
|
|
||||||
|
var options = new JlinkOptions()
|
||||||
|
.addModules(args.get("--add-modules").split(","))
|
||||||
|
.bindServices(true)
|
||||||
|
.compress(CompressionLevel.ZIP)
|
||||||
|
.endian(JlinkOptions.Endian.BIG)
|
||||||
|
.ignoreSigningInformation(true)
|
||||||
|
.launcher("name", "module", "mainclass")
|
||||||
|
.limitModule(args.get("--limit-modules").split(","))
|
||||||
|
.modulePath(args.get("--module-path"))
|
||||||
|
.noHeaderFiles(true)
|
||||||
|
.noManPages(true)
|
||||||
|
.output(args.get("--output"))
|
||||||
|
.saveOpts(args.get("--save-opts"))
|
||||||
|
.stripDebug(true)
|
||||||
|
.suggestProviders(args.get("--suggest-providers").split(","))
|
||||||
|
.verbose(true);
|
||||||
|
|
||||||
|
assertEquals(options.size(), args.size(), "Wrong number of arguments");
|
||||||
|
|
||||||
|
for (var arg : args.entrySet()) {
|
||||||
|
assertTrue(options.containsKey(arg.getKey()), arg.getValue() + " not found");
|
||||||
|
assertEquals(arg.getValue(), options.get(arg.getKey()), arg.getKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
options.launcher("name-2", "module-2");
|
||||||
|
assertEquals("name-2=module-2", options.get("--launcher"), "incorrect launcher");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCmdFiles() {
|
||||||
|
System.setOut(new PrintStream(outputStreamCaptor));
|
||||||
|
final JlinkOperation jlink;
|
||||||
|
if (System.getProperty("os.name").startsWith("Windows")) {
|
||||||
|
jlink = new JlinkOperation().cmdFiles("src/test/resources/jlink/options_jlink_win.txt");
|
||||||
|
} else {
|
||||||
|
jlink = new JlinkOperation().cmdFiles("src/test/resources/jlink/options_jlink.txt");
|
||||||
|
}
|
||||||
|
assertDoesNotThrow(jlink::execute);
|
||||||
|
var out = outputStreamCaptor.toString();
|
||||||
|
assertTrue(out.contains("List of available plugins:"), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCmdFilesVersion() {
|
||||||
|
System.setOut(new PrintStream(outputStreamCaptor));
|
||||||
|
var jlink = new JlinkOperation().cmdFiles("src/test/resources/jlink/options_verbose.txt",
|
||||||
|
"src/test/resources/jlink/options_version.txt");
|
||||||
|
assertDoesNotThrow(jlink::execute);
|
||||||
|
var out = outputStreamCaptor.toString();
|
||||||
|
assertTrue(out.matches("[\\d.]+[\\r\\n]+"), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDisablePlugin() {
|
||||||
|
System.setOut(new PrintStream(outputStreamCaptor));
|
||||||
|
var jlink = new JlinkOperation()
|
||||||
|
.disablePlugin("vm")
|
||||||
|
.disablePlugin("system-modules")
|
||||||
|
.toolArgs("--list-plugins");
|
||||||
|
assertDoesNotThrow(jlink::execute);
|
||||||
|
var out = outputStreamCaptor.toString();
|
||||||
|
assertTrue(out.contains("List of available plugins:"), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testExecute() throws IOException {
|
||||||
|
var tmpdir = Files.createTempDirectory("bld-jlink-test").toFile();
|
||||||
|
try {
|
||||||
|
var output = new File(tmpdir, "jlink");
|
||||||
|
|
||||||
|
var options = new JlinkOptions()
|
||||||
|
.modulePath("src/test/resources/jlink/build/jmod")
|
||||||
|
.addModules("dev.mccue.tree")
|
||||||
|
.launcher("tree", "dev.mccue.tree", "dev.mccue.tree.Tree")
|
||||||
|
.output(output.getAbsolutePath());
|
||||||
|
if (Runtime.version().version().get(0) >= 21) {
|
||||||
|
options.compress(ZipCompression.ZIP_6);
|
||||||
|
} else {
|
||||||
|
options.compress(CompressionLevel.ZIP);
|
||||||
|
}
|
||||||
|
|
||||||
|
var jlink = new JlinkOperation().jlinkOptions(options);
|
||||||
|
|
||||||
|
assertDoesNotThrow(jlink::execute);
|
||||||
|
assertTrue(output.exists(), "Output dir does not exist");
|
||||||
|
} finally {
|
||||||
|
FileUtils.deleteDirectory(tmpdir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHelp() {
|
||||||
|
var jlink = new JlinkOperation().toolArgs("--help");
|
||||||
|
assertDoesNotThrow(jlink::execute);
|
||||||
|
assertTrue(jlink.toolArgs().isEmpty(), "args not empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testNoArguments() {
|
||||||
|
var jlink = new JlinkOperation();
|
||||||
|
assertTrue(jlink.jlinkOptions().isEmpty(), "jlink options not empty");
|
||||||
|
assertTrue(jlink.cmdFiles().isEmpty(), "file options not empty");
|
||||||
|
assertThrows(ExitStatusException.class, jlink::execute);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testVersion() {
|
||||||
|
System.setOut(new PrintStream(outputStreamCaptor));
|
||||||
|
var jlink = new JlinkOperation().toolArgs("--verbose", "--version");
|
||||||
|
assertDoesNotThrow(jlink::execute);
|
||||||
|
var out = outputStreamCaptor.toString();
|
||||||
|
assertTrue(out.matches("[\\d.]+[\\r\\n]+"), out);
|
||||||
|
}
|
||||||
|
}
|
191
src/test/java/rife/bld/operations/TestJmodOperation.java
Normal file
191
src/test/java/rife/bld/operations/TestJmodOperation.java
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Erik C. Thauvin (https://erik.thauvin.net/)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.operations;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import rife.bld.operations.exceptions.ExitStatusException;
|
||||||
|
import rife.tools.FileUtils;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static rife.bld.operations.JmodOperation.OperationMode;
|
||||||
|
|
||||||
|
public class TestJmodOperation {
|
||||||
|
private final ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream();
|
||||||
|
private final PrintStream stdout = System.out;
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void tearDown() {
|
||||||
|
System.setOut(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testArguments() {
|
||||||
|
var args = new HashMap<String, String>();
|
||||||
|
args.put("--class-path", "classpath");
|
||||||
|
args.put("--cmds", "cmds");
|
||||||
|
args.put("--config", "config");
|
||||||
|
args.put("--date", "1997-08-29T09:14:00Z");
|
||||||
|
args.put("--dir", "dir");
|
||||||
|
args.put("--do-not-resolve-by-default", null);
|
||||||
|
args.put("--dry-run", null);
|
||||||
|
args.put("--exclude", "glob:glob,regex:regex");
|
||||||
|
args.put("--hash-modules", "regex");
|
||||||
|
args.put("--header-files", "header-files");
|
||||||
|
args.put("--legal-notices", "legal-notices");
|
||||||
|
args.put("--libs", "libs");
|
||||||
|
args.put("--main-class", "main-class");
|
||||||
|
args.put("--man-pages", "man-pages");
|
||||||
|
args.put("--module-path", "module-path");
|
||||||
|
args.put("--module-version", "module-version");
|
||||||
|
args.put("--target-platform", "target-platform");
|
||||||
|
args.put("--warn-if-resolved", "deprecated");
|
||||||
|
|
||||||
|
var options = new JmodOptions()
|
||||||
|
.classpath(args.get("--class-path"))
|
||||||
|
.cmds(args.get("--cmds"))
|
||||||
|
.config(args.get("--config"))
|
||||||
|
.date(ZonedDateTime.of(1997, 8, 29, 2, 14, 0, 1, ZoneId.of("America/Los_Angeles")))
|
||||||
|
.dir(args.get("--dir"))
|
||||||
|
.doNotResolveByDefault(true)
|
||||||
|
.dryRun(true)
|
||||||
|
.exclude(new JmodOptions.FilePattern(JmodOptions.FilePatternType.GLOB, "glob"),
|
||||||
|
new JmodOptions.FilePattern(JmodOptions.FilePatternType.REGEX, "regex"))
|
||||||
|
.hashModules(args.get("--hash-modules"))
|
||||||
|
.headerFiles(args.get("--header-files"))
|
||||||
|
.legalNotices(args.get("--legal-notices"))
|
||||||
|
.libs(args.get("--libs"))
|
||||||
|
.mainClass(args.get("--main-class"))
|
||||||
|
.manPages(args.get("--man-pages"))
|
||||||
|
.modulePath(args.get("--module-path"))
|
||||||
|
.moduleVersion(args.get("--module-version"))
|
||||||
|
.targetPlatform(args.get("--target-platform"))
|
||||||
|
.warnIfResolved(JmodOptions.ResolvedReason.DEPRECATED);
|
||||||
|
|
||||||
|
assertEquals(options.size(), args.size(), "Wrong number of arguments");
|
||||||
|
|
||||||
|
for (var arg : args.entrySet()) {
|
||||||
|
assertTrue(options.containsKey(arg.getKey()), arg.getValue() + " not found");
|
||||||
|
assertEquals(arg.getValue(), options.get(arg.getKey()), arg.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCmdFiles() {
|
||||||
|
System.setOut(new PrintStream(outputStreamCaptor));
|
||||||
|
var jmod = new JmodOperation().cmdFiles("src/test/resources/jlink/options_version.txt");
|
||||||
|
assertDoesNotThrow(jmod::execute);
|
||||||
|
var out = outputStreamCaptor.toString();
|
||||||
|
assertTrue(out.matches("[\\d.]+[\\r\\n]+"), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCmdFilesCreate() throws IOException {
|
||||||
|
var tmpdir = Files.createTempDirectory("bld-jmod-test").toFile();
|
||||||
|
try {
|
||||||
|
var mod = new File(tmpdir, "dev.mccue.tree.jmod");
|
||||||
|
|
||||||
|
var jmod = new JmodOperation()
|
||||||
|
.cmdFiles("src/test/resources/jlink/options_jmod.txt")
|
||||||
|
.jmodFile(mod.getAbsolutePath());
|
||||||
|
|
||||||
|
assertDoesNotThrow(jmod::execute);
|
||||||
|
assertTrue(mod.exists(), "mod does not exist");
|
||||||
|
} finally {
|
||||||
|
FileUtils.deleteDirectory(tmpdir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCreate() throws IOException {
|
||||||
|
var tmpdir = Files.createTempDirectory("bld-jmod-test").toFile();
|
||||||
|
try {
|
||||||
|
var mod = new File(tmpdir, "dev.mccue.tree.jmod");
|
||||||
|
|
||||||
|
var options = new JmodOptions()
|
||||||
|
.date(ZonedDateTime.now())
|
||||||
|
.legalNotices("src/test/resources/jlink/dev.mccue.apple/legal")
|
||||||
|
.classpath("src/test/resources/jlink/build/jar/dev.mccue.apple.jar");
|
||||||
|
var jmod = new JmodOperation()
|
||||||
|
.operationMode(OperationMode.CREATE)
|
||||||
|
.jmodFile(mod.getAbsolutePath())
|
||||||
|
.jmodOptions(options);
|
||||||
|
|
||||||
|
assertDoesNotThrow(jmod::execute);
|
||||||
|
assertTrue(mod.exists(), "mod does not exist");
|
||||||
|
} finally {
|
||||||
|
FileUtils.deleteDirectory(tmpdir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testExecute() throws IOException {
|
||||||
|
var tmpdir = Files.createTempDirectory("bld-jmod-test").toFile();
|
||||||
|
try {
|
||||||
|
var mod = new File(tmpdir, "dev.mccue.tree.jmod");
|
||||||
|
|
||||||
|
var options = new JmodOptions().classpath("src/test/resources/jlink/build/jar/dev.mccue.tree.jar");
|
||||||
|
if (Runtime.version().version().get(0) >= 20) {
|
||||||
|
options.compress(ZipCompression.ZIP_9);
|
||||||
|
}
|
||||||
|
|
||||||
|
var jmod = new JmodOperation()
|
||||||
|
.operationMode(OperationMode.CREATE)
|
||||||
|
.jmodFile(mod.getAbsolutePath())
|
||||||
|
.jmodOptions(options);
|
||||||
|
|
||||||
|
assertDoesNotThrow(jmod::execute);
|
||||||
|
assertTrue(mod.exists(), "mod does not exist");
|
||||||
|
|
||||||
|
jmod.jmodOptions().clear();
|
||||||
|
System.setOut(new PrintStream(outputStreamCaptor));
|
||||||
|
|
||||||
|
jmod.operationMode(OperationMode.DESCRIBE);
|
||||||
|
assertDoesNotThrow(jmod::execute, "describe mod failed");
|
||||||
|
assertTrue(outputStreamCaptor.toString().contains("dev.mccue.tree"),
|
||||||
|
"missing dev.mccue.tee in:\n" + outputStreamCaptor);
|
||||||
|
|
||||||
|
jmod.operationMode(OperationMode.LIST);
|
||||||
|
assertDoesNotThrow(jmod::execute, "list mod failed");
|
||||||
|
assertTrue(outputStreamCaptor.toString().contains("module-info.class"),
|
||||||
|
"missing module-info.class in:\n" + outputStreamCaptor);
|
||||||
|
} finally {
|
||||||
|
FileUtils.deleteDirectory(tmpdir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHelp() {
|
||||||
|
var jmod = new JmodOperation().toolArgs("--help-extra");
|
||||||
|
assertDoesNotThrow(jmod::execute);
|
||||||
|
assertTrue(jmod.toolArgs().isEmpty(), "args not empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testNoArguments() {
|
||||||
|
var jmod = new JmodOperation();
|
||||||
|
assertTrue(jmod.cmdFiles().isEmpty(), "file options not empty");
|
||||||
|
assertTrue(jmod.jmodOptions().isEmpty(), "jmod options not empty");
|
||||||
|
assertThrows(ExitStatusException.class, jmod::execute);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testVersion() {
|
||||||
|
System.setOut(new PrintStream(outputStreamCaptor));
|
||||||
|
var jmod = new JmodOperation().toolArgs("--version");
|
||||||
|
assertDoesNotThrow(jmod::execute);
|
||||||
|
var out = outputStreamCaptor.toString();
|
||||||
|
assertTrue(out.matches("[\\d.]+[\\r\\n]+"), out);
|
||||||
|
}
|
||||||
|
}
|
231
src/test/java/rife/bld/operations/TestJpackageOperation.java
Normal file
231
src/test/java/rife/bld/operations/TestJpackageOperation.java
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Erik C. Thauvin (https://erik.thauvin.net/)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.operations;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import rife.bld.operations.exceptions.ExitStatusException;
|
||||||
|
import rife.tools.FileUtils;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static rife.bld.operations.JpackageOptions.Launcher;
|
||||||
|
import static rife.bld.operations.JpackageOptions.PackageType;
|
||||||
|
|
||||||
|
public class TestJpackageOperation {
|
||||||
|
private final ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream();
|
||||||
|
private final PrintStream stdout = System.out;
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void tearDown() {
|
||||||
|
System.setOut(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testArguments() {
|
||||||
|
var args = new HashMap<String, String>();
|
||||||
|
args.put("--about-url", "about-url");
|
||||||
|
args.put("--add-launcher", "name=path");
|
||||||
|
args.put("--add-modules", "modules-1,modules-2");
|
||||||
|
args.put("--app-content", "content-1,content-2");
|
||||||
|
args.put("--app-image", "app-image");
|
||||||
|
args.put("--app-version", "app-version");
|
||||||
|
args.put("--arguments", "argument1 argument2");
|
||||||
|
args.put("--copyright", "copyright");
|
||||||
|
args.put("--description", "description");
|
||||||
|
args.put("--dest", "dest");
|
||||||
|
args.put("--file-associations", "file-associations");
|
||||||
|
args.put("--icon", "icon");
|
||||||
|
args.put("--input", "input");
|
||||||
|
args.put("--install-dir", "install-dir");
|
||||||
|
args.put("--java-options", "java-options");
|
||||||
|
args.put("--jlink-options", "--strip-debug --add-modules module-1,module-2");
|
||||||
|
args.put("--launcher-as-service", null);
|
||||||
|
args.put("--license-file", "license-file");
|
||||||
|
args.put("--linux-app-category", "linux-app-category");
|
||||||
|
args.put("--linux-app-release", "linux-app-release");
|
||||||
|
args.put("--linux-deb-maintainer", "linux-deb-maintainer");
|
||||||
|
args.put("--linux-menu-group", "linux-menu-group");
|
||||||
|
args.put("--linux-package-deps", null);
|
||||||
|
args.put("--linux-package-name", "linux-package-name");
|
||||||
|
args.put("--linux-rpm-license-type", "linux-rpm-license-type");
|
||||||
|
args.put("--linux-shortcut", null);
|
||||||
|
args.put("--mac-app-category", "mac-app-category");
|
||||||
|
args.put("--mac-app-image-sign-identity", "mac-app-image-sign-identity");
|
||||||
|
args.put("--mac-app-store", null);
|
||||||
|
args.put("--mac-dmg-content", "mac-dmg-content");
|
||||||
|
args.put("--mac-entitlements", "mac-entitlements");
|
||||||
|
args.put("--mac-installer-sign-identity", "mac-installer-sign-identity");
|
||||||
|
args.put("--mac-package-identifier", "mac-package-identifier");
|
||||||
|
args.put("--mac-package-name", "mac-package-name");
|
||||||
|
args.put("--mac-package-signing-prefix", "mac-package-signing-prefix");
|
||||||
|
args.put("--mac-sign", null);
|
||||||
|
args.put("--mac-signing-key-user-name", "mac-signing-key-user-name");
|
||||||
|
args.put("--mac-signing-keychain", "mac-signing-keychain");
|
||||||
|
args.put("--main-class", "main-class");
|
||||||
|
args.put("--main-jar", "main-jar");
|
||||||
|
args.put("--module", "module");
|
||||||
|
args.put("--module-path", "module-path-1:module-path-2");
|
||||||
|
args.put("--name", "name");
|
||||||
|
args.put("--resource-dir", "resource-dir");
|
||||||
|
args.put("--runtime-image", "runtime-image");
|
||||||
|
args.put("--strip-debug", null);
|
||||||
|
args.put("--temp", "temp");
|
||||||
|
args.put("--type", "exe");
|
||||||
|
args.put("--vendor", "vendor");
|
||||||
|
args.put("--verbose", null);
|
||||||
|
args.put("--win-console", null);
|
||||||
|
args.put("--win-dir-chooser", null);
|
||||||
|
args.put("--win-help-url", "win-help-url");
|
||||||
|
args.put("--win-menu", null);
|
||||||
|
args.put("--win-menu-group", "win-menu-group");
|
||||||
|
args.put("--win-per-user-install", null);
|
||||||
|
args.put("--win-shortcut", null);
|
||||||
|
args.put("--win-shortcut-prompt", null);
|
||||||
|
args.put("--win-update-url", "win-update-url");
|
||||||
|
args.put("--win-upgrade-uuid", "win-upgrade-uuid");
|
||||||
|
|
||||||
|
var options = new JpackageOptions()
|
||||||
|
.aboutUrl(args.get("--about-url"))
|
||||||
|
.addLauncher(new Launcher("name", "path"))
|
||||||
|
.addModules(args.get("--add-modules").split(","))
|
||||||
|
.appContent(args.get("--app-content").split(","))
|
||||||
|
.appImage(args.get("--app-image"))
|
||||||
|
.appVersion(args.get("--app-version"))
|
||||||
|
.arguments(args.get("--arguments").split(" "))
|
||||||
|
.copyright(args.get("--copyright"))
|
||||||
|
.description(args.get("--description"))
|
||||||
|
.dest(args.get("--dest"))
|
||||||
|
.fileAssociations(args.get("--file-associations").split(","))
|
||||||
|
.icon(args.get("--icon"))
|
||||||
|
.input(args.get("--input"))
|
||||||
|
.installDir(args.get("--install-dir"))
|
||||||
|
.javaOptions(args.get("--java-options").split(","))
|
||||||
|
.jlinkOptions(new JlinkOptions().stripDebug(true).addModules("module-1", "module-2"))
|
||||||
|
.launcherAsService(true)
|
||||||
|
.licenseFile(args.get("--license-file"))
|
||||||
|
.linuxAppCategory(args.get("--linux-app-category"))
|
||||||
|
.linuxAppRelease(args.get("--linux-app-release"))
|
||||||
|
.linuxDebMaintainer(args.get("--linux-deb-maintainer"))
|
||||||
|
.linuxMenuGroup(args.get("--linux-menu-group"))
|
||||||
|
.linuxPackageDeps(true)
|
||||||
|
.linuxPackageName(args.get("--linux-package-name"))
|
||||||
|
.linuxRpmLicenseType(args.get("--linux-rpm-license-type"))
|
||||||
|
.linuxShortcut(true)
|
||||||
|
.macAppCategory(args.get("--mac-app-category"))
|
||||||
|
.macAppImageSignIdentity(args.get("--mac-app-image-sign-identity"))
|
||||||
|
.macAppStore(true)
|
||||||
|
.macDmgContent(args.get("--mac-dmg-content"))
|
||||||
|
.macEntitlements(args.get("--mac-entitlements"))
|
||||||
|
.macInstallerSignIdentity(args.get("--mac-installer-sign-identity"))
|
||||||
|
.macPackageIdentifier(args.get("--mac-package-identifier"))
|
||||||
|
.macPackageName(args.get("--mac-package-name"))
|
||||||
|
.macPackageSigningPrefix(args.get("--mac-package-signing-prefix"))
|
||||||
|
.macSign(true)
|
||||||
|
.macSigningKeyUserName(args.get("--mac-signing-key-user-name"))
|
||||||
|
.macSigningKeychain(args.get("--mac-signing-keychain"))
|
||||||
|
.mainClass(args.get("--main-class"))
|
||||||
|
.mainJar(args.get("--main-jar"))
|
||||||
|
.module(args.get("--module"))
|
||||||
|
.modulePath(args.get("--module-path").split(","))
|
||||||
|
.name(args.get("--name"))
|
||||||
|
.resourceDir(args.get("--resource-dir"))
|
||||||
|
.runtimeImage(args.get("--runtime-image"))
|
||||||
|
.stripDebug(true)
|
||||||
|
.temp(args.get("--temp"))
|
||||||
|
.type(PackageType.EXE)
|
||||||
|
.vendor(args.get("--vendor"))
|
||||||
|
.verbose(true)
|
||||||
|
.winConsole(true)
|
||||||
|
.winDirChooser(true)
|
||||||
|
.winHelpUrl(args.get("--win-help-url"))
|
||||||
|
.winMenu(true)
|
||||||
|
.winMenuGroup(args.get("--win-menu-group"))
|
||||||
|
.winPerUserInstall(true)
|
||||||
|
.winShortcut(true)
|
||||||
|
.winShortcutPrompt(true)
|
||||||
|
.winUpdateUrl(args.get("--win-update-url"))
|
||||||
|
.winUpgradeUuid(args.get("--win-upgrade-uuid"));
|
||||||
|
|
||||||
|
assertEquals(options.size(), args.size(), "Wrong number of arguments");
|
||||||
|
|
||||||
|
for (var arg : args.entrySet()) {
|
||||||
|
assertTrue(options.containsKey(arg.getKey()), arg.getValue() + " not found");
|
||||||
|
assertEquals(arg.getValue(), options.get(arg.getKey()), arg.getKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCreatePackage() throws Exception {
|
||||||
|
var tmpdir = Files.createTempDirectory("bld-jpackage-test").toFile();
|
||||||
|
try {
|
||||||
|
var jlinkOptions = new JlinkOptions()
|
||||||
|
.compress(JlinkOptions.CompressionLevel.ZIP)
|
||||||
|
.stripNativeCommands(true);
|
||||||
|
var options = new JpackageOptions()
|
||||||
|
.input("lib/bld")
|
||||||
|
.name("bld")
|
||||||
|
.mainJar("bld-wrapper.jar")
|
||||||
|
.javaOptions("--enable-preview")
|
||||||
|
.dest(tmpdir.getAbsolutePath())
|
||||||
|
.verbose(true)
|
||||||
|
.jlinkOptions(jlinkOptions);
|
||||||
|
var os = System.getProperty("os.version");
|
||||||
|
if (os.endsWith("MANJARO")) {
|
||||||
|
options.type(PackageType.DEB);
|
||||||
|
}
|
||||||
|
|
||||||
|
var jpackage = new JpackageOperation().jpackageOptions(options);
|
||||||
|
jpackage.execute();
|
||||||
|
|
||||||
|
var files = tmpdir.listFiles();
|
||||||
|
assertNotNull(files, "files should not be null");
|
||||||
|
assertTrue(files.length > 0, "no files found");
|
||||||
|
|
||||||
|
assertTrue(files[0].getName().matches("bld.*\\.[A-Za-z]{3}"), "Package not found");
|
||||||
|
} finally {
|
||||||
|
FileUtils.deleteDirectory(tmpdir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCmdFiles() {
|
||||||
|
System.setOut(new PrintStream(outputStreamCaptor));
|
||||||
|
var jpackage = new JpackageOperation().cmdFiles("src/test/resources/jlink/options_verbose.txt",
|
||||||
|
"src/test/resources/jlink/options_version.txt");
|
||||||
|
assertDoesNotThrow(jpackage::execute);
|
||||||
|
var out = outputStreamCaptor.toString();
|
||||||
|
assertTrue(out.matches("[\\d.]+[\\r\\n]+"), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHelp() {
|
||||||
|
var jpackage = new JpackageOperation().toolArgs("--help");
|
||||||
|
assertDoesNotThrow(jpackage::execute);
|
||||||
|
assertTrue(jpackage.toolArgs().isEmpty(), "args not empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testNoArguments() {
|
||||||
|
var jpackage = new JpackageOperation();
|
||||||
|
assertTrue(jpackage.fileOptions().isEmpty(), "file options not empty");
|
||||||
|
assertTrue(jpackage.jpackageOptions().isEmpty(), "jpackage options not empty");
|
||||||
|
assertThrows(ExitStatusException.class, jpackage::execute);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testVersion() {
|
||||||
|
System.setOut(new PrintStream(outputStreamCaptor));
|
||||||
|
var jpackage = new JpackageOperation().toolArgs("--verbose", "--version");
|
||||||
|
assertDoesNotThrow(jpackage::execute);
|
||||||
|
var out = outputStreamCaptor.toString();
|
||||||
|
assertTrue(out.matches("[\\d.]+[\\r\\n]+"), out);
|
||||||
|
}
|
||||||
|
}
|
2
src/test/resources/jlink/.gitignore
vendored
Normal file
2
src/test/resources/jlink/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
build/javac
|
||||||
|
build/jar
|
40
src/test/resources/jlink/Makefile
Normal file
40
src/test/resources/jlink/Makefile
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -rf build
|
||||||
|
|
||||||
|
.PHONY: compile
|
||||||
|
compile: clean
|
||||||
|
javac -d build/javac --module-source-path "./*/src" --module dev.mccue.tree,dev.mccue.apple
|
||||||
|
|
||||||
|
.PHONY: package
|
||||||
|
package: compile
|
||||||
|
mkdir -p build/jar
|
||||||
|
|
||||||
|
jar --create --file build/jar/dev.mccue.apple.jar \
|
||||||
|
-C build/javac/dev.mccue.apple . \
|
||||||
|
-C dev.mccue.apple/res .
|
||||||
|
jar --create --file build/jar/dev.mccue.tree.jar \
|
||||||
|
-C build/javac/dev.mccue.tree .
|
||||||
|
|
||||||
|
.PHONY: link
|
||||||
|
link: package
|
||||||
|
mkdir -p build/jmod
|
||||||
|
|
||||||
|
jmod create \
|
||||||
|
--legal-notices dev.mccue.apple/legal \
|
||||||
|
--class-path build/jar/dev.mccue.apple.jar \
|
||||||
|
build/jmod/dev.mccue.apple.jmod
|
||||||
|
|
||||||
|
jmod create \
|
||||||
|
--class-path build/jar/dev.mccue.tree.jar \
|
||||||
|
build/jmod/dev.mccue.tree.jmod
|
||||||
|
|
||||||
|
jlink \
|
||||||
|
--module-path build/jmod \
|
||||||
|
--add-modules dev.mccue.tree \
|
||||||
|
--launcher tree=dev.mccue.tree/dev.mccue.tree.Tree \
|
||||||
|
--output build/jlink
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
|
test: link
|
||||||
|
./build/jlink/bin/tree
|
BIN
src/test/resources/jlink/build/jar/dev.mccue.apple.jar
Normal file
BIN
src/test/resources/jlink/build/jar/dev.mccue.apple.jar
Normal file
Binary file not shown.
BIN
src/test/resources/jlink/build/jar/dev.mccue.tree.jar
Normal file
BIN
src/test/resources/jlink/build/jar/dev.mccue.tree.jar
Normal file
Binary file not shown.
BIN
src/test/resources/jlink/build/jmod/dev.mccue.apple.jmod
Normal file
BIN
src/test/resources/jlink/build/jmod/dev.mccue.apple.jmod
Normal file
Binary file not shown.
BIN
src/test/resources/jlink/build/jmod/dev.mccue.tree.jmod
Normal file
BIN
src/test/resources/jlink/build/jmod/dev.mccue.tree.jmod
Normal file
Binary file not shown.
11
src/test/resources/jlink/dev.mccue.apple/dev.mccue.apple.iml
Normal file
11
src/test/resources/jlink/dev.mccue.apple/dev.mccue.apple.iml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
1
src/test/resources/jlink/dev.mccue.apple/legal/LICENSE
Normal file
1
src/test/resources/jlink/dev.mccue.apple/legal/LICENSE
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Apples are GOD'S creation. You have no right to them.
|
|
@ -0,0 +1 @@
|
||||||
|
red
|
|
@ -0,0 +1,20 @@
|
||||||
|
package dev.mccue.apple;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UncheckedIOException;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public final class Apple {
|
||||||
|
public String color() {
|
||||||
|
try {
|
||||||
|
return new String(
|
||||||
|
Objects.requireNonNull(
|
||||||
|
Apple.class.getResourceAsStream("/dev/mccue/apple/color.txt")
|
||||||
|
).readAllBytes()
|
||||||
|
);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new UncheckedIOException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
module dev.mccue.apple {
|
||||||
|
exports dev.mccue.apple;
|
||||||
|
}
|
12
src/test/resources/jlink/dev.mccue.tree/dev.mccue.tree.iml
Normal file
12
src/test/resources/jlink/dev.mccue.tree/dev.mccue.tree.iml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="module" module-name="dev.mccue.apple" />
|
||||||
|
</component>
|
||||||
|
</module>
|
|
@ -0,0 +1,15 @@
|
||||||
|
package dev.mccue.tree;
|
||||||
|
|
||||||
|
import dev.mccue.apple.Apple;
|
||||||
|
|
||||||
|
public final class Tree {
|
||||||
|
public Apple bearFruit() {
|
||||||
|
return new Apple();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println(
|
||||||
|
new Tree().bearFruit().color()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
module dev.mccue.tree {
|
||||||
|
requires dev.mccue.apple;
|
||||||
|
}
|
5
src/test/resources/jlink/options_jlink.txt
Normal file
5
src/test/resources/jlink/options_jlink.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
--verbose --version #--foo
|
||||||
|
--module-path "\'foo --bar\' \"bar --foo\" --bar" --list-plugins
|
||||||
|
--output foo --bind-services
|
||||||
|
|
||||||
|
# bar
|
5
src/test/resources/jlink/options_jlink_win.txt
Normal file
5
src/test/resources/jlink/options_jlink_win.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
--verbose --version #--foo
|
||||||
|
--module-path "\'foo --bar\' --bar" --list-plugins
|
||||||
|
--output foo --bind-services
|
||||||
|
|
||||||
|
# bar
|
3
src/test/resources/jlink/options_jmod.txt
Normal file
3
src/test/resources/jlink/options_jmod.txt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
create
|
||||||
|
--legal-notices src/test/resources/jlink/dev.mccue.apple/legal
|
||||||
|
--class-path src/test/resources/jlink/build/jar/dev.mccue.apple.jar
|
1
src/test/resources/jlink/options_verbose.txt
Normal file
1
src/test/resources/jlink/options_verbose.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
--verbose
|
1
src/test/resources/jlink/options_version.txt
Normal file
1
src/test/resources/jlink/options_version.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
--version
|
Loading…
Add table
Add a link
Reference in a new issue