add more options, add jrun task

This commit is contained in:
Jörg Prante 2024-11-08 17:40:22 +01:00
parent ac147ef72e
commit 816dd9d6ab
8 changed files with 273 additions and 35 deletions

View file

@ -0,0 +1,4 @@
package org.xbib.gradle.plugin.jlink;
public class JDepsExtension {
}

View file

@ -42,6 +42,8 @@ public abstract class JLinkPlugin implements Plugin<Project> {
jModExtension.getCompress().convention(6); // zip-6, default jModExtension.getCompress().convention(6); // zip-6, default
jModExtension.getCmds().unsetConvention(); jModExtension.getCmds().unsetConvention();
jModExtension.getConfigs().unsetConvention(); jModExtension.getConfigs().unsetConvention();
jModExtension.getHeaderFiles().unsetConvention();
jModExtension.getLibs().unsetConvention();
JLinkExtension jLinkExtension = project.getExtensions().create("jlink", JLinkExtension.class); JLinkExtension jLinkExtension = project.getExtensions().create("jlink", JLinkExtension.class);
jLinkExtension.getJavaCompiler().convention(service.compilerFor(toolchain)); jLinkExtension.getJavaCompiler().convention(service.compilerFor(toolchain));
@ -60,7 +62,7 @@ public abstract class JLinkPlugin implements Plugin<Project> {
jLinkExtension.getAddModules().convention(List.of("java.base")); jLinkExtension.getAddModules().convention(List.of("java.base"));
jLinkExtension.getLimitModules().convention(List.of()); jLinkExtension.getLimitModules().convention(List.of());
jLinkExtension.getBindServices().convention(false); jLinkExtension.getBindServices().convention(false);
jLinkExtension.getLauncher().unsetConvention(); jLinkExtension.getLauncher().convention(project.getName());
jLinkExtension.getCompress().convention(6); // zip-6, default jLinkExtension.getCompress().convention(6); // zip-6, default
jLinkExtension.getStripDebug().convention(true); // same as jpackage default jLinkExtension.getStripDebug().convention(true); // same as jpackage default
jLinkExtension.getStripNativeCommands().convention(false); // keep commands jLinkExtension.getStripNativeCommands().convention(false); // keep commands
@ -75,8 +77,14 @@ public abstract class JLinkPlugin implements Plugin<Project> {
jPackageExtension.getModule().unsetConvention(); jPackageExtension.getModule().unsetConvention();
jPackageExtension.getInput().convention(project.getLayout().getBuildDirectory().dir("jlink")); jPackageExtension.getInput().convention(project.getLayout().getBuildDirectory().dir("jlink"));
jPackageExtension.getType().convention("rpm"); // Fedora/Red Hat Linux jPackageExtension.getType().convention("rpm"); // Fedora/Red Hat Linux
jPackageExtension.getjLinkOptions().convention(List.of("--strip-native-commands", "--strip-debug", "--no-man-pages", "--no-header-files")); // same as jpackage default
jPackageExtension.getAppName().convention(project.getName()); jPackageExtension.getAppName().convention(project.getName());
jPackageExtension.getAppVersion().convention(project.getVersion().toString()); jPackageExtension.getAppVersion().convention(project.getVersion().toString());
jPackageExtension.getAppVendor().unsetConvention();
jPackageExtension.getAppCopyright().unsetConvention();
jPackageExtension.getAppDescription().unsetConvention();
jPackageExtension.getAppIcon().unsetConvention();
jPackageExtension.getAppImage().unsetConvention();
// install the jmod task // install the jmod task
TaskProvider<JModTask> jModTask = project.getTasks().register("jmod", JModTask.class); TaskProvider<JModTask> jModTask = project.getTasks().register("jmod", JModTask.class);
@ -90,6 +98,8 @@ public abstract class JLinkPlugin implements Plugin<Project> {
it.compress.set(jModExtension.getCompress()); it.compress.set(jModExtension.getCompress());
it.cmds.set(jModExtension.getCmds()); it.cmds.set(jModExtension.getCmds());
it.configs.set(jModExtension.getConfigs()); it.configs.set(jModExtension.getConfigs());
it.headerFiles.set(jModExtension.getHeaderFiles());
it.libs.set(jModExtension.getLibs());
}); });
// install the jdeps task // install the jdeps task
@ -120,6 +130,7 @@ public abstract class JLinkPlugin implements Plugin<Project> {
it.noManPages.set(jLinkExtension.getNoManPages()); it.noManPages.set(jLinkExtension.getNoManPages());
it.endian.set(jLinkExtension.getEndian()); it.endian.set(jLinkExtension.getEndian());
}); });
// depend jpackage on jlink task // depend jpackage on jlink task
TaskProvider<JPackageTask> jPackageTask = project.getTasks().register("jpackage", JPackageTask.class); TaskProvider<JPackageTask> jPackageTask = project.getTasks().register("jpackage", JPackageTask.class);
project.getTasks().withType(JPackageTask.class).forEach(it -> { project.getTasks().withType(JPackageTask.class).forEach(it -> {
@ -132,9 +143,24 @@ public abstract class JLinkPlugin implements Plugin<Project> {
it.module.set(jPackageExtension.getModule()); it.module.set(jPackageExtension.getModule());
it.input.set(jPackageExtension.getInput()); it.input.set(jPackageExtension.getInput());
it.type.set(jPackageExtension.getType()); it.type.set(jPackageExtension.getType());
it.jLinkOptions.set(jPackageExtension.getjLinkOptions());
it.appName.set(jPackageExtension.getAppName()); it.appName.set(jPackageExtension.getAppName());
it.appVersion.set(jPackageExtension.getAppVersion()); it.appVersion.set(jPackageExtension.getAppVersion());
it.appCopyright.set(jPackageExtension.getAppCopyright());
it.appVendor.set(jPackageExtension.getAppVendor());
it.appDescription.set(jPackageExtension.getAppDescription());
it.appIcon.set(jPackageExtension.getAppIcon());
it.appImage.set(jPackageExtension.getAppImage());
}); });
TaskProvider<JRunTask> jRunTask = project.getTasks().register("jrun", JRunTask.class);
project.getTasks().withType(JRunTask.class).forEach(it -> {
it.setGroup("run");
it.dependsOn(jLinkTask);
it.exec.set(jLinkExtension.getjLinkOutputDirectory().file("bin/" +
prefix("=", jLinkExtension.getLauncher().get())));
});
Configuration jLinkConfiguration = project.getConfigurations().create("jlink"); Configuration jLinkConfiguration = project.getConfigurations().create("jlink");
jLinkConfiguration.setCanBeConsumed(true); jLinkConfiguration.setCanBeConsumed(true);
jLinkConfiguration.setCanBeResolved(false); jLinkConfiguration.setCanBeResolved(false);
@ -150,4 +176,9 @@ public abstract class JLinkPlugin implements Plugin<Project> {
project.getObjects().named(Usage.class, "jpackage"))); project.getObjects().named(Usage.class, "jpackage")));
jPackageConfiguration.outgoing(o -> o.artifact(jPackageTask.flatMap(t -> t.jPackageOutputDirectory))); jPackageConfiguration.outgoing(o -> o.artifact(jPackageTask.flatMap(t -> t.jPackageOutputDirectory)));
} }
private static String prefix(String delimiter, String string) {
String[] s = string.split(delimiter);
return s.length > 0 ? s[0] : string;
}
} }

