From 1b6d22e51b1fbc5b4f6f835322ef0b25e8dfbe33 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 5 Jan 2024 17:19:50 -0800 Subject: [PATCH 1/8] More in-depth `--setup`. Add defaults and way to update release channels. --- .../llbit/chunky/launcher/ChunkyLauncher.java | 64 +++++++++++++++++-- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/launcher/src/se/llbit/chunky/launcher/ChunkyLauncher.java b/launcher/src/se/llbit/chunky/launcher/ChunkyLauncher.java index 5ac27bb12..7bec2e694 100644 --- a/launcher/src/se/llbit/chunky/launcher/ChunkyLauncher.java +++ b/launcher/src/se/llbit/chunky/launcher/ChunkyLauncher.java @@ -308,12 +308,66 @@ interface ShowLauncher { private static void doSetup(LauncherSettings settings) throws FileNotFoundException { headlessCreateSettingsDirectory(); - System.out.print("Memory limit (MiB): "); Scanner in = new Scanner(System.in); - settings.memoryLimit = in.nextInt(); - in.nextLine(); - System.out.print("Java options: "); - settings.javaOptions = in.nextLine(); + + System.out.printf("Memory limit (MiB) [%d]: ", settings.memoryLimit); + try { + String memoryLimit = in.nextLine().trim(); + settings.memoryLimit = Integer.parseInt(memoryLimit); + } catch (NumberFormatException ignored) { + } + + System.out.printf("Java options [%s]: ", settings.javaOptions); + { + String javaOptions = in.nextLine().trim(); + if (!javaOptions.isEmpty()) { + settings.javaOptions = javaOptions; + } + } + + System.out.print("Reload release channels [Y/n]: "); + { + String updateReleaseChannels = in.nextLine().trim(); + if (!updateReleaseChannels.contains("n")) { + LauncherInfoChecker checker = new LauncherInfoChecker( + settings, + error -> { + System.err.println("Failed to fetch launcher info!"); + System.err.println(error); + }, + info -> { + if (info != null) { + if (info.version.compareTo(ChunkyLauncher.LAUNCHER_VERSION) > 0) { + System.out.printf("Launcher update found! Version %s released on %s: %s\n", + info.version, info.date, settings.getResourceUrl(info.path)); + if (info.notes.isEmpty()) { + System.out.println("No release notes available."); + } else { + System.out.println(info.notes); + } + System.out.println(); + } + + settings.setReleaseChannels(info.channels); + } + } + ); + checker.start(); + try { + checker.join(); + } catch (InterruptedException e) { + System.err.println("Interrupted!"); + } + } + } + + System.out.println("Available channels:"); + System.out.println(String.join(", ", settings.releaseChannels.keySet())); + System.out.printf("Release channel [%s]: ", settings.selectedChannel.id); + { + String releaseChannel = in.nextLine().trim(); + settings.selectedChannel = settings.releaseChannels.getOrDefault(releaseChannel, settings.selectedChannel); + } } /** From e83f9fcbdd4ad1591a0d453ce0b0b9be0d4cc0a2 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 7 Jan 2024 01:28:01 -0800 Subject: [PATCH 2/8] Bundle apache commons CLI. Port CLI parsing. Add simple test for parsing. --- launcher/build.gradle | 27 +- .../llbit/chunky/launcher/ChunkyLauncher.java | 310 ++++++++++++------ .../launcher/ChunkyLauncherCliParseTest.java | 116 +++++++ 3 files changed, 350 insertions(+), 103 deletions(-) create mode 100644 launcher/test/se/llbit/chunky/launcher/ChunkyLauncherCliParseTest.java diff --git a/launcher/build.gradle b/launcher/build.gradle index da183b841..675b1e2c8 100644 --- a/launcher/build.gradle +++ b/launcher/build.gradle @@ -9,9 +9,13 @@ configurations { } dependencies { - bundled 'org.apache.maven:maven-artifact:3.9.9' + bundled 'org.apache.maven:maven-artifact:3.9.9' + bundled 'commons-cli:commons-cli:1.6.0' - implementation project(':lib') + implementation project(':lib') + + testImplementation 'com.google.truth:truth:1.1.3' + testImplementation 'junit:junit:4.13.2' } java { @@ -21,13 +25,22 @@ java { } } -sourceSets.main { - java.srcDir 'src' +sourceSets { + main { + java { + srcDir 'src' + } resources { - srcDir 'src' - include '**/*.png' - include '**/*.fxml' + srcDir 'src' + include '**/*.png' + include '**/*.fxml' } + } + test { + java { + srcDir 'test' + } + } } jar { diff --git a/launcher/src/se/llbit/chunky/launcher/ChunkyLauncher.java b/launcher/src/se/llbit/chunky/launcher/ChunkyLauncher.java index 7bec2e694..e4d176456 100644 --- a/launcher/src/se/llbit/chunky/launcher/ChunkyLauncher.java +++ b/launcher/src/se/llbit/chunky/launcher/ChunkyLauncher.java @@ -20,6 +20,7 @@ import javafx.stage.Stage; import org.apache.maven.artifact.versioning.ArtifactVersion; import org.apache.maven.artifact.versioning.DefaultArtifactVersion; +import org.apache.commons.cli.*; import se.llbit.chunky.PersistentSettings; import se.llbit.chunky.launcher.ui.ChunkyLauncherFx; import se.llbit.chunky.launcher.ui.DebugConsole; @@ -51,13 +52,98 @@ public class ChunkyLauncher { public static final int LAUNCHER_SETTINGS_REVISION = 1; - /** - * Print a launch error message to the console. - * Prints the command that was used to try to launch Chunky. - */ - protected static void launchFailure(String command) { - System.out.println("Failed to launch Chunky. Command used:"); - System.out.println(command); + public static Options cliOptions() { + Options options = new Options(); + + options.addOption(Option.builder() + .option("h") + .longOpt("help") + .desc("Show this help message") + .build() + ); + + options.addOption(Option.builder() + .longOpt("nolauncher") + .build() + ); + + options.addOption(Option.builder() + .longOpt("launcher") + .desc("Forces the launcher GUI to be shown") + .build() + ); + + options.addOption(Option.builder() + .longOpt("version") + .desc("Show the launcher version and exit") + .build() + ); + + options.addOption(Option.builder() + .longOpt("verbose") + .desc("Enables verbose logging") + .build() + ); + + options.addOption(Option.builder() + .longOpt("console") + .desc("Forces debug console to be opened") + .build() + ); + + options.addOptionGroup(new OptionGroup() + .addOption(Option.builder() + .longOpt("update") + .argName("release channel") + .optionalArg(true) + .desc("Update Chunky to the latest release") + .build() + ) + .addOption(Option.builder() + .longOpt("updateAlpha") + .desc("Update Chunky to the latest snapshot release. Equivalent to `--update snapshot`. (legacy)") + .build() + ) + ); + + options.addOption(Option.builder() + .longOpt("setup") + .desc("Runs the interactive command-line launcher setup") + .build() + ); + + options.addOption(Option.builder() + .longOpt("noRetryJavafx") + .build() + ); + + options.addOption(Option.builder() + .longOpt("javaOptions") + .argName("options") + .optionalArg(false) + .desc("Add a Java option when launching Chunky") + .build() + ); + + options.addOption(Option.builder() + .longOpt("checkJvm") + .desc("Check if JVM version is 64-bit") + .build() + ); + + options.addOption(Option.builder() + .longOpt("dangerouslyDisableLibraryValidation") + .desc("Disable library validation. This can be dangerous!") + .build() + ); + + return options; + } + + public static CommandLine parseCli(String[] args) throws ParseException { + Options options = cliOptions(); + return new DefaultParser() + .parse(options, args, true); } public static void main(String[] args) throws FileNotFoundException { @@ -84,99 +170,90 @@ public static void main(String[] args) throws FileNotFoundException { if (args.length > 0) { mode = LaunchMode.HEADLESS; - for (int i = 0; i < args.length; i++) { - String arg = args[i]; - switch (arg) { - case "--nolauncher": - mode = LaunchMode.GUI; - break; - case "--launcher": - forceLauncher = true; - break; - case "--version": - System.out.println("Chunky Launcher v" + LAUNCHER_VERSION); - return; - case "--verbose": - settings.verboseLauncher = true; - break; - case "--console": - settings.forceGuiConsole = true; - break; - case "--update": - case "--updateAlpha": - ReleaseChannel channel; - if (arg.equals("--updateAlpha")) { - channel = LauncherSettings.SNAPSHOT_RELEASE_CHANNEL; - } else { - channel = settings.selectedChannel; - if (i < args.length - 1 && settings.releaseChannels.containsKey(args[i + 1])) { - channel = settings.releaseChannels.getOrDefault(args[i + 1], channel); - } - } - System.out.println("Checking for updates on the \"" + channel.name + "\" channel..."); - UpdateChecker updateThread = new UpdateChecker(settings, channel, new UpdateListener() { - @Override - public void updateError(String message) { - } - @Override - public void updateAvailable(VersionInfo latest) { - try { - headlessCreateSettingsDirectory(); - } catch (FileNotFoundException e) { - throw new Error(e); - } - System.out.println("Downloading Chunky " + latest + ":"); - ConsoleUpdater.update(latest, settings); - } + CommandLine cmd = parseCli(args); - @Override - public void noUpdateAvailable() { - System.out.println("No updates found."); - } - }); - updateThread.start(); - return; - case "--setup": - // Configure launcher settings. - doSetup(settings); - settings.save(); - return; - case "--noRetryJavafx": - retryIfMissingJavafx = false; - // if this is the only option, with "--javaOptions" "" we want the launcher - if (args.length == 3) - forceLauncher = true; - break; - case "--javaOptions": - if (i == args.length - 1) { - System.err.println("--javaOptions must be followed by the options to can chunky with"); - System.exit(1); - } - if (settings.javaOptions.isEmpty()) - settings.javaOptions = args[i + 1]; - else if (!settings.javaOptions.contains(args[i + 1])) - settings.javaOptions = args[i + 1] + " " + settings.javaOptions; - ++i; - break; - case "--checkJvm": - boolean is64Bit = JreUtil.is64BitJvm(); - if (!is64Bit) { - System.err.println("This does not appear to be a 64-bit JVM."); - } - System.exit(is64Bit ? 0 : -1); - case "--dangerouslyDisableLibraryValidation": - System.out.println("Library validation is disabled."); - LauncherSettings.disableLibraryValidation = true; - break; - default: - if (!headlessOptions.isEmpty()) { - headlessOptions += " "; - } - headlessOptions += arg; - break; + if (cmd.hasOption("help")) { + new HelpFormatter() + .printHelp("java -jar ChunkyLauncher.jar", cliOptions()); + return; + } + + if (cmd.hasOption("nolauncher")) { + mode = LaunchMode.GUI; + } + + if (cmd.hasOption("launcher")) { + forceLauncher = true; + } + + if (cmd.hasOption("version")) { + System.out.println("Chunky Launcher v" + LAUNCHER_VERSION); + return; + } + + if (cmd.hasOption("verbose")) { + settings.verboseLauncher = true; + } + + if (cmd.hasOption("console")) { + settings.forceGuiConsole = true; + } + + if (cmd.hasOption("update") || cmd.hasOption("updateAlpha")) { + ReleaseChannel channel; + if (cmd.hasOption("updateAlpha")) { + channel = LauncherSettings.SNAPSHOT_RELEASE_CHANNEL; + } else { + channel = settings.selectedChannel; + + String selected = cmd.getOptionValue("update"); + if (selected != null) { + channel = settings.releaseChannels.getOrDefault(selected, channel); + } + } + + headlessUpdateChunky(settings, channel); + return; + } + + if (cmd.hasOption("setup")) { + doSetup(settings); + settings.save(); + return; + } + + if (cmd.hasOption("noRetryJavafx")) { + retryIfMissingJavafx = false; + // if this is the only option, with "--javaOptions" "" we want the launcher + if (args.length == 3) + forceLauncher = true; + } + + if (cmd.hasOption("javaOptions")) { + String options = cmd.getOptionValue("javaOptions"); + if (settings.javaOptions.isEmpty()) { + settings.javaOptions = options; + } else if (!settings.javaOptions.contains(options)) { + settings.javaOptions = options + " " + settings.javaOptions; + } + } + + if (cmd.hasOption("checkJvm")) { + boolean is64Bit = JreUtil.is64BitJvm(); + if (!is64Bit) { + System.err.println("This does not appear to be a 64-bit JVM."); } + System.exit(is64Bit ? 0 : -1); + } + + if (cmd.hasOption("dangerouslyDisableLibraryValidation")) { + System.out.println("Library validation is disabled."); + LauncherSettings.disableLibraryValidation = true; } + + headlessOptions = String.join(" ", cmd.getArgList()); + if (forceLauncher) { mode = LaunchMode.GUI; } @@ -259,6 +336,8 @@ else if (!settings.javaOptions.contains(args[i + 1])) JavaFxInstaller.launch(settings, args); } e.printStackTrace(System.err); + } catch (ParseException e) { + System.out.println(e.getMessage()); } } @@ -302,6 +381,36 @@ private static void headlessCreateSettingsDirectory() throws FileNotFoundExcepti } } + private static void headlessUpdateChunky(LauncherSettings settings, ReleaseChannel channel) { + System.out.println("Checking for updates on the \"" + channel.name + "\" channel..."); + UpdateChecker updateThread = new UpdateChecker(settings, channel, new UpdateListener() { + @Override + public void updateError(String message) { + } + + @Override + public void updateAvailable(VersionInfo latest) { + try { + headlessCreateSettingsDirectory(); + } catch (FileNotFoundException e) { + throw new Error(e); + } + System.out.println("Downloading Chunky " + latest + ":"); + ConsoleUpdater.update(latest, settings); + } + + @Override + public void noUpdateAvailable() { + System.out.println("No updates found."); + } + }); + updateThread.start(); + try { + updateThread.join(); + } catch (InterruptedException ignored) { + } + } + interface ShowLauncher { boolean showLauncher(); } @@ -445,4 +554,13 @@ public static String prettyPrintSize(int size) { return String.format("%.1f %s", fSize, unit); } } + + /** + * Print a launch error message to the console. + * Prints the command that was used to try to launch Chunky. + */ + protected static void launchFailure(String command) { + System.out.println("Failed to launch Chunky. Command used:"); + System.out.println(command); + } } diff --git a/launcher/test/se/llbit/chunky/launcher/ChunkyLauncherCliParseTest.java b/launcher/test/se/llbit/chunky/launcher/ChunkyLauncherCliParseTest.java new file mode 100644 index 000000000..1040a00af --- /dev/null +++ b/launcher/test/se/llbit/chunky/launcher/ChunkyLauncherCliParseTest.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2024 Chunky contributors + * + * This file is part of Chunky. + * + * Chunky is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Chunky is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with Chunky. If not, see . + */ + +package se.llbit.chunky.launcher; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.ParseException; +import org.junit.Test; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +public class ChunkyLauncherCliParseTest { + @Test + public void testAdditionalOptions() throws ParseException { + CommandLine cmd = ChunkyLauncher.parseCli(new String[] { "--", "--help", "--help1" }); + assertThat(cmd.getOptions().length).isEqualTo(0); + assertThat(cmd.getArgs().length).isEqualTo(2); + assertThat(cmd.getArgs()[0]).isEqualTo("--help"); + assertThat(cmd.getArgs()[1]).isEqualTo("--help1"); + } + + @Test + public void testOptions() throws ParseException { + CommandLine cmd; + + // Check --help + cmd = ChunkyLauncher.parseCli(new String[] { "--help" }); + assertThat(cmd.getOptions().length).isEqualTo(1); + assertThat(cmd.hasOption("help")).isTrue(); + + // Check -h + cmd = ChunkyLauncher.parseCli(new String[] { "-h" }); + assertThat(cmd.getOptions().length).isEqualTo(1); + assertThat(cmd.hasOption("help")).isTrue(); + + // Check --nolauncher + cmd = ChunkyLauncher.parseCli(new String[] { "--nolauncher" }); + assertThat(cmd.getOptions().length).isEqualTo(1); + assertThat(cmd.hasOption("nolauncher")).isTrue(); + + // Check --launcher + cmd = ChunkyLauncher.parseCli(new String[] { "--launcher" }); + assertThat(cmd.getOptions().length).isEqualTo(1); + assertThat(cmd.hasOption("launcher")).isTrue(); + + // Check --version + cmd = ChunkyLauncher.parseCli(new String[] { "--version" }); + assertThat(cmd.getOptions().length).isEqualTo(1); + assertThat(cmd.hasOption("version")).isTrue(); + + // Check --verbose + cmd = ChunkyLauncher.parseCli(new String[] { "--verbose" }); + assertThat(cmd.getOptions().length).isEqualTo(1); + assertThat(cmd.hasOption("verbose")).isTrue(); + + // Check --console + cmd = ChunkyLauncher.parseCli(new String[] { "--console" }); + assertThat(cmd.getOptions().length).isEqualTo(1); + assertThat(cmd.hasOption("console")).isTrue(); + + // Check --setup + cmd = ChunkyLauncher.parseCli(new String[] { "--setup" }); + assertThat(cmd.getOptions().length).isEqualTo(1); + assertThat(cmd.hasOption("setup")).isTrue(); + + // Check --noRetryJavafx + cmd = ChunkyLauncher.parseCli(new String[] { "--noRetryJavafx" }); + assertThat(cmd.getOptions().length).isEqualTo(1); + assertThat(cmd.hasOption("noRetryJavafx")).isTrue(); + + // Check --checkJvm + cmd = ChunkyLauncher.parseCli(new String[] { "--checkJvm" }); + assertThat(cmd.getOptions().length).isEqualTo(1); + assertThat(cmd.hasOption("checkJvm")).isTrue(); + + // Check --dangerouslyDisableLibraryValidation + cmd = ChunkyLauncher.parseCli(new String[] { "--dangerouslyDisableLibraryValidation" }); + assertThat(cmd.getOptions().length).isEqualTo(1); + assertThat(cmd.hasOption("dangerouslyDisableLibraryValidation")).isTrue(); + } + + @Test + public void testUpdateGroup() throws ParseException { + CommandLine cmd; + + // Check --update + cmd = ChunkyLauncher.parseCli(new String[] { "--update" }); + assertThat(cmd.getOptions().length).isEqualTo(1); + assertThat(cmd.hasOption("update")).isTrue(); + + // Check --updateAlpha + cmd = ChunkyLauncher.parseCli(new String[] { "--updateAlpha" }); + assertThat(cmd.getOptions().length).isEqualTo(1); + assertThat(cmd.hasOption("updateAlpha")).isTrue(); + + // Check both --update and --updateAlpha is invalid + assertThrows(ParseException.class, () -> + ChunkyLauncher.parseCli(new String[] { "--update", "--updateAlpha" })); + } +} From 5895d07db1322661ea426c108a01938cd82997fc Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 7 Jan 2024 01:35:26 -0800 Subject: [PATCH 3/8] Fix argument for `--javaOptions` --- launcher/src/se/llbit/chunky/launcher/ChunkyLauncher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/src/se/llbit/chunky/launcher/ChunkyLauncher.java b/launcher/src/se/llbit/chunky/launcher/ChunkyLauncher.java index e4d176456..86f4c86e3 100644 --- a/launcher/src/se/llbit/chunky/launcher/ChunkyLauncher.java +++ b/launcher/src/se/llbit/chunky/launcher/ChunkyLauncher.java @@ -119,8 +119,8 @@ public static Options cliOptions() { options.addOption(Option.builder() .longOpt("javaOptions") + .hasArg(true) .argName("options") - .optionalArg(false) .desc("Add a Java option when launching Chunky") .build() ); From 3da59989c71845c547bcbaa2aa6c73d29a36fc48 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 7 Jan 2024 21:41:56 -0800 Subject: [PATCH 4/8] Remove `stopAtNonOption`. Remove `--updateAlpha` and `--nolauncher` --- .../llbit/chunky/launcher/ChunkyLauncher.java | 55 ++++++------------- .../launcher/ChunkyLauncherCliParseTest.java | 31 +++-------- 2 files changed, 26 insertions(+), 60 deletions(-) diff --git a/launcher/src/se/llbit/chunky/launcher/ChunkyLauncher.java b/launcher/src/se/llbit/chunky/launcher/ChunkyLauncher.java index 86f4c86e3..bb69c41a2 100644 --- a/launcher/src/se/llbit/chunky/launcher/ChunkyLauncher.java +++ b/launcher/src/se/llbit/chunky/launcher/ChunkyLauncher.java @@ -62,11 +62,6 @@ public static Options cliOptions() { .build() ); - options.addOption(Option.builder() - .longOpt("nolauncher") - .build() - ); - options.addOption(Option.builder() .longOpt("launcher") .desc("Forces the launcher GUI to be shown") @@ -91,29 +86,17 @@ public static Options cliOptions() { .build() ); - options.addOptionGroup(new OptionGroup() - .addOption(Option.builder() - .longOpt("update") - .argName("release channel") - .optionalArg(true) - .desc("Update Chunky to the latest release") - .build() - ) - .addOption(Option.builder() - .longOpt("updateAlpha") - .desc("Update Chunky to the latest snapshot release. Equivalent to `--update snapshot`. (legacy)") - .build() - ) - ); - options.addOption(Option.builder() - .longOpt("setup") - .desc("Runs the interactive command-line launcher setup") + .longOpt("update") + .argName("release channel") + .optionalArg(true) + .desc("Update Chunky to the latest release") .build() ); options.addOption(Option.builder() - .longOpt("noRetryJavafx") + .longOpt("setup") + .desc("Runs the interactive command-line launcher setup") .build() ); @@ -125,6 +108,11 @@ public static Options cliOptions() { .build() ); + options.addOption(Option.builder() + .longOpt("noRetryJavafx") + .build() + ); + options.addOption(Option.builder() .longOpt("checkJvm") .desc("Check if JVM version is 64-bit") @@ -143,7 +131,7 @@ public static Options cliOptions() { public static CommandLine parseCli(String[] args) throws ParseException { Options options = cliOptions(); return new DefaultParser() - .parse(options, args, true); + .parse(options, args); } public static void main(String[] args) throws FileNotFoundException { @@ -179,10 +167,6 @@ public static void main(String[] args) throws FileNotFoundException { return; } - if (cmd.hasOption("nolauncher")) { - mode = LaunchMode.GUI; - } - if (cmd.hasOption("launcher")) { forceLauncher = true; } @@ -200,17 +184,12 @@ public static void main(String[] args) throws FileNotFoundException { settings.forceGuiConsole = true; } - if (cmd.hasOption("update") || cmd.hasOption("updateAlpha")) { - ReleaseChannel channel; - if (cmd.hasOption("updateAlpha")) { - channel = LauncherSettings.SNAPSHOT_RELEASE_CHANNEL; - } else { - channel = settings.selectedChannel; + if (cmd.hasOption("update")) { + ReleaseChannel channel = settings.selectedChannel; - String selected = cmd.getOptionValue("update"); - if (selected != null) { - channel = settings.releaseChannels.getOrDefault(selected, channel); - } + String selected = cmd.getOptionValue("update"); + if (selected != null) { + channel = settings.releaseChannels.getOrDefault(selected, channel); } headlessUpdateChunky(settings, channel); diff --git a/launcher/test/se/llbit/chunky/launcher/ChunkyLauncherCliParseTest.java b/launcher/test/se/llbit/chunky/launcher/ChunkyLauncherCliParseTest.java index 1040a00af..6053c7cb1 100644 --- a/launcher/test/se/llbit/chunky/launcher/ChunkyLauncherCliParseTest.java +++ b/launcher/test/se/llbit/chunky/launcher/ChunkyLauncherCliParseTest.java @@ -49,11 +49,6 @@ public void testOptions() throws ParseException { assertThat(cmd.getOptions().length).isEqualTo(1); assertThat(cmd.hasOption("help")).isTrue(); - // Check --nolauncher - cmd = ChunkyLauncher.parseCli(new String[] { "--nolauncher" }); - assertThat(cmd.getOptions().length).isEqualTo(1); - assertThat(cmd.hasOption("nolauncher")).isTrue(); - // Check --launcher cmd = ChunkyLauncher.parseCli(new String[] { "--launcher" }); assertThat(cmd.getOptions().length).isEqualTo(1); @@ -79,6 +74,11 @@ public void testOptions() throws ParseException { assertThat(cmd.getOptions().length).isEqualTo(1); assertThat(cmd.hasOption("setup")).isTrue(); + // Check --update + cmd = ChunkyLauncher.parseCli(new String[] { "--update" }); + assertThat(cmd.getOptions().length).isEqualTo(1); + assertThat(cmd.hasOption("update")).isTrue(); + // Check --noRetryJavafx cmd = ChunkyLauncher.parseCli(new String[] { "--noRetryJavafx" }); assertThat(cmd.getOptions().length).isEqualTo(1); @@ -93,24 +93,11 @@ public void testOptions() throws ParseException { cmd = ChunkyLauncher.parseCli(new String[] { "--dangerouslyDisableLibraryValidation" }); assertThat(cmd.getOptions().length).isEqualTo(1); assertThat(cmd.hasOption("dangerouslyDisableLibraryValidation")).isTrue(); - } - @Test - public void testUpdateGroup() throws ParseException { - CommandLine cmd; - - // Check --update - cmd = ChunkyLauncher.parseCli(new String[] { "--update" }); + // Check --javaOptions + cmd = ChunkyLauncher.parseCli(new String[] { "--javaOptions", "test" }); assertThat(cmd.getOptions().length).isEqualTo(1); - assertThat(cmd.hasOption("update")).isTrue(); - - // Check --updateAlpha - cmd = ChunkyLauncher.parseCli(new String[] { "--updateAlpha" }); - assertThat(cmd.getOptions().length).isEqualTo(1); - assertThat(cmd.hasOption("updateAlpha")).isTrue(); - - // Check both --update and --updateAlpha is invalid - assertThrows(ParseException.class, () -> - ChunkyLauncher.parseCli(new String[] { "--update", "--updateAlpha" })); + assertThat(cmd.hasOption("javaOptions")).isTrue(); + assertThat(cmd.getOptionValue("javaOptions")).isEqualTo("test"); } } From 3d45c2c490f3f88e88065cf19e671e43c56e763f Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 7 Jan 2024 22:38:20 -0800 Subject: [PATCH 5/8] Add apache commons CLI to tools and libraries. Make help dialog better. Centralize copyright lines and CLI utilities. --- .../ui/controller/CreditsController.java | 15 ++++++- .../se/llbit/chunky/ui/dialogs/Credits.fxml | 16 +++++++- .../llbit/chunky/launcher/ChunkyLauncher.java | 38 +++++++++++------ .../launcher/ChunkyLauncherCliParseTest.java | 20 ++++----- lib/src/se/llbit/chunky/HelpCopyright.java | 30 ++++++++++++++ lib/src/se/llbit/chunky/cli/CliUtil.java | 41 +++++++++++++++++++ 6 files changed, 136 insertions(+), 24 deletions(-) create mode 100644 lib/src/se/llbit/chunky/HelpCopyright.java create mode 100644 lib/src/se/llbit/chunky/cli/CliUtil.java diff --git a/chunky/src/java/se/llbit/chunky/ui/controller/CreditsController.java b/chunky/src/java/se/llbit/chunky/ui/controller/CreditsController.java index 6b38a46fd..d491ed296 100644 --- a/chunky/src/java/se/llbit/chunky/ui/controller/CreditsController.java +++ b/chunky/src/java/se/llbit/chunky/ui/controller/CreditsController.java @@ -40,6 +40,7 @@ import javafx.scene.layout.VBox; import javafx.scene.text.Font; import javafx.stage.Stage; +import se.llbit.chunky.HelpCopyright; import se.llbit.chunky.main.Chunky; import se.llbit.chunky.plugin.PluginApi; import se.llbit.chunky.ui.ChunkyFx; @@ -49,10 +50,11 @@ import se.llbit.util.Pair; public class CreditsController implements Initializable { - @FXML private Label version; @FXML + public Label copyrightLine; + @FXML private Hyperlink gplv3; @FXML private Hyperlink markdown; @@ -83,6 +85,10 @@ public class CreditsController implements Initializable { @FXML private Hyperlink lz4JavaLicense; @FXML + private Hyperlink apacheCli; + @FXML + private Hyperlink apacheCliLicense; + @FXML private VBox pluginBox; @FXML private ImageView logoImage; @@ -140,6 +146,8 @@ public void initialize(URL location, ResourceBundle resources) { version.setText(Chunky.getMainWindowTitle()); + copyrightLine.setText(HelpCopyright.COPYRIGHT_LINE); + gplv3.setOnAction( e -> launchAndReset(gplv3, "https://github.com/chunky-dev/chunky/blob/master/LICENSE") ); @@ -189,6 +197,11 @@ public void initialize(URL location, ResourceBundle resources) { lz4JavaLicense.setBorder(Border.EMPTY); lz4JavaLicense.setOnAction(e -> launchAndReset(lz4JavaLicense, "https://github.com/lz4/lz4-java/blob/master/LICENSE.txt")); + apacheCli.setBorder(Border.EMPTY); + apacheCli.setOnAction(e -> launchAndReset(apacheCli, "https://commons.apache.org/proper/commons-cli/")); + apacheCliLicense.setBorder(Border.EMPTY); + apacheCliLicense.setOnAction(e -> launchAndReset(apacheCliLicense, "http://www.apache.org/licenses/LICENSE-2.0")); + if (!plugins.isEmpty()) { plugins.forEach((key, item) -> pluginBox.getChildren().addAll(buildBox(item))); } else { diff --git a/chunky/src/res/se/llbit/chunky/ui/dialogs/Credits.fxml b/chunky/src/res/se/llbit/chunky/ui/dialogs/Credits.fxml index bbc38015e..e3227eba3 100644 --- a/chunky/src/res/se/llbit/chunky/ui/dialogs/Credits.fxml +++ b/chunky/src/res/se/llbit/chunky/ui/dialogs/Credits.fxml @@ -31,7 +31,7 @@ -