From b6df9f63e920527ac5970493d27fd05165d799b8 Mon Sep 17 00:00:00 2001 From: Marcell Perger Date: Wed, 5 Jun 2024 22:23:05 +0100 Subject: [PATCH 01/23] refactor: Start creating MiniCLI --- .../net/marcellperger/mathexpr/cli/CLI.java | 9 ++++ .../cli/minicli/BooleanCLIOption.java | 18 +++++++ .../mathexpr/cli/minicli/CLIOption.java | 33 ++++++++++++ .../mathexpr/cli/minicli/MiniCLI.java | 54 +++++++++++++++++++ .../mathexpr/cli/minicli/StringCLIOption.java | 14 +++++ 5 files changed, 128 insertions(+) create mode 100644 src/main/java/net/marcellperger/mathexpr/cli/CLI.java create mode 100644 src/main/java/net/marcellperger/mathexpr/cli/minicli/BooleanCLIOption.java create mode 100644 src/main/java/net/marcellperger/mathexpr/cli/minicli/CLIOption.java create mode 100644 src/main/java/net/marcellperger/mathexpr/cli/minicli/MiniCLI.java create mode 100644 src/main/java/net/marcellperger/mathexpr/cli/minicli/StringCLIOption.java diff --git a/src/main/java/net/marcellperger/mathexpr/cli/CLI.java b/src/main/java/net/marcellperger/mathexpr/cli/CLI.java new file mode 100644 index 0000000..6cc880c --- /dev/null +++ b/src/main/java/net/marcellperger/mathexpr/cli/CLI.java @@ -0,0 +1,9 @@ +package net.marcellperger.mathexpr.cli; + +import java.util.Arrays; + +public class CLI { + public static void main(String[] args) { + System.out.println("args = " + Arrays.stream(args).map(s -> "`" + s + "`").toList()); + } +} diff --git a/src/main/java/net/marcellperger/mathexpr/cli/minicli/BooleanCLIOption.java b/src/main/java/net/marcellperger/mathexpr/cli/minicli/BooleanCLIOption.java new file mode 100644 index 0000000..f1e11af --- /dev/null +++ b/src/main/java/net/marcellperger/mathexpr/cli/minicli/BooleanCLIOption.java @@ -0,0 +1,18 @@ +package net.marcellperger.mathexpr.cli.minicli; + +import java.util.List; + +public class BooleanCLIOption extends CLIOption { + public BooleanCLIOption(List optionNames) { + super(Boolean.class, optionNames); + } + + @Override + public void setValueFromString(String s) { + setValue(switch (s.strip().toLowerCase()) { + case "0", "no", "false" -> false; + case "1", "yes", "true" -> true; + case String s2 -> throw new IllegalArgumentException("Bad boolean value '" + s2 + "'"); // TODO special CLIParseException + }); + } +} diff --git a/src/main/java/net/marcellperger/mathexpr/cli/minicli/CLIOption.java b/src/main/java/net/marcellperger/mathexpr/cli/minicli/CLIOption.java new file mode 100644 index 0000000..94101b2 --- /dev/null +++ b/src/main/java/net/marcellperger/mathexpr/cli/minicli/CLIOption.java @@ -0,0 +1,33 @@ +package net.marcellperger.mathexpr.cli.minicli; + +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public abstract class CLIOption { + List names; + Class type; + @Nullable T value; + + public CLIOption(Class valueType, List optionNames) { + names = optionNames; + type = valueType; + } + + public List getNames() { + return names; + } + + public @Nullable T getValue() { + return value; + } + public void setValue(@Nullable T value) { + this.value = value; + } + + public abstract void setValueFromString(String s); + + public void reset() { + value = null; + } +} diff --git a/src/main/java/net/marcellperger/mathexpr/cli/minicli/MiniCLI.java b/src/main/java/net/marcellperger/mathexpr/cli/minicli/MiniCLI.java new file mode 100644 index 0000000..7438686 --- /dev/null +++ b/src/main/java/net/marcellperger/mathexpr/cli/minicli/MiniCLI.java @@ -0,0 +1,54 @@ +package net.marcellperger.mathexpr.cli.minicli; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class MiniCLI { + Map> options = new HashMap<>(); + List positionalArgs = new ArrayList<>(); + + public MiniCLI() { + + } + + @Contract("_ -> new") + public CLIOption addStringOption(String @NotNull ... names) { + // First validate all of them so we don't mutate unless all are valid + for(String name : names) { + if (!name.startsWith("-")) throw new IllegalArgumentException("Option name must start with '-'"); + if (options.containsKey(name)) { + throw new IllegalStateException("Argument '%s' has already been registered".formatted(name)); + } + } + CLIOption opt = new StringCLIOption(List.of(names)); + for(String name : names) { + options.put(name, opt); + } + return opt; + } + + + @Contract("_ -> this") + public MiniCLI parseArgs(String[] args) { + return parseArgs(List.of(args)); + } + @Contract("_ -> this") + public MiniCLI parseArgs(List args) { + + return this; + } + private enum ArgType { + NORMAL, SINGLE, DOUBLE; + public static ArgType fromArg(String arg) { + if(arg.startsWith("--")) return DOUBLE; + if(arg.startsWith("-")) return SINGLE; + return NORMAL; + } + } +} diff --git a/src/main/java/net/marcellperger/mathexpr/cli/minicli/StringCLIOption.java b/src/main/java/net/marcellperger/mathexpr/cli/minicli/StringCLIOption.java new file mode 100644 index 0000000..5ce4f0f --- /dev/null +++ b/src/main/java/net/marcellperger/mathexpr/cli/minicli/StringCLIOption.java @@ -0,0 +1,14 @@ +package net.marcellperger.mathexpr.cli.minicli; + +import java.util.List; + +public class StringCLIOption extends CLIOption { + public StringCLIOption(List keys) { + super(String.class, keys); + } + + @Override + public void setValueFromString(String s) { + setValue(s); + } +} From 148e3ceec03b132e8f6e775f76559404bed08453 Mon Sep 17 00:00:00 2001 From: Marcell Perger Date: Thu, 6 Jun 2024 22:36:24 +0100 Subject: [PATCH 02/23] feat: Do most (not all yet) of the core CLI parsing stuff [WIP] --- .idea/inspectionProfiles/Project_Default.xml | 3 + .../cli/minicli/BooleanCLIOption.java | 21 ++++-- .../mathexpr/cli/minicli/CLIOption.java | 20 +++++- .../cli/minicli/CLIParseException.java | 18 +++++ .../mathexpr/cli/minicli/MiniCLI.java | 70 ++++++++++++++++++- .../mathexpr/cli/minicli/OptionValueMode.java | 31 ++++++++ .../mathexpr/cli/minicli/StringCLIOption.java | 4 +- 7 files changed, 160 insertions(+), 7 deletions(-) create mode 100644 src/main/java/net/marcellperger/mathexpr/cli/minicli/CLIParseException.java create mode 100644 src/main/java/net/marcellperger/mathexpr/cli/minicli/OptionValueMode.java diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index 637f013..c6332e8 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -3,6 +3,9 @@