From fe50b6b85a8f4dfff2a6a7a48673f073368af096 Mon Sep 17 00:00:00 2001 From: Jonas Tobias Hopusch Date: Sat, 12 Mar 2022 01:58:05 +0100 Subject: [PATCH 1/5] Add commons-cli dependency to gradle project configuration --- build.gradle.kts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index 281b392..644ea60 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,6 +12,10 @@ repositories { mavenCentral() } +dependencies { + implementation(group="org.apache", name="commons-cli", version="1.5.0") +} + fun versionBanner(): String { val os = ByteArrayOutputStream() val devNull = OutputStream.nullOutputStream() From 1a2596337129ebd70648900c52193cf5b646ac42 Mon Sep 17 00:00:00 2001 From: Jonas Tobias Hopusch Date: Sat, 12 Mar 2022 03:12:58 +0100 Subject: [PATCH 2/5] Correct incorrect group for commons-cli dependency --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 644ea60..f989cfc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,7 @@ repositories { } dependencies { - implementation(group="org.apache", name="commons-cli", version="1.5.0") + implementation(group="commons-cli", name="commons-cli", version="1.5.0") } fun versionBanner(): String { From ddf8047ebd92b009b4990023b2f2b6b2f53bb6c0 Mon Sep 17 00:00:00 2001 From: Jonas Tobias Hopusch Date: Sat, 12 Mar 2022 03:13:30 +0100 Subject: [PATCH 3/5] Disable modularization The modularization file was heavily interfering with the addition and usage of the commons-cli dependency which does not have a static module name. Since the benefits it gave this very small application were miniscule, I have decided to delete / comment out all relevant configuration --- build.gradle.kts | 6 +++--- src/main/java/module-info.java | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) delete mode 100644 src/main/java/module-info.java diff --git a/build.gradle.kts b/build.gradle.kts index f989cfc..33d7497 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -40,8 +40,8 @@ tasks.jar { attributes( "Implementation-Title" to project.name, "Implementation-Version" to project.version, - "Main-Class" to "de.jotoho.waituntil.Main", - "Main-Module" to "de.jotoho.waituntil.main" + "Main-Class" to "de.jotoho.waituntil.Main" + //"Main-Module" to "de.jotoho.waituntil.main" ) } } @@ -49,5 +49,5 @@ tasks.jar { application { // Define the main class for the application. mainClass.set("de.jotoho.waituntil.Main") - mainModule.set("de.jotoho.waituntil.main") + //mainModule.set("de.jotoho.waituntil.main") } diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java deleted file mode 100644 index 72e6d14..0000000 --- a/src/main/java/module-info.java +++ /dev/null @@ -1,2 +0,0 @@ -module de.jotoho.waituntil.main { -} \ No newline at end of file From b53e7a617d88f7ec512f8e7befb2aca300ed48ea Mon Sep 17 00:00:00 2001 From: Jonas Tobias Hopusch Date: Sat, 12 Mar 2022 03:16:00 +0100 Subject: [PATCH 4/5] Refactor main method to use commons-cli to parse arguments --- .../java/de/jotoho/waituntil/AppOptions.java | 23 ++++ src/main/java/de/jotoho/waituntil/Main.java | 100 ++++++++++-------- 2 files changed, 79 insertions(+), 44 deletions(-) create mode 100644 src/main/java/de/jotoho/waituntil/AppOptions.java diff --git a/src/main/java/de/jotoho/waituntil/AppOptions.java b/src/main/java/de/jotoho/waituntil/AppOptions.java new file mode 100644 index 0000000..83d9412 --- /dev/null +++ b/src/main/java/de/jotoho/waituntil/AppOptions.java @@ -0,0 +1,23 @@ +package de.jotoho.waituntil; + +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; + +final class AppOptions { + // Disable Instance Creation + private AppOptions() {} + + public final static Option help = + Option.builder().argName("h").longOpt("help").desc("Shows this help " + + "message and exits").build(); + public final static Option version = + Option.builder().argName("v").longOpt("version").desc("Shows version information and exits").build(); + + private final static Options options = new Options() + .addOption(help) + .addOption(version); + + public static Options getOptions() { + return options; + } +} diff --git a/src/main/java/de/jotoho/waituntil/Main.java b/src/main/java/de/jotoho/waituntil/Main.java index c160fdc..3380bb2 100644 --- a/src/main/java/de/jotoho/waituntil/Main.java +++ b/src/main/java/de/jotoho/waituntil/Main.java @@ -18,8 +18,8 @@ package de.jotoho.waituntil; along with this program. If not, see . */ -import java.util.HashSet; -import java.util.Map; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.ParseException; import static de.jotoho.waituntil.GlobalConf.applicationOutputLanguage; @@ -28,53 +28,65 @@ import static de.jotoho.waituntil.GlobalConf.applicationOutputLanguage; // Author: Jonas Tobias Hopusch (@jotoho) public final class Main { - public static void main(final String[] args) { - final var optionDictionary = Map.of("-h", "--help", "-v", "--version"); - final var options = new HashSet(); - final var words = new HashSet(); + private static void printVersionInformation() { + final var thisPackage = Main.class.getPackage(); + final var appVersion = thisPackage.getImplementationVersion() != null ? thisPackage.getImplementationVersion() : "version unknown"; + System.out.println("waituntil " + appVersion); + System.out.println(""" - for (final String arg : args) { - if (arg.startsWith("--")) { - options.add(arg.substring(2)); - } else if (arg.startsWith("-")) { - if (optionDictionary.containsKey(arg)) - options.add(optionDictionary.get(arg).substring(2)); - else - System.err.println("Short-hand '$arg' does not exist. Ignoring!"); - } else { - words.add(arg); - } + This program 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. + + This program 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."""); + } + + private static void printHelpInformation() { + switch (applicationOutputLanguage) { + case GlobalConf.langGerman -> System.out.println("Hilfe kommt noch. (Nicht implementiert)"); + default -> System.out.println("Help is yet to come. (Not implemented)"); } + } - if (options.contains("help")) { - switch (applicationOutputLanguage) { - case GlobalConf.langGerman -> System.out.println("Hilfe kommt noch. (Nicht implementiert)"); - default -> System.out.println("Help is yet to come. (Not implemented)"); - } - } else if (options.contains("version")) { - final var thisPackage = Main.class.getPackage(); - final var appVersion = thisPackage.getImplementationVersion() != null - ? thisPackage.getImplementationVersion() - : "version unknown"; - System.out.println("waituntil " + appVersion); - System.out.println(""" - - This program 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. - - This program 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."""); - } else if (words.size() == 1) { - final var target = TimeCalculator.calculateAndAnnounceTargetTime(words.iterator().next()); - Sleep.waitUntilTimeStamp(target); - } else { - switch (applicationOutputLanguage) { - case GlobalConf.langGerman -> System.err.println("FATAL: Es wurde exact ein nicht-flag Argument erwartet. (" + words.size() + " erhalten)"); - default -> System.err.println("FATAL: Expected one non-flag argument. (Got " + words.size() + ")"); + public static void main(final String[] args) { + try { + final var parsedArguments = + DefaultParser.builder() + .setStripLeadingAndTrailingQuotes(true) + .build() + .parse(AppOptions.getOptions(), args); + + final var userData = parsedArguments.getArgs(); + + if (parsedArguments.hasOption(AppOptions.help)) { + printHelpInformation(); + } else if (parsedArguments.hasOption(AppOptions.version)) { + printVersionInformation(); + } else if (userData.length == 0) { + switch (applicationOutputLanguage) { + case GlobalConf.langGerman -> System.err.println("FATAL: Es wurde exact ein nicht-flag Argument erwartet. (" + userData.length + " erhalten)"); + default -> System.err.println("FATAL: Expected one non-flag argument. (Got " + userData.length + ")"); + } + System.exit(1); + } else if (userData.length > 1) { + switch (applicationOutputLanguage) { + case GlobalConf.langGerman -> System.err.println("FATAL: " + + "Es wurde exact ein nicht-flag Argument erwartet. (" + userData.length + " erhalten)"); + default -> System.err.println("FATAL: Expected one " + + "non-flag argument. (Got " + userData.length + ")"); + } + System.exit(1); + } else { + final var target = + TimeCalculator.calculateAndAnnounceTargetTime(userData[0]); + Sleep.waitUntilTimeStamp(target); } + } catch (final ParseException e) { + System.getLogger("main").log(System.Logger.Level.ERROR, "Parsing " + + "of arguments failed and the program cannot continue.", e); System.exit(1); } } From 1c48b1861fcb40bdb974975ccf16ea854b86fbf9 Mon Sep 17 00:00:00 2001 From: Jonas Tobias Hopusch Date: Sat, 12 Mar 2022 03:23:28 +0100 Subject: [PATCH 5/5] Rewrite some error messages for wrong argument amounts --- src/main/java/de/jotoho/waituntil/Main.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/de/jotoho/waituntil/Main.java b/src/main/java/de/jotoho/waituntil/Main.java index 3380bb2..e558d67 100644 --- a/src/main/java/de/jotoho/waituntil/Main.java +++ b/src/main/java/de/jotoho/waituntil/Main.java @@ -67,16 +67,18 @@ public final class Main { printVersionInformation(); } else if (userData.length == 0) { switch (applicationOutputLanguage) { - case GlobalConf.langGerman -> System.err.println("FATAL: Es wurde exact ein nicht-flag Argument erwartet. (" + userData.length + " erhalten)"); - default -> System.err.println("FATAL: Expected one non-flag argument. (Got " + userData.length + ")"); + case GlobalConf.langGerman -> System.err.println("FATAL: " + + "Es wurde keine Uhrzeit angegeben."); + default -> System.err.println("FATAL: No target time was " + + "provided."); } System.exit(1); } else if (userData.length > 1) { switch (applicationOutputLanguage) { case GlobalConf.langGerman -> System.err.println("FATAL: " + - "Es wurde exact ein nicht-flag Argument erwartet. (" + userData.length + " erhalten)"); - default -> System.err.println("FATAL: Expected one " + - "non-flag argument. (Got " + userData.length + ")"); + "Zu viele Argumente wurden angegeben."); + default -> System.err.println("FATAL: Too many arguments " + + "provided."); } System.exit(1); } else {