View file

@ -5,6 +5,8 @@ import org.gradle.api.file.Directory;
import org.gradle.api.file.DirectoryProperty; import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.provider.ListProperty; import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.Property; import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Optional;
import java.util.List; import java.util.List;
@ -20,12 +22,18 @@ public class JModExtension {
private final ListProperty<String> configs; private final ListProperty<String> configs;
private final ListProperty<String> headerFiles;
private final ListProperty<String> libs;
public JModExtension(Project project) { public JModExtension(Project project) {
jModDirectory = project.getObjects().directoryProperty(); jModDirectory = project.getObjects().directoryProperty();
moduleVersion = project.getObjects().property(String.class); moduleVersion = project.getObjects().property(String.class);
compress = project.getObjects().property(Integer.class); compress = project.getObjects().property(Integer.class);
cmds = project.getObjects().listProperty(String.class); cmds = project.getObjects().listProperty(String.class);
configs = project.getObjects().listProperty(String.class); configs = project.getObjects().listProperty(String.class);
headerFiles = project.getObjects().listProperty(String.class);
libs = project.getObjects().listProperty(String.class);
} }
public void setjModDirectory(Directory jModDirectory) { public void setjModDirectory(Directory jModDirectory) {
@ -67,4 +75,20 @@ public class JModExtension {
public ListProperty<String> getConfigs() { public ListProperty<String> getConfigs() {
return configs; return configs;
} }
public void setHeaderFiles(List<String> headerFiles) {
this.headerFiles.set(headerFiles);
}
public ListProperty<String> getHeaderFiles() {
return headerFiles;
}
public void setLibs(List<String> libs) {
this.libs.set(libs);
}
public ListProperty<String> getLibs() {
return libs;
}
} }

View file

@ -6,6 +6,8 @@ import org.gradle.api.file.Directory;
import org.gradle.api.file.DirectoryProperty; import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.provider.ListProperty; import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.Property; import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Optional;
import org.gradle.jvm.toolchain.JavaCompiler; import org.gradle.jvm.toolchain.JavaCompiler;
public class JPackageExtension { public class JPackageExtension {
@ -20,18 +22,36 @@ public class JPackageExtension {
private final Property<String> type; private final Property<String> type;
private final ListProperty<String> jLinkOptions;
private final Property<String> appName; private final Property<String> appName;
private final Property<String> appVersion; private final Property<String> appVersion;
private final Property<String> appCopyright;
private final Property<String> appVendor;
private final Property<String> appDescription;
private final Property<String> appIcon;
private final DirectoryProperty appImage;
public JPackageExtension(Project project) { public JPackageExtension(Project project) {
jPackageOutputDirectory = project.getObjects().directoryProperty(); jPackageOutputDirectory = project.getObjects().directoryProperty();
addModules = project.getObjects().listProperty(String.class); addModules = project.getObjects().listProperty(String.class);
module = project.getObjects().property(String.class); module = project.getObjects().property(String.class);
input = project.getObjects().directoryProperty(); input = project.getObjects().directoryProperty();
type = project.getObjects().property(String.class); type = project.getObjects().property(String.class);
jLinkOptions = project.getObjects().listProperty(String.class);
appName = project.getObjects().property(String.class); appName = project.getObjects().property(String.class);
appVersion = project.getObjects().property(String.class); appVersion = project.getObjects().property(String.class);
appCopyright = project.getObjects().property(String.class);
appVendor = project.getObjects().property(String.class);
appDescription = project.getObjects().property(String.class);
appIcon = project.getObjects().property(String.class);
appImage = project.getObjects().directoryProperty();
} }
public void setjPackageOutputDirectory(Directory jPackageOutputDirectory) { public void setjPackageOutputDirectory(Directory jPackageOutputDirectory) {
@ -74,6 +94,14 @@ public class JPackageExtension {
return type; return type;
} }
public void setjLinkOptions(List<String> jLinkOptions) {
this.jLinkOptions.set(jLinkOptions);
}
public ListProperty<String> getjLinkOptions() {
return jLinkOptions;
}
public void setAppName(String appName) { public void setAppName(String appName) {
this.appName.set(appName); this.appName.set(appName);
} }
@ -89,4 +117,44 @@ public class JPackageExtension {
public Property<String> getAppVersion() { public Property<String> getAppVersion() {
return appVersion; return appVersion;
} }
public void setAppCopyright(String appCopyright) {
this.appCopyright.set(appCopyright);
}
public Property<String> getAppCopyright() {
return appCopyright;
}
public void setAppVendor(String appVendor) {
this.appVendor.set(appVendor);
}
public Property<String> getAppVendor() {
return appVendor;
}
public void setAppDescription(String appDescription) {
this.appDescription.set(appDescription);
}
public Property<String> getAppDescription() {
return appDescription;
}
public void setAppIcon(String appIcon) {
this.appIcon.set(appIcon);
}
public Property<String> getAppIcon() {
return appIcon;
}
public void setAppImage(Directory appImage) {
this.appImage .set(appImage);
}
public DirectoryProperty getAppImage() {
return appImage;
}
} }

View file

@ -43,10 +43,6 @@ public class JPackageTask extends AbstractExecTask<JPackageTask> {
@Input @Input
Property<String> module; Property<String> module;
@Input
@Optional
Property<String> appImage;
@InputDirectory @InputDirectory
@Optional @Optional
DirectoryProperty input; DirectoryProperty input;
@ -55,6 +51,10 @@ public class JPackageTask extends AbstractExecTask<JPackageTask> {
@Optional @Optional
Property<String> type; Property<String> type;
@Input
@Optional
ListProperty<String> jLinkOptions;
@Input @Input
@Optional @Optional
Property<String> appName; Property<String> appName;
@ -65,7 +65,11 @@ public class JPackageTask extends AbstractExecTask<JPackageTask> {
@Input @Input
@Optional @Optional
Property<String> copyright; Property<String> appCopyright;
@Input
@Optional
Property<String> appVendor;
@Input @Input
@Optional @Optional
@ -73,7 +77,11 @@ public class JPackageTask extends AbstractExecTask<JPackageTask> {
@Input @Input
@Optional @Optional
Property<String> icon; Property<String> appIcon;
@InputDirectory
@Optional
DirectoryProperty appImage;
@Inject @Inject
public JPackageTask() { public JPackageTask() {
@ -84,14 +92,16 @@ public class JPackageTask extends AbstractExecTask<JPackageTask> {
jPackageOutputDirectory = getProject().getObjects().directoryProperty(); jPackageOutputDirectory = getProject().getObjects().directoryProperty();
addModules = getProject().getObjects().listProperty(String.class); addModules = getProject().getObjects().listProperty(String.class);
module = getProject().getObjects().property(String.class); module = getProject().getObjects().property(String.class);
appImage = getProject().getObjects().property(String.class);
input = getProject().getObjects().directoryProperty(); input = getProject().getObjects().directoryProperty();
type = getProject().getObjects().property(String.class); type = getProject().getObjects().property(String.class);
jLinkOptions = getProject().getObjects().listProperty(String.class);
appName = getProject().getObjects().property(String.class); appName = getProject().getObjects().property(String.class);
appVersion = getProject().getObjects().property(String.class); appVersion = getProject().getObjects().property(String.class);
copyright = getProject().getObjects().property(String.class); appCopyright = getProject().getObjects().property(String.class);
appVendor = getProject().getObjects().property(String.class);
appDescription = getProject().getObjects().property(String.class); appDescription = getProject().getObjects().property(String.class);
icon = getProject().getObjects().property(String.class); appIcon = getProject().getObjects().property(String.class);
appImage = getProject().getObjects().directoryProperty();
} }
@Override @Override
@ -120,12 +130,12 @@ public class JPackageTask extends AbstractExecTask<JPackageTask> {
args.add("--input"); args.add("--input");
args.add(input.getAsFile().get().getAbsolutePath()); args.add(input.getAsFile().get().getAbsolutePath());
} }
if (appImage.isPresent()) {
args.add("--app-image");
args.add(appImage.get());
}
args.add("--type"); args.add("--type");
args.add(type.get()); args.add(type.get());
if (jLinkOptions.isPresent() && !jLinkOptions.get().isEmpty()) {
args.add("--jlink-options");
args.add(String.join(" ", jLinkOptions.get()));
}
if (appName.isPresent()) { if (appName.isPresent()) {
args.add("--name"); args.add("--name");
args.add(appName.get()); args.add(appName.get());
@ -134,17 +144,25 @@ public class JPackageTask extends AbstractExecTask<JPackageTask> {
args.add("--app-version"); args.add("--app-version");
args.add(appVersion.get()); args.add(appVersion.get());
} }
if (copyright.isPresent()) { if (appVendor.isPresent()) {
args.add("--vendor");
args.add(appVendor.get());
}
if (appCopyright.isPresent()) {
args.add("--copyright"); args.add("--copyright");
args.add(copyright.get()); args.add(appCopyright.get());
} }
if (appDescription.isPresent()) { if (appDescription.isPresent()) {
args.add("--description"); args.add("--description");
args.add(appDescription.get()); args.add(appDescription.get());
} }
if (icon.isPresent()) { if (appIcon.isPresent()) {
args.add("--icon"); args.add("--icon");
args.add(icon.get()); args.add(appIcon.get());
}
if (appImage.isPresent()) {
args.add("--app-image");
args.add(appImage.getAsFile().get().getAbsolutePath());
} }
setArgs(args); setArgs(args);
getLogger().log(LogLevel.INFO, "executing " + getExecutable() + " with " + getArgs()); getLogger().log(LogLevel.INFO, "executing " + getExecutable() + " with " + getArgs());
@ -191,14 +209,6 @@ public class JPackageTask extends AbstractExecTask<JPackageTask> {
return module; return module;
} }
public void setAppImage(String appImage) {
this.appImage .set(appImage);
}
public Property<String> getAppImage() {
return appImage;
}
public DirectoryProperty getInput() { public DirectoryProperty getInput() {
return input; return input;
} }
@ -211,6 +221,14 @@ public class JPackageTask extends AbstractExecTask<JPackageTask> {
return type; return type;
} }
public void setjLinkOptions(List<String> jLinkOptions) {
this.jLinkOptions.set(jLinkOptions);
}
public ListProperty<String> getjLinkOptions() {
return jLinkOptions;
}
public void setAppName(String appName) { public void setAppName(String appName) {
this.appName.set(appName); this.appName.set(appName);
} }
@ -227,12 +245,20 @@ public class JPackageTask extends AbstractExecTask<JPackageTask> {
return appVersion; return appVersion;
} }
public void setCopyright(String copyright) { public void setAppCopyright(String appCopyright) {
this.copyright.set(copyright); this.appCopyright.set(appCopyright);
} }
public Property<String> getCopyright() { public Property<String> getAppCopyright() {
return copyright; return appCopyright;
}
public void setAppVendor(String appVendor) {
this.appVendor.set(appVendor);
}
public Property<String> getAppVendor() {
return appVendor;
} }
public void setAppDescription(String appDescription) { public void setAppDescription(String appDescription) {
@ -243,12 +269,20 @@ public class JPackageTask extends AbstractExecTask<JPackageTask> {
return appDescription; return appDescription;
} }
public void setIcon(String icon) { public void setAppIcon(String appIcon) {
this.icon.set(icon); this.appIcon.set(appIcon);
} }
public Property<String> getIcon() { public Property<String> getAppIcon() {
return icon; return appIcon;
}
public void setAppImage(Directory appImage) {
this.appImage .set(appImage);
}
public DirectoryProperty getAppImage() {
return appImage;
} }
private static void createDirectory(Path path) throws IOException { private static void createDirectory(Path path) throws IOException {

View file

@ -0,0 +1,34 @@
package org.xbib.gradle.plugin.jlink;
import org.gradle.api.file.RegularFile;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.tasks.AbstractExecTask;
import org.gradle.api.tasks.InputFile;
import javax.inject.Inject;
public class JRunTask extends AbstractExecTask<JRunTask> {
@InputFile
RegularFileProperty exec;
@Inject
public JRunTask() {
super(JRunTask.class);
exec = getProject().getObjects().fileProperty();
}
@Override
public void exec() {
setExecutable(exec.get());
super.exec();
}
public void setExec(RegularFile exec) {
this.exec.set(exec);
}
public RegularFileProperty getExec() {
return exec;
}
}

View file

@ -21,7 +21,6 @@ class JLinkTest extends Specification {
jlink { jlink {
addModules.set(List.of("org.example.app")) addModules.set(List.of("org.example.app"))
launcher.set("app=org.example.app/org.example.app.Main") launcher.set("app=org.example.app/org.example.app.Main")
stripDebug.set(true)
} }
""" """
appModuleInfoFile << """ appModuleInfoFile << """

View file

@ -0,0 +1,44 @@
package org.xbib.gradle.plugin.jlink
import spock.lang.Specification
import static org.gradle.testkit.runner.TaskOutcome.FAILED
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
import static org.xbib.gradle.plugin.jlink.JLinkGradleBuild.runsOnLinux
class JRunTest extends Specification {
@Delegate
JLinkGradleBuild build = new JLinkGradleBuild()
def "can use jlink plugin with jrun task"() {
given:
def taskToRun = ":app:jrun"
appBuildFile << """
dependencies {
api "org.junit.jupiter:junit-jupiter-engine:5.10.2"
}
jlink {
addModules.set(List.of("org.example.app"))
launcher.set("app=org.example.app/org.example.app.Main")
}
"""
appModuleInfoFile << """
module org.example.app {
exports org.example.app;
}
"""
when:
def result = success ? build(taskToRun) : fail(taskToRun)
then:
println result.output
result.task(taskToRun).outcome == (success ? SUCCESS : FAILED)
success
where:
label | os | success
'fedora' | 'linux' | runsOnLinux()
}
}