From 488c37fde2a77d72415539483af8cc12f59fecd8 Mon Sep 17 00:00:00 2001 From: darvil82 Date: Tue, 26 Dec 2023 18:07:27 +0100 Subject: [PATCH 01/18] add: wasUsed method to ParsedArguments --- src/main/java/lanat/ParsedArguments.java | 10 ++++++ .../exampleTests/CommandTemplateExample.java | 11 ++++++- .../lanat/test/exampleTests/ExampleTest.java | 31 +++---------------- src/test/java/module-info.java | 2 +- 4 files changed, 26 insertions(+), 28 deletions(-) diff --git a/src/main/java/lanat/ParsedArguments.java b/src/main/java/lanat/ParsedArguments.java index 68e51b3e..ca7f9289 100644 --- a/src/main/java/lanat/ParsedArguments.java +++ b/src/main/java/lanat/ParsedArguments.java @@ -17,6 +17,7 @@ public class ParsedArguments { private final @NotNull HashMap<@NotNull Argument, @Nullable Object> parsedArgs; private final @NotNull Command cmd; + private final boolean wasUsed; private final @NotNull List<@NotNull ParsedArguments> subParsedArguments; ParsedArguments( @@ -27,9 +28,18 @@ public class ParsedArguments { { this.parsedArgs = parsedArgs; this.cmd = cmd; + this.wasUsed = cmd.getTokenizer().hasFinished(); this.subParsedArguments = subParsedArguments; } + public boolean wasUsed() { + return this.wasUsed; + } + + public @NotNull Command getCommand() { + return this.cmd; + } + /** * Returns the parsed value of the argument with the given name. * @param arg The argument to get the value of diff --git a/src/test/java/lanat/test/exampleTests/CommandTemplateExample.java b/src/test/java/lanat/test/exampleTests/CommandTemplateExample.java index 980f6dc5..3e1d5fd0 100644 --- a/src/test/java/lanat/test/exampleTests/CommandTemplateExample.java +++ b/src/test/java/lanat/test/exampleTests/CommandTemplateExample.java @@ -60,6 +60,7 @@ protected boolean checkFile(@NotNull File file) { @InitDef public static void afterInit(@NotNull Command cmd) { + cmd.setOnOkCallback(p -> System.out.println("ok " + cmd.getName())); cmd.addGroup(new ArgumentGroup("test-group") {{ this.setRestricted(true); this.addArgument(cmd.getArgument("string")); @@ -75,13 +76,21 @@ public MySubCommand() {} @Argument.Define(argType = CounterArgumentType.class, description = "This is a counter", names = "c") public int counter = 0; + @InitDef + public static void afterInit(@NotNull Command cmd) { + cmd.setOnOkCallback(p -> System.out.println("ok " + cmd.getName())); + } + @CommandAccessor public AnotherSubCommand anotherSubCommand; @Command.Define(names = "another-sub-command", description = "This is a sub-command.") public static class AnotherSubCommand extends CommandTemplate { public AnotherSubCommand() {} - + @InitDef + public static void afterInit(@NotNull Command cmd) { + cmd.setOnOkCallback(p -> System.out.println("ok " + cmd.getName())); + } @Argument.Define(argType = CounterArgumentType.class, description = "This is a counter", names = "c") public int counter = 0; } diff --git a/src/test/java/lanat/test/exampleTests/ExampleTest.java b/src/test/java/lanat/test/exampleTests/ExampleTest.java index f4bf472e..8af006c1 100644 --- a/src/test/java/lanat/test/exampleTests/ExampleTest.java +++ b/src/test/java/lanat/test/exampleTests/ExampleTest.java @@ -18,32 +18,11 @@ public void main() { // TextFormatter.enableSequences = false; // ErrorFormatter.errorFormatterClass = SimpleErrorFormatter.class; - var ap = new ArgumentParser("my-program") {{ - this.setCallbackInvocationOption(CallbacksInvocationOption.NO_ERROR_IN_ARGUMENT); - this.setDescription("This is the description of my program. What do you think about it? Oh by the way, don't forget to use the argument!"); - this.setLicense("Here's some more extra information about my program. Really don't know how to fill this out..."); - this.addHelpArgument(); - this.addArgument(Argument.create(new CounterArgumentType(), "counter", "c").onOk(System.out::println)); - this.addArgument(Argument.create(new Example1Type(), "user", "u").required().positional().withDescription("Specify the user/s to use.")); - this.addArgument(Argument.createOfBoolType("t").onOk(v -> System.out.println("present"))); - this.addArgument(Argument.create(new NumberRangeArgumentType<>(0.0, 15.23), "number").onOk(System.out::println).withDescription("The value that matters the most (not really). Hey, this thing is generated automatically as well!: ")); - this.addArgument(Argument.create(new MultipleStringsArgumentType(Range.from(3).to(5)), "string", "s").onOk(System.out::println).withPrefix(Argument.PrefixChar.PLUS)); - this.addArgument(Argument.create(new IntegerArgumentType(), "test").onOk(System.out::println).allowsUnique()); - - this.addCommand(new Command("sub1", "testing") {{ - this.addArgument(Argument.create(new IntegerArgumentType(), "required").required().positional()); - this.addArgument(Argument.create(new NumberRangeArgumentType<>(0.0, 15.23), "number").onOk(System.out::println)); - this.setDescription("Now this is the description of the subcommand inside the main command."); - this.addCommand(new Command("sub2", "testing") {{ - this.addArgument(Argument.create(new IntegerArgumentType(), "required").required().positional()); - this.addArgument(Argument.create(new NumberRangeArgumentType<>(0.0, 15.23), "number").onOk(System.out::println)); - }}); - }}); - }}; - - ap.parse(CLInput.from("josh ! --number 2 sub1 --required 1 --number 121")) - .printErrors() - .getParsedArguments(); + var result = ArgumentParser.parseFromInto( + CommandTemplateExample.class, + CLInput.from("--number 12 sub-command -ccc"), + opts -> opts.printErrors() + ); } public static class Example1Type extends ArgumentType { diff --git a/src/test/java/module-info.java b/src/test/java/module-info.java index 5cc43e2a..c03609d2 100644 --- a/src/test/java/module-info.java +++ b/src/test/java/module-info.java @@ -6,7 +6,7 @@ requires textFormatter; exports lanat.test to org.junit.platform.commons, lanat; - exports lanat.test.exampleTests to org.junit.platform.commons, lanat; + exports lanat.test.exampleTests to org.junit.platform.commons, lanat, utils; exports lanat.test.units to lanat, org.junit.platform.commons; exports lanat.test.units.commandTemplates to lanat, org.junit.platform.commons, utils; } \ No newline at end of file From 3e1c0bdee18be98b3550f85a4ed2b6e446296187 Mon Sep 17 00:00:00 2001 From: darvil82 Date: Tue, 26 Dec 2023 18:12:16 +0100 Subject: [PATCH 02/18] minor javadoc tweak --- src/main/java/lanat/ArgumentGroup.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/lanat/ArgumentGroup.java b/src/main/java/lanat/ArgumentGroup.java index 8343600d..198cb2ca 100644 --- a/src/main/java/lanat/ArgumentGroup.java +++ b/src/main/java/lanat/ArgumentGroup.java @@ -23,7 +23,7 @@ * arguments that are in different groups. For example, given the following group tree: *
  *            +-----------------------+
- *            |  Group 1 (restricted)  |
+ *            |  Group 1 (restricted) |
  *            |-----------------------|
  *            | Argument 1            |
  *            +-----------------------+
@@ -31,7 +31,7 @@
  *          +---------------------------+
  *          |                           |
  *  +---------------+      +-------------------------+
- *  |    Group 2    |      |   Group 3 (restricted)   |
+ *  |    Group 2    |      |   Group 3 (restricted)  |
  *  |---------------|      |-------------------------|
  *  | Argument 2.1  |      | Argument 3.1            |
  *  | Argument 2.2  |      | Argument 3.2            |

From 11649154559cdac5ce1b2a97555bc0bb2cc19c53 Mon Sep 17 00:00:00 2001
From: darvil82 
Date: Tue, 26 Dec 2023 19:03:20 +0100
Subject: [PATCH 03/18] basic implementation done

---
 src/main/java/lanat/ArgumentParser.java       |  1 +
 src/main/java/lanat/CommandTemplate.java      | 25 ++++++++++++++
 src/main/java/lanat/ParsedArguments.java      | 16 ++++-----
 .../exampleTests/CommandTemplateExample.java  | 33 +++++++++----------
 .../units/commandTemplates/CmdTemplates.java  |  6 +++-
 5 files changed, 53 insertions(+), 28 deletions(-)

diff --git a/src/main/java/lanat/ArgumentParser.java b/src/main/java/lanat/ArgumentParser.java
index fb5a94b0..628b469c 100644
--- a/src/main/java/lanat/ArgumentParser.java
+++ b/src/main/java/lanat/ArgumentParser.java
@@ -413,6 +413,7 @@ private static  T into(
 					AfterParseOptions.into$handleCommandAccessor(instance, commandAccesorField, parsedArgs);
 				});
 
+			instance.afterInstantiation(parsedArgs);
 			return instance;
 		}
 
diff --git a/src/main/java/lanat/CommandTemplate.java b/src/main/java/lanat/CommandTemplate.java
index 39d4a969..4d4b4793 100644
--- a/src/main/java/lanat/CommandTemplate.java
+++ b/src/main/java/lanat/CommandTemplate.java
@@ -100,6 +100,31 @@
  */
 @Command.Define
 public abstract class CommandTemplate {
+	private ParsedArguments parsedArguments;
+
+	/**
+	 *
+	 * @param parsedArguments
+	 */
+	void afterInstantiation(@NotNull ParsedArguments parsedArguments) {
+		this.parsedArguments = parsedArguments;
+		if (this.wasUsed()) this.onValuesReceived();
+	}
+
+	public final @NotNull ParsedArguments getParsedArguments() {
+		return this.parsedArguments;
+	}
+
+	public final @NotNull Command getCommand() {
+		return this.parsedArguments.getCommand();
+	}
+
+	public final boolean wasUsed() {
+		return this.parsedArguments.wasUsed();
+	}
+
+	public void onValuesReceived() {}
+
 	/**
 	 * Annotation used to define an init method for a Command Template.
 	 * @see CommandTemplate#beforeInit(CommandBuildHelper)
diff --git a/src/main/java/lanat/ParsedArguments.java b/src/main/java/lanat/ParsedArguments.java
index ca7f9289..2f80fe9b 100644
--- a/src/main/java/lanat/ParsedArguments.java
+++ b/src/main/java/lanat/ParsedArguments.java
@@ -113,20 +113,16 @@ public boolean wasUsed() {
 			throw new IllegalArgumentException("argument route must not be empty");
 		}
 
-		ParsedArguments matchedParsedArgs;
-
 		if (argRoute.length == 1) {
 			return (Optional)this.get(this.getArgument(argRoute[0]));
-		} else if ((matchedParsedArgs = this.getSubParsedArgs(argRoute[0])) != null) {
-			return matchedParsedArgs.get(Arrays.copyOfRange(argRoute, 1, argRoute.length));
-		} else {
-			throw new CommandNotFoundException(argRoute[0]);
 		}
+
+		return this.getSubParsedArgs(argRoute[0])
+			.get(Arrays.copyOfRange(argRoute, 1, argRoute.length));
 	}
 
 	/**
 	 * Returns the argument in {@link #parsedArgs} with the given name.
-	 *
 	 * @throws ArgumentNotFoundException If no argument with the given name is found
 	 */
 	private @NotNull Argument getArgument(@NotNull String name) {
@@ -143,11 +139,13 @@ public boolean wasUsed() {
 	 * {@code null}.
 	 *
 	 * @param name The name of the sub command
+	 * @throws CommandNotFoundException If no sub command with the given name is found
 	 * @return The sub {@link ParsedArguments} with the given name, or {@code null} if none is found
 	 */
-	public ParsedArguments getSubParsedArgs(@NotNull String name) {
+	public @NotNull ParsedArguments getSubParsedArgs(@NotNull String name) {
 		for (var sub : this.subParsedArguments)
 			if (sub.cmd.hasName(name)) return sub;
-		return null;
+
+		throw new CommandNotFoundException(name);
 	}
 }
\ No newline at end of file
diff --git a/src/test/java/lanat/test/exampleTests/CommandTemplateExample.java b/src/test/java/lanat/test/exampleTests/CommandTemplateExample.java
index 3e1d5fd0..374477d5 100644
--- a/src/test/java/lanat/test/exampleTests/CommandTemplateExample.java
+++ b/src/test/java/lanat/test/exampleTests/CommandTemplateExample.java
@@ -1,9 +1,6 @@
 package lanat.test.exampleTests;
 
-import lanat.Argument;
-import lanat.ArgumentGroup;
-import lanat.Command;
-import lanat.CommandTemplate;
+import lanat.*;
 import lanat.argumentTypes.*;
 import org.jetbrains.annotations.NotNull;
 
@@ -12,8 +9,6 @@
 
 @Command.Define(names = "my-program", description = "This is a test program.")
 public class CommandTemplateExample extends CommandTemplate.Default {
-	public CommandTemplateExample() {}
-
 	@Argument.Define(argType = StringArgumentType.class, description = "This is a string argument.")
 	public Optional string;
 
@@ -60,7 +55,6 @@ protected boolean checkFile(@NotNull File file) {
 
 	@InitDef
 	public static void afterInit(@NotNull Command cmd) {
-		cmd.setOnOkCallback(p -> System.out.println("ok " + cmd.getName()));
 		cmd.addGroup(new ArgumentGroup("test-group") {{
 			this.setRestricted(true);
 			this.addArgument(cmd.getArgument("string"));
@@ -68,31 +62,34 @@ public static void afterInit(@NotNull Command cmd) {
 		}});
 	}
 
+	@Override
+	public void onValuesReceived() {
+		System.out.println("This is the value of number: " + this.number);
+	}
 
 	@Command.Define(names = "sub-command", description = "This is a sub-command.")
 	public static class MySubCommand extends CommandTemplate.Default {
-		public MySubCommand() {}
 
 		@Argument.Define(argType = CounterArgumentType.class, description = "This is a counter", names = "c")
 		public int counter = 0;
 
-		@InitDef
-		public static void afterInit(@NotNull Command cmd) {
-			cmd.setOnOkCallback(p -> System.out.println("ok " + cmd.getName()));
-		}
-
 		@CommandAccessor
 		public AnotherSubCommand anotherSubCommand;
 
+		@Override
+		public void onValuesReceived() {
+			System.out.println("This is the value of counter: " + this.counter);
+		}
+
 		@Command.Define(names = "another-sub-command", description = "This is a sub-command.")
 		public static class AnotherSubCommand extends CommandTemplate {
-			public AnotherSubCommand() {}
-			@InitDef
-			public static void afterInit(@NotNull Command cmd) {
-				cmd.setOnOkCallback(p -> System.out.println("ok " + cmd.getName()));
-			}
 			@Argument.Define(argType = CounterArgumentType.class, description = "This is a counter", names = "c")
 			public int counter = 0;
+
+			@Override
+			public void onValuesReceived() {
+				System.out.println("This is the value of counter: " + this.counter);
+			}
 		}
 	}
 }
\ No newline at end of file
diff --git a/src/test/java/lanat/test/units/commandTemplates/CmdTemplates.java b/src/test/java/lanat/test/units/commandTemplates/CmdTemplates.java
index aa4d2578..c73ed6b2 100644
--- a/src/test/java/lanat/test/units/commandTemplates/CmdTemplates.java
+++ b/src/test/java/lanat/test/units/commandTemplates/CmdTemplates.java
@@ -3,10 +3,12 @@
 import lanat.Argument;
 import lanat.Command;
 import lanat.CommandTemplate;
+import lanat.ParsedArguments;
 import lanat.argumentTypes.BooleanArgumentType;
 import lanat.argumentTypes.FloatArgumentType;
 import lanat.argumentTypes.IntegerArgumentType;
 import lanat.argumentTypes.StringArgumentType;
+import org.jetbrains.annotations.NotNull;
 
 import java.util.Optional;
 
@@ -29,6 +31,7 @@ public static class CmdTemplate1 extends CommandTemplate {
 		@CommandAccessor
 		public CmdTemplate1_1 cmd2;
 
+
 		@Command.Define(names = "cmd1-1")
 		public static class CmdTemplate1_1 extends CommandTemplate {
 			@Argument.Define(argType = FloatArgumentType.class)
@@ -42,7 +45,7 @@ public static class CmdTemplate1_1 extends CommandTemplate {
 	@Command.Define(names = "cmd2")
 	public static class CmdTemplate2 extends CommandTemplate {
 		@Command.Define
-		public static class CmdTemplate2_1 extends CommandTemplate { }
+		public static class CmdTemplate2_1 extends CommandTemplate {}
 	}
 
 	@Command.Define
@@ -53,6 +56,7 @@ public static class CmdTemplate3 extends CommandTemplate {
 		@CommandAccessor
 		public CmdTemplate3_1 cmd2;
 
+
 		@Command.Define(names = "cmd3-1")
 		public static class CmdTemplate3_1 extends CommandTemplate {
 			@Argument.Define(argType = IntegerArgumentType.class, positional = true)

From 542da5924ad62fc0a781ec87eebb9ecbec19e1f5 Mon Sep 17 00:00:00 2001
From: darvil82 
Date: Wed, 27 Dec 2023 02:36:42 +0100
Subject: [PATCH 04/18] add javadocs

---
 src/main/java/lanat/CommandTemplate.java | 33 +++++++++++++++++++++---
 src/main/java/lanat/ParsedArguments.java | 11 +++++++-
 2 files changed, 39 insertions(+), 5 deletions(-)

diff --git a/src/main/java/lanat/CommandTemplate.java b/src/main/java/lanat/CommandTemplate.java
index 4d4b4793..e1d6e629 100644
--- a/src/main/java/lanat/CommandTemplate.java
+++ b/src/main/java/lanat/CommandTemplate.java
@@ -100,31 +100,56 @@
  */
 @Command.Define
 public abstract class CommandTemplate {
+	/**  */
 	private ParsedArguments parsedArguments;
 
 	/**
-	 *
-	 * @param parsedArguments
+	 * Called right after the Command Template is instantiated by the Argument Parser.
+	 * Sets the {@link #parsedArguments} field and calls {@link #onValuesReceived()} if the command was used.
+	 * @param parsedArguments The parsed arguments of the command.
 	 */
 	void afterInstantiation(@NotNull ParsedArguments parsedArguments) {
 		this.parsedArguments = parsedArguments;
 		if (this.wasUsed()) this.onValuesReceived();
 	}
 
+	/**
+	 * Returns the {@link ParsedArguments} instance used by this Command Template. This instance is the one that was
+	 * used to initialize this Command Template.
+	 * @return The {@link ParsedArguments} instance used by this Command Template.
+	 */
 	public final @NotNull ParsedArguments getParsedArguments() {
+		if (this.parsedArguments == null)
+			throw new IllegalStateException("Command Template was not properly initialized by the Argument Parser.");
 		return this.parsedArguments;
 	}
 
+	/**
+	 * Returns the {@link Command} instance used by this Command Template. This instance is the one that was
+	 * used to initialize this Command Template.
+	 * @return The {@link Command} instance used by this Command Template.
+	 */
 	public final @NotNull Command getCommand() {
-		return this.parsedArguments.getCommand();
+		return this.getParsedArguments().getCommand();
 	}
 
+	/**
+	 * Returns {@code true} if the Command of this Template was used in the command line.
+	 * @return {@code true} if the Command of this Template was used in the command line, {@code false} otherwise.
+	 */
 	public final boolean wasUsed() {
-		return this.parsedArguments.wasUsed();
+		return this.getParsedArguments().wasUsed();
 	}
 
+	/**
+	 * Called when the Command of this Template is used in the command line.
+	 * This method is called after the parsed values are set.
+	 * 

+ * This method may be overridden to perform actions when the command is used. + */ public void onValuesReceived() {} + /** * Annotation used to define an init method for a Command Template. * @see CommandTemplate#beforeInit(CommandBuildHelper) diff --git a/src/main/java/lanat/ParsedArguments.java b/src/main/java/lanat/ParsedArguments.java index 2f80fe9b..6267c826 100644 --- a/src/main/java/lanat/ParsedArguments.java +++ b/src/main/java/lanat/ParsedArguments.java @@ -32,10 +32,19 @@ public class ParsedArguments { this.subParsedArguments = subParsedArguments; } + /** + * Returns {@code true} if the command was used, {@code false} otherwise. + * @return {@code true} if the command was used, {@code false} otherwise + */ public boolean wasUsed() { return this.wasUsed; } + /** + * Returns the {@link Command} that this {@link ParsedArguments} object belongs to. This is the Command + * that was used to parse the arguments. + * @return The {@link Command} that this {@link ParsedArguments} object belongs to + */ public @NotNull Command getCommand() { return this.cmd; } @@ -140,7 +149,7 @@ public boolean wasUsed() { * * @param name The name of the sub command * @throws CommandNotFoundException If no sub command with the given name is found - * @return The sub {@link ParsedArguments} with the given name, or {@code null} if none is found + * @return The sub {@link ParsedArguments} with the given name */ public @NotNull ParsedArguments getSubParsedArgs(@NotNull String name) { for (var sub : this.subParsedArguments) From d61879f3d7cfa0c297b38caa62cc8a12ff1ce2b9 Mon Sep 17 00:00:00 2001 From: darvil82 Date: Wed, 27 Dec 2023 02:54:31 +0100 Subject: [PATCH 05/18] add missing javadocs --- src/main/java/lanat/ParsedArguments.java | 12 ++++++++++-- .../test/units/commandTemplates/CmdTemplates.java | 6 +----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/lanat/ParsedArguments.java b/src/main/java/lanat/ParsedArguments.java index 6267c826..9eabbe7c 100644 --- a/src/main/java/lanat/ParsedArguments.java +++ b/src/main/java/lanat/ParsedArguments.java @@ -15,23 +15,31 @@ * Container for all the parsed arguments and their respective values. */ public class ParsedArguments { + /** The parsed arguments. Pairs of each argument and it's respective value */ private final @NotNull HashMap<@NotNull Argument, @Nullable Object> parsedArgs; + + /** The {@link Command} that this {@link ParsedArguments} object belongs to */ private final @NotNull Command cmd; + + /** Whether the command was used or not */ private final boolean wasUsed; + + /** The other inner {@link ParsedArguments}s for the sub-commands */ private final @NotNull List<@NotNull ParsedArguments> subParsedArguments; + ParsedArguments( @NotNull Command cmd, @NotNull HashMap<@NotNull Argument, @Nullable Object> parsedArgs, @NotNull List<@NotNull ParsedArguments> subParsedArguments - ) - { + ) { this.parsedArgs = parsedArgs; this.cmd = cmd; this.wasUsed = cmd.getTokenizer().hasFinished(); this.subParsedArguments = subParsedArguments; } + /** * Returns {@code true} if the command was used, {@code false} otherwise. * @return {@code true} if the command was used, {@code false} otherwise diff --git a/src/test/java/lanat/test/units/commandTemplates/CmdTemplates.java b/src/test/java/lanat/test/units/commandTemplates/CmdTemplates.java index c73ed6b2..aa4d2578 100644 --- a/src/test/java/lanat/test/units/commandTemplates/CmdTemplates.java +++ b/src/test/java/lanat/test/units/commandTemplates/CmdTemplates.java @@ -3,12 +3,10 @@ import lanat.Argument; import lanat.Command; import lanat.CommandTemplate; -import lanat.ParsedArguments; import lanat.argumentTypes.BooleanArgumentType; import lanat.argumentTypes.FloatArgumentType; import lanat.argumentTypes.IntegerArgumentType; import lanat.argumentTypes.StringArgumentType; -import org.jetbrains.annotations.NotNull; import java.util.Optional; @@ -31,7 +29,6 @@ public static class CmdTemplate1 extends CommandTemplate { @CommandAccessor public CmdTemplate1_1 cmd2; - @Command.Define(names = "cmd1-1") public static class CmdTemplate1_1 extends CommandTemplate { @Argument.Define(argType = FloatArgumentType.class) @@ -45,7 +42,7 @@ public static class CmdTemplate1_1 extends CommandTemplate { @Command.Define(names = "cmd2") public static class CmdTemplate2 extends CommandTemplate { @Command.Define - public static class CmdTemplate2_1 extends CommandTemplate {} + public static class CmdTemplate2_1 extends CommandTemplate { } } @Command.Define @@ -56,7 +53,6 @@ public static class CmdTemplate3 extends CommandTemplate { @CommandAccessor public CmdTemplate3_1 cmd2; - @Command.Define(names = "cmd3-1") public static class CmdTemplate3_1 extends CommandTemplate { @Argument.Define(argType = IntegerArgumentType.class, positional = true) From a4e2d6a9bf914731711c6973a47e6be63bfa02b3 Mon Sep 17 00:00:00 2001 From: darvil82 Date: Wed, 27 Dec 2023 03:27:19 +0100 Subject: [PATCH 06/18] add missing javadocs --- src/main/java/lanat/CommandTemplate.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/lanat/CommandTemplate.java b/src/main/java/lanat/CommandTemplate.java index e1d6e629..65e4e1f2 100644 --- a/src/main/java/lanat/CommandTemplate.java +++ b/src/main/java/lanat/CommandTemplate.java @@ -100,12 +100,16 @@ */ @Command.Define public abstract class CommandTemplate { - /** */ + /** The parsed arguments of the command. */ private ParsedArguments parsedArguments; /** * Called right after the Command Template is instantiated by the Argument Parser. * Sets the {@link #parsedArguments} field and calls {@link #onValuesReceived()} if the command was used. + *

+ * The reason this is used instead of a constructor is because we don't want to force inheritors to call + * {@code super()} in their constructors. Also, this method is called first by the innermost Command in + * the hierarchy, and then by the parent Commands. * @param parsedArguments The parsed arguments of the command. */ void afterInstantiation(@NotNull ParsedArguments parsedArguments) { From 71945e49392bf5ed1ee3d23ca07af218a52a8ecf Mon Sep 17 00:00:00 2001 From: darvil82 Date: Thu, 28 Dec 2023 14:39:20 +0100 Subject: [PATCH 07/18] refactor: rename ParsedArguments.java to ParseResult.java --- src/main/java/lanat/Argument.java | 6 +-- src/main/java/lanat/ArgumentParser.java | 38 +++++++-------- src/main/java/lanat/Command.java | 20 ++++---- src/main/java/lanat/CommandTemplate.java | 24 +++++----- ...{ParsedArguments.java => ParseResult.java} | 47 ++++++++++--------- ...rgumentsRoot.java => ParseResultRoot.java} | 12 ++--- src/main/java/lanat/parsing/Parser.java | 16 +++---- src/test/java/lanat/test/TestingParser.java | 8 ++-- .../lanat/test/units/TestParsedValues.java | 4 +- 9 files changed, 87 insertions(+), 88 deletions(-) rename src/main/java/lanat/{ParsedArguments.java => ParseResult.java} (76%) rename src/main/java/lanat/{ParsedArgumentsRoot.java => ParseResultRoot.java} (82%) diff --git a/src/main/java/lanat/Argument.java b/src/main/java/lanat/Argument.java index 9f157e5c..ecb3c406 100644 --- a/src/main/java/lanat/Argument.java +++ b/src/main/java/lanat/Argument.java @@ -32,7 +32,7 @@ *

* An Argument specifies a value that the user can introduce to the command. This value will be parsed by the specified * {@link ArgumentType} each time the Argument is used. Once finished parsing, the value may be retrieved by using - * {@link ParsedArguments#get(String)} on the {@link ParsedArguments} object returned by + * {@link ParseResult#get(String)} on the {@link ParseResult} object returned by * {@link ArgumentParser#parse(CLInput)}. * *

@@ -749,6 +749,4 @@ public void invokeCallbacks() { if (this.onErrorCallback == null) return; this.onErrorCallback.accept(this); } -} - - +} \ No newline at end of file diff --git a/src/main/java/lanat/ArgumentParser.java b/src/main/java/lanat/ArgumentParser.java index 628b469c..af5f1c6a 100644 --- a/src/main/java/lanat/ArgumentParser.java +++ b/src/main/java/lanat/ArgumentParser.java @@ -218,11 +218,11 @@ private void parseTokens() { @Override - @NotNull ParsedArgumentsRoot getParsedArguments() { - return new ParsedArgumentsRoot( + @NotNull ParseResultRoot getParseResult() { + return new ParseResultRoot( this, - this.getParser().getParsedArgumentsHashMap(), - this.getCommands().stream().map(Command::getParsedArguments).toList(), + this.getParser().getParsedArgsMap(), + this.getCommands().stream().map(Command::getParseResult).toList(), this.getForwardValue() ); } @@ -359,10 +359,10 @@ public AfterParseOptions exitIfNoInput() { } /** - * Returns a {@link ParsedArgumentsRoot} object that contains all the parsed arguments. + * Returns a {@link ParseResultRoot} object that contains all the parsed arguments. */ - public @NotNull ParsedArgumentsRoot getParsedArguments() { - return ArgumentParser.this.getParsedArguments(); + public @NotNull ParseResultRoot getResult() { + return ArgumentParser.this.getParseResult(); } /** @@ -375,17 +375,17 @@ public AfterParseOptions exitIfNoInput() { * @see CommandTemplate */ public T into(@NotNull Class clazz) { - return AfterParseOptions.into(clazz, this.getParsedArguments()); + return AfterParseOptions.into(clazz, this.getResult()); } /** * {@link #into(Class)} helper method. * @param templateClass The Command Template class to instantiate. - * @param parsedArgs The parsed arguments to set the fields of the Command Template class. + * @param parseResult The parsed arguments to set the fields of the Command Template class. */ private static T into( @NotNull Class templateClass, - @NotNull ParsedArguments parsedArgs + @NotNull ParseResult parseResult ) { final T instance = UtlReflection.instantiate(templateClass); @@ -393,7 +393,7 @@ private static T into( // set the values of the fields Stream.of(templateClass.getFields()) .filter(f -> f.isAnnotationPresent(Argument.Define.class)) - .forEach(field -> AfterParseOptions.into$setFieldValue(field, parsedArgs, instance)); + .forEach(field -> AfterParseOptions.into$setFieldValue(field, parseResult, instance)); // now handle the sub-command field accessors (if any) Stream.of(templateClass.getDeclaredClasses()) @@ -410,23 +410,23 @@ private static T into( ); }); - AfterParseOptions.into$handleCommandAccessor(instance, commandAccesorField, parsedArgs); + AfterParseOptions.into$handleCommandAccessor(instance, commandAccesorField, parseResult); }); - instance.afterInstantiation(parsedArgs); + instance.afterInstantiation(parseResult); return instance; } /** * {@link #into(Class)} helper method. Sets the value of the given field based on the parsed arguments. * @param field The field to set the value of. - * @param parsedArgs The parsed arguments to set the field value from. + * @param parseResult The parsed arguments to set the field value from. * @param instance The instance of the current Command Template class. * @param The type of the Command Template class. */ private static void into$setFieldValue( @NotNull Field field, - @NotNull ParsedArguments parsedArgs, + @NotNull ParseResult parseResult, @NotNull T instance ) { final var annotation = field.getAnnotation(Argument.Define.class); @@ -434,7 +434,7 @@ private static T into( // get the name of the argument from the annotation or field name final String argName = annotation.names().length == 0 ? field.getName() : annotation.names()[0]; - final @NotNull Optional parsedValue = parsedArgs.get(argName); + final @NotNull Optional parsedValue = parseResult.get(argName); try { // if the field has a value already set and the parsed value is empty, skip it (keep the old value) @@ -471,13 +471,13 @@ private static T into( * {@link #into(Class)} helper method. Handles the {@link CommandTemplate.CommandAccessor} annotation. * @param parsedTemplateInstance The instance of the current Command Template class. * @param commandAccesorField The field annotated with {@link CommandTemplate.CommandAccessor}. - * @param parsedArgs The parsed arguments to set the fields of the Command Template class. + * @param parseResult The parsed arguments to set the fields of the Command Template class. */ @SuppressWarnings("unchecked") private static void into$handleCommandAccessor( @NotNull T parsedTemplateInstance, @NotNull Field commandAccesorField, - @NotNull ParsedArguments parsedArgs + @NotNull ParseResult parseResult ) { final Class fieldType = commandAccesorField.getType(); @@ -494,7 +494,7 @@ private static T into( commandAccesorField.set(parsedTemplateInstance, AfterParseOptions.into( (Class)fieldType, - parsedArgs.getSubParsedArgs(cmdName) + parseResult.getSubResult(cmdName) ) ); } catch (IllegalAccessException e) { diff --git a/src/main/java/lanat/Command.java b/src/main/java/lanat/Command.java index 67523e51..6fc2b630 100644 --- a/src/main/java/lanat/Command.java +++ b/src/main/java/lanat/Command.java @@ -39,7 +39,7 @@ */ public class Command extends ErrorsContainerImpl - implements ErrorCallbacks, + implements ErrorCallbacks, ArgumentAdder, ArgumentGroupAdder, CommandAdder, @@ -59,7 +59,7 @@ public class Command // error handling callbacks private @Nullable Consumer onErrorCallback; - private @Nullable Consumer onCorrectCallback; + private @Nullable Consumer onCorrectCallback; private final @NotNull ModifyRecord helpFormatter = ModifyRecord.of(new HelpFormatter()); private final @NotNull ModifyRecord<@NotNull CallbacksInvocationOption> callbackInvocationOption = @@ -310,14 +310,14 @@ boolean uniqueArgumentReceivedValue(@Nullable Argument exclude) { } /** - * Returns a new {@link ParsedArguments} object that contains all the parsed arguments of this command and all its + * Returns a new {@link ParseResult} object that contains all the parsed arguments of this command and all its * Sub-Commands. */ - @NotNull ParsedArguments getParsedArguments() { - return new ParsedArguments( + @NotNull ParseResult getParseResult() { + return new ParseResult( this, - this.parser.getParsedArgumentsHashMap(), - this.subCommands.stream().map(Command::getParsedArguments).toList() + this.parser.getParsedArgsMap(), + this.subCommands.stream().map(Command::getParseResult).toList() ); } @@ -480,19 +480,19 @@ public void setOnErrorCallback(@Nullable Consumer<@NotNull Command> callback) { *

*/ @Override - public void setOnOkCallback(@Nullable Consumer<@NotNull ParsedArguments> callback) { + public void setOnOkCallback(@Nullable Consumer<@NotNull ParseResult> callback) { this.onCorrectCallback = callback; } @Override public void invokeCallbacks() { if (this.shouldExecuteCorrectCallback()) { - if (this.onCorrectCallback != null) this.onCorrectCallback.accept(this.getParsedArguments()); + if (this.onCorrectCallback != null) this.onCorrectCallback.accept(this.getParseResult()); } else { if (this.onErrorCallback != null) this.onErrorCallback.accept(this); } - this.parser.getParsedArgumentsHashMap() + this.parser.getParsedArgsMap() .entrySet() .stream() .sorted((x, y) -> Argument.compareByPriority(x.getKey(), y.getKey())) // sort by priority when invoking callbacks! diff --git a/src/main/java/lanat/CommandTemplate.java b/src/main/java/lanat/CommandTemplate.java index 65e4e1f2..212bacdb 100644 --- a/src/main/java/lanat/CommandTemplate.java +++ b/src/main/java/lanat/CommandTemplate.java @@ -101,31 +101,31 @@ @Command.Define public abstract class CommandTemplate { /** The parsed arguments of the command. */ - private ParsedArguments parsedArguments; + private ParseResult parseResult; /** * Called right after the Command Template is instantiated by the Argument Parser. - * Sets the {@link #parsedArguments} field and calls {@link #onValuesReceived()} if the command was used. + * Sets the {@link #parseResult} field and calls {@link #onValuesReceived()} if the command was used. *

* The reason this is used instead of a constructor is because we don't want to force inheritors to call * {@code super()} in their constructors. Also, this method is called first by the innermost Command in * the hierarchy, and then by the parent Commands. - * @param parsedArguments The parsed arguments of the command. + * @param parseResult The parsed arguments of the command. */ - void afterInstantiation(@NotNull ParsedArguments parsedArguments) { - this.parsedArguments = parsedArguments; + void afterInstantiation(@NotNull ParseResult parseResult) { + this.parseResult = parseResult; if (this.wasUsed()) this.onValuesReceived(); } /** - * Returns the {@link ParsedArguments} instance used by this Command Template. This instance is the one that was + * Returns the {@link ParseResult} instance used by this Command Template. This instance is the one that was * used to initialize this Command Template. - * @return The {@link ParsedArguments} instance used by this Command Template. + * @return The {@link ParseResult} instance used by this Command Template. */ - public final @NotNull ParsedArguments getParsedArguments() { - if (this.parsedArguments == null) + public final @NotNull ParseResult getParseResult() { + if (this.parseResult == null) throw new IllegalStateException("Command Template was not properly initialized by the Argument Parser."); - return this.parsedArguments; + return this.parseResult; } /** @@ -134,7 +134,7 @@ void afterInstantiation(@NotNull ParsedArguments parsedArguments) { * @return The {@link Command} instance used by this Command Template. */ public final @NotNull Command getCommand() { - return this.getParsedArguments().getCommand(); + return this.getParseResult().getCommand(); } /** @@ -142,7 +142,7 @@ void afterInstantiation(@NotNull ParsedArguments parsedArguments) { * @return {@code true} if the Command of this Template was used in the command line, {@code false} otherwise. */ public final boolean wasUsed() { - return this.getParsedArguments().wasUsed(); + return this.getParseResult().wasUsed(); } /** diff --git a/src/main/java/lanat/ParsedArguments.java b/src/main/java/lanat/ParseResult.java similarity index 76% rename from src/main/java/lanat/ParsedArguments.java rename to src/main/java/lanat/ParseResult.java index 9eabbe7c..53f74dcd 100644 --- a/src/main/java/lanat/ParsedArguments.java +++ b/src/main/java/lanat/ParseResult.java @@ -14,29 +14,29 @@ /** * Container for all the parsed arguments and their respective values. */ -public class ParsedArguments { +public class ParseResult { /** The parsed arguments. Pairs of each argument and it's respective value */ - private final @NotNull HashMap<@NotNull Argument, @Nullable Object> parsedArgs; + private final @NotNull HashMap<@NotNull Argument, @Nullable Object> parsedArgumentValues; - /** The {@link Command} that this {@link ParsedArguments} object belongs to */ + /** The {@link Command} that this {@link ParseResult} object belongs to */ private final @NotNull Command cmd; /** Whether the command was used or not */ private final boolean wasUsed; - /** The other inner {@link ParsedArguments}s for the sub-commands */ - private final @NotNull List<@NotNull ParsedArguments> subParsedArguments; + /** The other inner {@link ParseResult}s for the sub-commands */ + private final @NotNull List<@NotNull ParseResult> subResults; - ParsedArguments( + ParseResult( @NotNull Command cmd, - @NotNull HashMap<@NotNull Argument, @Nullable Object> parsedArgs, - @NotNull List<@NotNull ParsedArguments> subParsedArguments + @NotNull HashMap<@NotNull Argument, @Nullable Object> parsedArgumentValues, + @NotNull List<@NotNull ParseResult> subResults ) { - this.parsedArgs = parsedArgs; + this.parsedArgumentValues = parsedArgumentValues; this.cmd = cmd; this.wasUsed = cmd.getTokenizer().hasFinished(); - this.subParsedArguments = subParsedArguments; + this.subResults = subResults; } @@ -49,9 +49,9 @@ public boolean wasUsed() { } /** - * Returns the {@link Command} that this {@link ParsedArguments} object belongs to. This is the Command + * Returns the {@link Command} that this {@link ParseResult} object belongs to. This is the Command * that was used to parse the arguments. - * @return The {@link Command} that this {@link ParsedArguments} object belongs to + * @return The {@link Command} that this {@link ParseResult} object belongs to */ public @NotNull Command getCommand() { return this.cmd; @@ -66,11 +66,11 @@ public boolean wasUsed() { */ @SuppressWarnings("unchecked") // we'll just have to trust the user public @NotNull Optional get(@NotNull Argument arg) { - if (!this.parsedArgs.containsKey(arg)) { + if (!this.parsedArgumentValues.containsKey(arg)) { throw new ArgumentNotFoundException(arg); } - return Optional.ofNullable((T)this.parsedArgs.get(arg)); + return Optional.ofNullable((T)this.parsedArgumentValues.get(arg)); } /** @@ -81,7 +81,7 @@ public boolean wasUsed() { * * Example: *

-	 * {@code var argValue = parsedArguments.get("rootcommand.subCommand.argument")}
+	 * {@code var argValue = result.get("rootcommand.subCommand.argument")}
 	 * 
*

* More info at {@link #get(String...)} @@ -106,7 +106,7 @@ public boolean wasUsed() { * * Example: *

-	 * {@code var argValue = parsedArguments.get("rootcommand", "subCommand", "argument")}
+	 * {@code var argValue = result.get("rootcommand", "subCommand", "argument")}
 	 * 
* Returns the parsed value of the argument in the next command hierarchy: *
    @@ -134,16 +134,16 @@ public boolean wasUsed() { return (Optional)this.get(this.getArgument(argRoute[0])); } - return this.getSubParsedArgs(argRoute[0]) + return this.getSubResult(argRoute[0]) .get(Arrays.copyOfRange(argRoute, 1, argRoute.length)); } /** - * Returns the argument in {@link #parsedArgs} with the given name. + * Returns the argument in {@link #parsedArgumentValues} with the given name. * @throws ArgumentNotFoundException If no argument with the given name is found */ private @NotNull Argument getArgument(@NotNull String name) { - for (var arg : this.parsedArgs.keySet()) { + for (var arg : this.parsedArgumentValues.keySet()) { if (arg.hasName(name)) { return arg; } @@ -151,16 +151,17 @@ public boolean wasUsed() { throw new ArgumentNotFoundException(name); } + // TODO: FIX DESCRIPTION /** - * Returns the sub {@link ParsedArguments} with the given name. If none is found with the given name, returns + * Returns the sub {@link ParseResult} with the given name. If none is found with the given name, returns * {@code null}. * * @param name The name of the sub command * @throws CommandNotFoundException If no sub command with the given name is found - * @return The sub {@link ParsedArguments} with the given name + * @return The sub {@link ParseResult} with the given name */ - public @NotNull ParsedArguments getSubParsedArgs(@NotNull String name) { - for (var sub : this.subParsedArguments) + public @NotNull ParseResult getSubResult(@NotNull String name) { + for (var sub : this.subResults) if (sub.cmd.hasName(name)) return sub; throw new CommandNotFoundException(name); diff --git a/src/main/java/lanat/ParsedArgumentsRoot.java b/src/main/java/lanat/ParseResultRoot.java similarity index 82% rename from src/main/java/lanat/ParsedArgumentsRoot.java rename to src/main/java/lanat/ParseResultRoot.java index 940146b7..7abc2f05 100644 --- a/src/main/java/lanat/ParsedArgumentsRoot.java +++ b/src/main/java/lanat/ParseResultRoot.java @@ -11,17 +11,17 @@ * Container for all the parsed arguments and their respective values. * Provides methods specific to the root command. */ -public class ParsedArgumentsRoot extends ParsedArguments { +public class ParseResultRoot extends ParseResult { private final @Nullable String forwardValue; - ParsedArgumentsRoot( + ParseResultRoot( @NotNull ArgumentParser cmd, - @NotNull HashMap<@NotNull Argument, @Nullable Object> parsedArgs, - @NotNull List<@NotNull ParsedArguments> subArgs, + @NotNull HashMap<@NotNull Argument, @Nullable Object> parsedArgumentValues, + @NotNull List<@NotNull ParseResult> subArgs, @Nullable String forwardValue ) { - super(cmd, parsedArgs, subArgs); + super(cmd, parsedArgumentValues, subArgs); this.forwardValue = forwardValue; } @@ -33,4 +33,4 @@ public class ParsedArgumentsRoot extends ParsedArguments { public @NotNull Optional getForwardValue() { return Optional.ofNullable(this.forwardValue); } -} +} \ No newline at end of file diff --git a/src/main/java/lanat/parsing/Parser.java b/src/main/java/lanat/parsing/Parser.java index 40273a27..fc7961a1 100644 --- a/src/main/java/lanat/parsing/Parser.java +++ b/src/main/java/lanat/parsing/Parser.java @@ -21,7 +21,7 @@ * of the arguments that are being parsed. *

    * When finished parsing, this class will contain a map of the arguments to their parsed values. This map can be accessed - * by calling {@link Parser#getParsedArgumentsHashMap()}. + * by calling {@link Parser#getParsedArgsMap()}. */ public final class Parser extends ParsingStateBase { /** @@ -41,10 +41,10 @@ public final class Parser extends ParsingStateBase { /** * The parsed arguments. This is a map of the argument to the value that it parsed. The reason this is saved is that - * we don't want to run {@link Parser#getParsedArgumentsHashMap()} multiple times because that can break stuff badly + * we don't want to run {@link Parser#getParsedArgsMap()} multiple times because that can break stuff badly * in relation to error handling. */ - private HashMap<@NotNull Argument, @Nullable Object> parsedArguments; + private HashMap<@NotNull Argument, @Nullable Object> parsedArgumentValues; /** Contains the forward value if one was found. */ private @Nullable String forwardValue; @@ -316,13 +316,13 @@ private void checkForSimilarArgumentName(@NotNull String str) { * This function invokes the {@link Argument#finishParsing()} method on each argument the first time it is called. * After that, it will return the same hashmap. * */ - public @NotNull HashMap<@NotNull Argument, @Nullable Object> getParsedArgumentsHashMap() { - if (this.parsedArguments == null) { - this.parsedArguments = new HashMap<>() {{ + public @NotNull HashMap<@NotNull Argument, @Nullable Object> getParsedArgsMap() { + if (this.parsedArgumentValues == null) { + this.parsedArgumentValues = new HashMap<>() {{ Parser.this.command.getArguments().forEach(arg -> this.put(arg, arg.finishParsing())); }}; } - return this.parsedArguments; + return this.parsedArgumentValues; } private void argumentTypeParseValues(@NotNull Argument argument, @NotNull String... values) { @@ -343,4 +343,4 @@ private void addIncorrectValueNumberError(@NotNull Argument argument, int this.currentTokenIndex, argument, valueCount, isInArgNameList, this.isInTuple )); } -} +} \ No newline at end of file diff --git a/src/test/java/lanat/test/TestingParser.java b/src/test/java/lanat/test/TestingParser.java index eb5a3cfb..04702503 100644 --- a/src/test/java/lanat/test/TestingParser.java +++ b/src/test/java/lanat/test/TestingParser.java @@ -3,7 +3,7 @@ import lanat.ArgumentParser; import lanat.CLInput; import lanat.CommandTemplate; -import lanat.ParsedArgumentsRoot; +import lanat.ParseResultRoot; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -27,9 +27,9 @@ public List parseGetErrors(String args) { return this.parse(CLInput.from(args)).getErrors(); } - public @NotNull ParsedArgumentsRoot parseGetValues(@NotNull String args) { - var res = this.parse(CLInput.from(args)).printErrors().getParsedArguments(); + public @NotNull ParseResultRoot parseGetValues(@NotNull String args) { + var res = this.parse(CLInput.from(args)).printErrors().getResult(); assertNotNull(res, "The result of the parsing was null (Arguments have failed)"); return res; } -} +} \ No newline at end of file diff --git a/src/test/java/lanat/test/units/TestParsedValues.java b/src/test/java/lanat/test/units/TestParsedValues.java index 8caa50ba..d079d8e4 100644 --- a/src/test/java/lanat/test/units/TestParsedValues.java +++ b/src/test/java/lanat/test/units/TestParsedValues.java @@ -1,6 +1,6 @@ package lanat.test.units; -import lanat.ParsedArgumentsRoot; +import lanat.ParseResultRoot; import lanat.exceptions.ArgumentNotFoundException; import lanat.test.UnitTests; import org.junit.jupiter.api.DisplayName; @@ -11,7 +11,7 @@ import static org.junit.jupiter.api.Assertions.*; public class TestParsedValues extends UnitTests { - private ParsedArgumentsRoot parseArgs(String args) { + private ParseResultRoot parseArgs(String args) { return this.parser.parseGetValues(args); } From 165160743db6ad06aeef205d0151f4ef4225736c Mon Sep 17 00:00:00 2001 From: darvil82 Date: Thu, 28 Dec 2023 14:58:18 +0100 Subject: [PATCH 08/18] add ParseResultRoot#getUsedResults --- src/main/java/lanat/ArgumentParser.java | 3 +- src/main/java/lanat/CommandTemplate.java | 1 + src/main/java/lanat/ParseResult.java | 7 ++++- src/main/java/lanat/ParseResultRoot.java | 27 +++++++++++++++++ .../lanat/test/exampleTests/ExampleTest.java | 29 +++++++++++++------ 5 files changed, 56 insertions(+), 11 deletions(-) diff --git a/src/main/java/lanat/ArgumentParser.java b/src/main/java/lanat/ArgumentParser.java index af5f1c6a..9efef8e3 100644 --- a/src/main/java/lanat/ArgumentParser.java +++ b/src/main/java/lanat/ArgumentParser.java @@ -29,7 +29,7 @@ public class ArgumentParser extends Command { private @Nullable String license; private @Nullable String version; - + // TODO: match constructor javadocs here with the ones in Command /** * Creates a new command with the given name and description. * @param programName The name of the command. This is the name the user will use to indicate that they want to use this @@ -59,6 +59,7 @@ public ArgumentParser(@NotNull Class templateClass) { super(templateClass); } + // TODO: add info about the code comparison between using from() and not using it /** * Constructs a new {@link ArgumentParser} based on the given {@link CommandTemplate}, taking Sub-Commands into * account. diff --git a/src/main/java/lanat/CommandTemplate.java b/src/main/java/lanat/CommandTemplate.java index 212bacdb..389e662d 100644 --- a/src/main/java/lanat/CommandTemplate.java +++ b/src/main/java/lanat/CommandTemplate.java @@ -145,6 +145,7 @@ public final boolean wasUsed() { return this.getParseResult().wasUsed(); } + // TODO: add note to not use this method manually /** * Called when the Command of this Template is used in the command line. * This method is called after the parsed values are set. diff --git a/src/main/java/lanat/ParseResult.java b/src/main/java/lanat/ParseResult.java index 53f74dcd..71a3e67c 100644 --- a/src/main/java/lanat/ParseResult.java +++ b/src/main/java/lanat/ParseResult.java @@ -25,7 +25,7 @@ public class ParseResult { private final boolean wasUsed; /** The other inner {@link ParseResult}s for the sub-commands */ - private final @NotNull List<@NotNull ParseResult> subResults; + protected final @NotNull List<@NotNull ParseResult> subResults; ParseResult( @@ -73,6 +73,7 @@ public boolean wasUsed() { return Optional.ofNullable((T)this.parsedArgumentValues.get(arg)); } + // TODO: replace all ... instances with {@code ...} /** * Returns the parsed value of the argument with the given name. In order to access arguments in sub-commands, use * the . separator to specify the route to the argument. @@ -95,6 +96,9 @@ public boolean wasUsed() { * @throws ArgumentNotFoundException If the argument specified in the route does not exist */ public @NotNull Optional get(@NotNull String argRoute) { + if (!argRoute.contains(".")) + return this.get(new String[] { argRoute }); + return this.get(UtlString.split(argRoute, '.')); } @@ -120,6 +124,7 @@ public boolean wasUsed() { *
* * @throws CommandNotFoundException If the command specified in the route does not exist + * @throws ArgumentNotFoundException If the argument specified in the route does not exist * @return An {@link Optional} containing the parsed value of the argument with the given name, or * {@link Optional#empty()} if the argument was not found. * @param The type of the value of the argument. diff --git a/src/main/java/lanat/ParseResultRoot.java b/src/main/java/lanat/ParseResultRoot.java index 7abc2f05..01f0a9b4 100644 --- a/src/main/java/lanat/ParseResultRoot.java +++ b/src/main/java/lanat/ParseResultRoot.java @@ -3,6 +3,7 @@ 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.Optional; @@ -33,4 +34,30 @@ public class ParseResultRoot extends ParseResult { public @NotNull Optional getForwardValue() { return Optional.ofNullable(this.forwardValue); } + + /** + * Returns a list of all the {@link ParseResult} objects that belong to a command that was used by the user. + * The list is ordered from the root command to the last used command. + *

+ * The list contains this {@link ParseResultRoot} object as well. + * @return A list of all the {@link ParseResult} objects that belong to a command that was used by the user + */ + public @NotNull List<@NotNull ParseResult> getUsedResults() { + if (!this.wasUsed()) + return List.of(); + + ParseResult current = this; + var list = new ArrayList(1); + + while (current != null) { + list.add(current); + + current = current.subResults.stream() + .filter(ParseResult::wasUsed) + .findFirst() + .orElse(null); + } + + return list; + } } \ No newline at end of file diff --git a/src/test/java/lanat/test/exampleTests/ExampleTest.java b/src/test/java/lanat/test/exampleTests/ExampleTest.java index 8af006c1..85d2d515 100644 --- a/src/test/java/lanat/test/exampleTests/ExampleTest.java +++ b/src/test/java/lanat/test/exampleTests/ExampleTest.java @@ -1,10 +1,6 @@ package lanat.test.exampleTests; import lanat.*; -import lanat.argumentTypes.CounterArgumentType; -import lanat.argumentTypes.IntegerArgumentType; -import lanat.argumentTypes.MultipleStringsArgumentType; -import lanat.argumentTypes.NumberRangeArgumentType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.junit.jupiter.api.Test; @@ -18,11 +14,26 @@ public void main() { // TextFormatter.enableSequences = false; // ErrorFormatter.errorFormatterClass = SimpleErrorFormatter.class; - var result = ArgumentParser.parseFromInto( - CommandTemplateExample.class, - CLInput.from("--number 12 sub-command -ccc"), - opts -> opts.printErrors() - ); +// ArgumentParser.parseFromInto( +// CommandTemplateExample.class, +// CLInput.from("--number 12 sub-command -ccc"), +// opts -> opts.printErrors() +// ); + + ArgumentParser.from(CommandTemplateExample.class) + .parse(CLInput.from("--number 12 sub-command -ccc")) + .getResult() + .getUsedResults() + .forEach(result -> { + var cmdName = result.getCommand().getName(); + System.out.println(cmdName + " was used!"); + + switch (cmdName) { + case "my-program" -> System.out.println("number value: " + result.get("number")); + case "sub-command" -> System.out.println("c value: " + result.get("c")); + case "another-sub-command" -> System.out.println("c value: " + result.get("c")); + } + }); } public static class Example1Type extends ArgumentType { From c428bdd3b9493b8febab73c8d0835f83ca26c24b Mon Sep 17 00:00:00 2001 From: darvil82 Date: Thu, 28 Dec 2023 15:11:18 +0100 Subject: [PATCH 09/18] add todo note --- src/main/java/lanat/ParseResultRoot.java | 3 +-- .../lanat/helpRepresentation/descriptions/RouteParser.java | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/lanat/ParseResultRoot.java b/src/main/java/lanat/ParseResultRoot.java index 01f0a9b4..3ca4d1ac 100644 --- a/src/main/java/lanat/ParseResultRoot.java +++ b/src/main/java/lanat/ParseResultRoot.java @@ -20,8 +20,7 @@ public class ParseResultRoot extends ParseResult { @NotNull HashMap<@NotNull Argument, @Nullable Object> parsedArgumentValues, @NotNull List<@NotNull ParseResult> subArgs, @Nullable String forwardValue - ) - { + ) { super(cmd, parsedArgumentValues, subArgs); this.forwardValue = forwardValue; } diff --git a/src/main/java/lanat/helpRepresentation/descriptions/RouteParser.java b/src/main/java/lanat/helpRepresentation/descriptions/RouteParser.java index f47b4bbb..fa186ad7 100644 --- a/src/main/java/lanat/helpRepresentation/descriptions/RouteParser.java +++ b/src/main/java/lanat/helpRepresentation/descriptions/RouteParser.java @@ -69,7 +69,7 @@ public class RouteParser { private RouteParser(@NotNull NamedWithDescription user, @Nullable String route) { // if route is empty, the command the user belongs to is the target - if (UtlString.isNullOrEmpty(route)) { + if (UtlString.isNullOrEmpty(route)) { // TODO: replace with UtlString.isNullOrBlank once utils is bumped this.currentTarget = RouteParser.getCommandOf(user); this.route = new String[0]; return; @@ -171,4 +171,4 @@ void setCurrentTarget(List list, BiFunction predicate) { + UtlReflection.getSimpleName(this.currentTarget.getClass()) + ' ' + this.currentTarget.getName()) ); } -} +} \ No newline at end of file From 84afff589812ae45bb7980da82a1a9822ae94a2c Mon Sep 17 00:00:00 2001 From: darvil82 Date: Thu, 28 Dec 2023 15:17:55 +0100 Subject: [PATCH 10/18] fix: javadoc in getSubResult --- src/main/java/lanat/ParseResult.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/lanat/ParseResult.java b/src/main/java/lanat/ParseResult.java index 71a3e67c..fa215af6 100644 --- a/src/main/java/lanat/ParseResult.java +++ b/src/main/java/lanat/ParseResult.java @@ -156,10 +156,9 @@ public boolean wasUsed() { throw new ArgumentNotFoundException(name); } - // TODO: FIX DESCRIPTION /** - * Returns the sub {@link ParseResult} with the given name. If none is found with the given name, returns - * {@code null}. + * Returns the sub {@link ParseResult} with the given name. If none is found with the given name, + * {@link CommandNotFoundException} is thrown. * * @param name The name of the sub command * @throws CommandNotFoundException If no sub command with the given name is found From 7dcb85db6f616cc0436d5826cd6c46d05dddb5b5 Mon Sep 17 00:00:00 2001 From: darvil82 Date: Thu, 28 Dec 2023 15:21:02 +0100 Subject: [PATCH 11/18] change all instances to {@code } --- src/main/java/lanat/Argument.java | 10 +++---- src/main/java/lanat/ArgumentType.java | 2 +- src/main/java/lanat/Command.java | 6 ++-- src/main/java/lanat/ParseResult.java | 5 ++-- .../descriptions/RouteParser.java | 28 +++++++++---------- src/main/java/lanat/parsing/Tokenizer.java | 6 ++-- 6 files changed, 28 insertions(+), 29 deletions(-) diff --git a/src/main/java/lanat/Argument.java b/src/main/java/lanat/Argument.java index ecb3c406..6b617822 100644 --- a/src/main/java/lanat/Argument.java +++ b/src/main/java/lanat/Argument.java @@ -276,8 +276,8 @@ public void setDefaultValue(@Nullable TInner value) { * names. *

*

- * Single character names can be used in argument name lists (e.g. -abc), each alphabetic character - * being an argument name, that is, -a -b -c. + * Single character names can be used in argument name lists (e.g. {@code -abc}), each alphabetic character + * being an argument name, that is, {@code -a -b -c}. *

* * @param names the names that should be added to this argument. @@ -463,8 +463,8 @@ public void setRepresentationColor(@NotNull Color color) { /** * Checks if this argument matches the given name, including the prefix. *

- * For example, if the prefix is '-' and the argument has the name "help", this method - * will return {@code true} if the name is "--help". + * For example, if the prefix is {@code '-'} and the argument has the name {@code "help"}, this method + * will return {@code true} if the name is {@code "--help"}. *

* * @param name the name to check @@ -651,7 +651,7 @@ private PrefixChar(char character) { *

* NOTE:
* The constant fields of this class should be used instead of this method. Other characters could break - * compatibility with shells using special characters as prefixes, such as the | or ; + * compatibility with shells using special characters as prefixes, such as the {@code |} or {@code ;} * characters. *

* diff --git a/src/main/java/lanat/ArgumentType.java b/src/main/java/lanat/ArgumentType.java index d84fada2..571a7334 100644 --- a/src/main/java/lanat/ArgumentType.java +++ b/src/main/java/lanat/ArgumentType.java @@ -287,7 +287,7 @@ int getLastReceivedValuesNum() { /** * Iterates over the values that this argument received when being parsed. This also sets - * this.currentArgValueIndex to the current index of the value. + * {@code this.currentArgValueIndex} to the current index of the value. * * @param args The values that this argument received when being parsed. * @param consumer The consumer that will be called for each value. diff --git a/src/main/java/lanat/Command.java b/src/main/java/lanat/Command.java index 6fc2b630..e7412014 100644 --- a/src/main/java/lanat/Command.java +++ b/src/main/java/lanat/Command.java @@ -184,10 +184,10 @@ public void registerToCommand(@NotNull Command parentCommand) { * fail, the program will return the result of the OR bit operation that will be applied to all other command * results. For example: *
    - *
  • Command 'foo' has a return value of 2. (0b010)
  • - *
  • Command 'bar' has a return value of 5. (0b101)
  • + *
  • Command 'foo' has a return value of 2. {@code (0b010)}
  • + *
  • Command 'bar' has a return value of 5. {@code (0b101)}
  • *
- * Both commands failed, so in this case the resultant return value would be 7 (0b111). + * Both commands failed, so in this case the resultant return value would be 7 {@code (0b111)}. * @param errorCode The error code to return when this command fails. */ public void setErrorCode(int errorCode) { diff --git a/src/main/java/lanat/ParseResult.java b/src/main/java/lanat/ParseResult.java index fa215af6..ed5c8bd5 100644 --- a/src/main/java/lanat/ParseResult.java +++ b/src/main/java/lanat/ParseResult.java @@ -73,10 +73,9 @@ public boolean wasUsed() { return Optional.ofNullable((T)this.parsedArgumentValues.get(arg)); } - // TODO: replace all ... instances with {@code ...} /** * Returns the parsed value of the argument with the given name. In order to access arguments in sub-commands, use - * the . separator to specify the route to the argument. + * the {@code .} separator to specify the route to the argument. * *

* @@ -87,7 +86,7 @@ public boolean wasUsed() { *

* More info at {@link #get(String...)} * - * @param argRoute The route to the argument, separated by the . character. + * @param argRoute The route to the argument, separated by the {@code .} character. * @param The type of the value of the argument. This is used to avoid casting. A type that does not match the * argument's type will result in a {@link ClassCastException}. * @return An {@link Optional} containing the parsed value of the argument with the given name, or diff --git a/src/main/java/lanat/helpRepresentation/descriptions/RouteParser.java b/src/main/java/lanat/helpRepresentation/descriptions/RouteParser.java index fa186ad7..34aa9339 100644 --- a/src/main/java/lanat/helpRepresentation/descriptions/RouteParser.java +++ b/src/main/java/lanat/helpRepresentation/descriptions/RouteParser.java @@ -13,28 +13,28 @@ import java.util.function.BiFunction; /** - * Parser for simple route syntax used in description tags (e.g. args.myArg1.type). + * Parser for simple route syntax used in description tags (e.g. {@code args.myArg1.type}). *

* The route syntax is very simple. It is a dot-separated list of names indicating the path to the object to be * returned. By default, the route initial target is the command the user belongs to. If the route starts with - * !, the user itself becomes the initial target. If the route is empty or null, the command the user + * {@code !}, the user itself becomes the initial target. If the route is empty or null, the command the user * belongs to is returned. *

*

* These are the objects that can be accessed using the route syntax: *

    - *
  • args: the arguments of the command. + *
  • {@code args}: the arguments of the command. *
      - *
    • type: the type of the argument. + *
    • {@code type}: the type of the argument. *

      * Note that this only works if the current target is an {@link Argument}. *

      *
    • *
    *
  • - *
  • groups: the groups of the command.
  • + *
  • {@code groups}: the groups of the command.
  • *
  • - * cmds: the subcommands of the command. + * {@code cmds}: the subcommands of the command. *

    * Note that after selecting a command, all the selectors above can be used again to select inner objects of the command. *

    @@ -44,20 +44,20 @@ *

    Examples

    *
      *
    1. - * Select the type of the argument myArg1 of the current command: - * "args.myArg1.type" + * Select the type of the argument {@code myArg1} of the current command: + * {@code "args.myArg1.type"} *
    2. *
    3. - * Select the Sub-Command myCmd of the current command: - * "cmds.myCmd" + * Select the Sub-Command {@code myCmd} of the current command: + * {@code "cmds.myCmd"} *
    4. *
    5. - * Select the type of the argument myArg1 of the Sub-Command myCmd of the current command: - * "cmds.myCmd.args.myArg1.type" + * Select the type of the argument {@code myArg1} of the Sub-Command {@code myCmd} of the current command: + * {@code "cmds.myCmd.args.myArg1.type"} *
    6. *
    7. * Select the {@link ArgumentType} of the {@link Argument} that is requesting to parse this description: - * "!.type" + * {@code "!.type"} *
    8. *
    */ @@ -94,7 +94,7 @@ private RouteParser(@NotNull NamedWithDescription user, @Nullable String route) * to is returned. *

    * The reason why the user is needed is because its likely that it will be needed to gather the Command it belongs - * to, and also if the route starts with !, the user itself becomes the initial target. + * to, and also if the route starts with {@code !}, the user itself becomes the initial target. *

    * * @param user the user that is requesting to parse the route diff --git a/src/main/java/lanat/parsing/Tokenizer.java b/src/main/java/lanat/parsing/Tokenizer.java index 879ecc1b..7f21c37a 100644 --- a/src/main/java/lanat/parsing/Tokenizer.java +++ b/src/main/java/lanat/parsing/Tokenizer.java @@ -268,7 +268,7 @@ private void tokenizeCurrentValue() { } /** - * Returns {@code true} if the given string can be an argument name list, eg: "-fbq". + * Returns {@code true} if the given string can be an argument name list, eg: {@code "-fbq"}. *

    * This returns {@code true} if at least the first character is a valid argument prefix and at least one of the * next characters is a valid argument name. @@ -300,7 +300,7 @@ private boolean isArgNameList(@NotNull String str) { } /** - * Returns {@code true} if the given string can be an argument name, eg: "--help". + * Returns {@code true} if the given string can be an argument name, eg: {@code "--help"}. *

    * This returns {@code true} if the given string is a valid argument name with a double prefix. *

    @@ -378,4 +378,4 @@ private boolean isCharAtRelativeIndex(int index, @NotNull Predicate<@NotNull Cha public String getInputString() { return this.inputString; } -} +} \ No newline at end of file From 5ed5c5d04c4c202e4a06012f883c5465f470d064 Mon Sep 17 00:00:00 2001 From: darvil82 Date: Thu, 28 Dec 2023 17:04:37 +0100 Subject: [PATCH 12/18] random javadoc improvements --- build.gradle.kts | 9 +++++-- src/main/java/lanat/ArgumentParser.java | 34 +++++++++++++++++------- src/main/java/lanat/Command.java | 1 + src/main/java/lanat/CommandTemplate.java | 4 ++- 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index fba61275..bc24f0bb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,8 +8,13 @@ version = "0.2.1" description = "Command line argument parser" dependencies { - implementation("com.darvil:utils:0.0.2") - implementation("com.darvil:terminal-text-formatter:1.0.0") + val implWithJavadoc = { s: String -> + implementation(s) + implementation(s + ":javadoc") + } + + implWithJavadoc("com.darvil:utils:0.0.2") + implWithJavadoc("com.darvil:terminal-text-formatter:1.0.0") implementation("org.jetbrains:annotations:24.0.1") testImplementation(platform("org.junit:junit-bom:5.9.1")) diff --git a/src/main/java/lanat/ArgumentParser.java b/src/main/java/lanat/ArgumentParser.java index 9efef8e3..5fed7fc7 100644 --- a/src/main/java/lanat/ArgumentParser.java +++ b/src/main/java/lanat/ArgumentParser.java @@ -23,13 +23,14 @@ *

    Argument Parser

    *

    * Provides the ability to parse a command line input and later gather the values of the parsed arguments. + * @see Command */ public class ArgumentParser extends Command { + /** This is used to be able to tell if we should reset the state of all the commands before parsing */ private boolean isParsed = false; private @Nullable String license; private @Nullable String version; - // TODO: match constructor javadocs here with the ones in Command /** * Creates a new command with the given name and description. * @param programName The name of the command. This is the name the user will use to indicate that they want to use this @@ -52,17 +53,27 @@ public ArgumentParser(@NotNull String programName) { /** * Creates a new command based on the given {@link CommandTemplate}. This does not take Sub-Commands into account. - * If you want to add Sub-Commands, use {@link #from(Class)} instead. + * If you want to add Sub-Commands, use {@link ArgumentParser#from(Class)} instead. * @param templateClass The class of the template to use. + * @see CommandTemplate */ public ArgumentParser(@NotNull Class templateClass) { super(templateClass); } - // TODO: add info about the code comparison between using from() and not using it /** * Constructs a new {@link ArgumentParser} based on the given {@link CommandTemplate}, taking Sub-Commands into * account. + *

    + * This is basically a shortcut for the following code: + *

    {@code
    +	 * new ArgumentParser(clazz) {{
    +	 *     this.addCommand(new Command(subCmdClazz)); // do this for all possible sub-commands
    +	 * }};
    +	 * }
    + * This method basically makes it easier to add Sub-Commands to the given {@link CommandTemplate}. It looks for + * {@link lanat.CommandTemplate.CommandAccessor} annotations in the given class and adds the corresponding + * sub-commands to the {@link Command} object. This is done recursively. * @param templateClass The class of the {@link CommandTemplate} to use. * @return A new {@link ArgumentParser} based on the given {@link CommandTemplate}. * @see CommandTemplate @@ -82,14 +93,12 @@ public static ArgumentParser from(@NotNull Class temp *

    * This is basically a shortcut for the following code: *

    {@code
    -	 * new ArgumentParser(clazz).parse(input).into(clazz);
    +	 * ArgumentParser.from(clazz).parse(input).into(clazz);
     	 * }
    *

    Example:

    * This code: *
    {@code
    -	 * MyTemplate parsed = new ArgumentParser(MyTemplate.class) {{
    -	 *     addCommand(new Command(MyTemplate.SubTemplate.class));
    -	 * }}
    +	 * ArgumentParser.from(MyTemplate.class)
     	 *     .parse(input)
     	 *     .printErrors()
     	 *     .exitIfErrors()
    @@ -101,7 +110,10 @@ public static ArgumentParser from(@NotNull Class temp
     	 * MyTemplate parsed = ArgumentParser.parseFromInto(MyTemplate.class, input);
     	 * }
     	 * 
    - * + * The example above uses the {@link #parseFromInto(Class, CLInput)} overload, which sets the default options for + * the {@link AfterParseOptions} object. + *

    + * This method uses {@link #from(Class)}. See that method for more info. * @param templateClass The class to use as a template. * @param input The input to parse. * @param options A consumer that can be used for configuring the parsing process. @@ -109,6 +121,8 @@ public static ArgumentParser from(@NotNull Class temp * @return The parsed template. * @see #parseFromInto(Class, CLInput) * @see CommandTemplate + * @see #from(Class) + * @see AfterParseOptions */ public static @NotNull T parseFromInto( @NotNull Class templateClass, @@ -125,12 +139,14 @@ public static ArgumentParser from(@NotNull Class temp /** * Constructs a new {@link ArgumentParser} based on the given {@link CommandTemplate}, parses the given input, and * populates the template with the parsed values. - * + *

    + * See {@link #parseFromInto(Class, CLInput, Consumer)} for more info. * @param templateClass The class to use as a template. * @param input The input to parse. * @param The type of the template. * @return The parsed template. * @see CommandTemplate + * @see #parseFromInto(Class, CLInput, Consumer) */ public static @NotNull T parseFromInto(@NotNull Class templateClass, @NotNull CLInput input) { diff --git a/src/main/java/lanat/Command.java b/src/main/java/lanat/Command.java index e7412014..fe52c322 100644 --- a/src/main/java/lanat/Command.java +++ b/src/main/java/lanat/Command.java @@ -92,6 +92,7 @@ public Command(@NotNull String name) { /** * Creates a new command based on the given {@link CommandTemplate}. This does not take Sub-Commands into account. + * If you want to add Sub-Commands, use {@link ArgumentParser#from(Class)} instead. * @param templateClass The class of the template to use. * @see CommandTemplate */ diff --git a/src/main/java/lanat/CommandTemplate.java b/src/main/java/lanat/CommandTemplate.java index 389e662d..d0904a0c 100644 --- a/src/main/java/lanat/CommandTemplate.java +++ b/src/main/java/lanat/CommandTemplate.java @@ -145,12 +145,14 @@ public final boolean wasUsed() { return this.getParseResult().wasUsed(); } - // TODO: add note to not use this method manually /** * Called when the Command of this Template is used in the command line. * This method is called after the parsed values are set. *

    * This method may be overridden to perform actions when the command is used. + *

    + * This method should not be called manually. It is called automatically by the Argument Parser once the Command + * Template is initialized. */ public void onValuesReceived() {} From 0d40c7c9a77c10bd0d63f8cddbf4a9d4033c3be1 Mon Sep 17 00:00:00 2001 From: darvil82 Date: Thu, 28 Dec 2023 17:08:39 +0100 Subject: [PATCH 13/18] bump utils --- build.gradle.kts | 2 +- .../java/lanat/helpRepresentation/descriptions/RouteParser.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index bc24f0bb..820debe9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,7 @@ dependencies { implementation(s + ":javadoc") } - implWithJavadoc("com.darvil:utils:0.0.2") + implWithJavadoc("com.darvil:utils:0.1.0") implWithJavadoc("com.darvil:terminal-text-formatter:1.0.0") implementation("org.jetbrains:annotations:24.0.1") diff --git a/src/main/java/lanat/helpRepresentation/descriptions/RouteParser.java b/src/main/java/lanat/helpRepresentation/descriptions/RouteParser.java index 34aa9339..cdd84fed 100644 --- a/src/main/java/lanat/helpRepresentation/descriptions/RouteParser.java +++ b/src/main/java/lanat/helpRepresentation/descriptions/RouteParser.java @@ -69,7 +69,7 @@ public class RouteParser { private RouteParser(@NotNull NamedWithDescription user, @Nullable String route) { // if route is empty, the command the user belongs to is the target - if (UtlString.isNullOrEmpty(route)) { // TODO: replace with UtlString.isNullOrBlank once utils is bumped + if (UtlString.isNullOrBlank(route)) { this.currentTarget = RouteParser.getCommandOf(user); this.route = new String[0]; return; From 5ce05dae3e862a1878ec9533e3ae0945a15e8961 Mon Sep 17 00:00:00 2001 From: darvil82 Date: Thu, 28 Dec 2023 17:10:18 +0100 Subject: [PATCH 14/18] fix issue after lib bump --- src/main/java/lanat/argumentTypes/TupleArgumentType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/lanat/argumentTypes/TupleArgumentType.java b/src/main/java/lanat/argumentTypes/TupleArgumentType.java index f7b9e6ba..498a39ec 100644 --- a/src/main/java/lanat/argumentTypes/TupleArgumentType.java +++ b/src/main/java/lanat/argumentTypes/TupleArgumentType.java @@ -52,7 +52,7 @@ public TupleArgumentType(@NotNull Range range, @NotNull ArgumentType argument return null; return argTypeRepr - .concat(new TextFormatter(this.argCount.getRegexRange()).withForegroundColor(Color.BRIGHT_YELLOW)); + .concat(new TextFormatter(this.argCount.getRepresentation()).withForegroundColor(Color.BRIGHT_YELLOW)); } @Override From b86fef19e9ec8b95bb8de9a7c5a4e0e0dceeaf77 Mon Sep 17 00:00:00 2001 From: darvil82 Date: Fri, 29 Dec 2023 16:11:18 +0100 Subject: [PATCH 15/18] remove unnecessary thing in build.kts --- build.gradle.kts | 9 ++------- .../lanat/test/exampleTests/CommandTemplateExample.java | 7 +++++-- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 820debe9..8390a2c3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,13 +8,8 @@ version = "0.2.1" description = "Command line argument parser" dependencies { - val implWithJavadoc = { s: String -> - implementation(s) - implementation(s + ":javadoc") - } - - implWithJavadoc("com.darvil:utils:0.1.0") - implWithJavadoc("com.darvil:terminal-text-formatter:1.0.0") + implementation("com.darvil:utils:0.1.0") + implementation("com.darvil:terminal-text-formatter:1.0.0") implementation("org.jetbrains:annotations:24.0.1") testImplementation(platform("org.junit:junit-bom:5.9.1")) diff --git a/src/test/java/lanat/test/exampleTests/CommandTemplateExample.java b/src/test/java/lanat/test/exampleTests/CommandTemplateExample.java index 374477d5..d7178ff2 100644 --- a/src/test/java/lanat/test/exampleTests/CommandTemplateExample.java +++ b/src/test/java/lanat/test/exampleTests/CommandTemplateExample.java @@ -1,6 +1,9 @@ package lanat.test.exampleTests; -import lanat.*; +import lanat.Argument; +import lanat.ArgumentGroup; +import lanat.Command; +import lanat.CommandTemplate; import lanat.argumentTypes.*; import org.jetbrains.annotations.NotNull; @@ -21,7 +24,7 @@ public class CommandTemplateExample extends CommandTemplate.Default { @Argument.Define(names = "arg1", argType = StringArgumentType.class) public String arg1; - @Argument.Define(description = "") + @Argument.Define(description = ". Must be executable.") public File file; @Argument.Define(names = "arg1a", argType = StringArgumentType.class) From 1117fc40a9bcc11b25849865e2a6a1ca20df6d73 Mon Sep 17 00:00:00 2001 From: darvil82 Date: Fri, 29 Dec 2023 16:34:20 +0100 Subject: [PATCH 16/18] improve docs --- README.md | 4 ++-- src/main/java/lanat/CommandTemplate.java | 23 ++++++++++++++++------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 816b26bc..6939e316 100644 --- a/README.md +++ b/README.md @@ -31,10 +31,10 @@ public int age = 18; @InitDef - public static void beforeInit(@NotNull CommandBuildHelper cmdBuildHelper) { + public static void beforeInit(@NotNull CommandBuildHelper helper) { // configure the argument "age" to have an argument type of // number range and set the range to 1-100 - cmdBuildHelper., Integer>getArgument("age") + helper., Integer>getArgument("age") .withArgType(new NumberRangeArgumentType<>(1, 100)) .onOk(v -> System.out.println("The age is valid!")); } diff --git a/src/main/java/lanat/CommandTemplate.java b/src/main/java/lanat/CommandTemplate.java index d0904a0c..972a6b5e 100644 --- a/src/main/java/lanat/CommandTemplate.java +++ b/src/main/java/lanat/CommandTemplate.java @@ -61,10 +61,19 @@ * @Argument.Define(names = {"name", "n"}, argType = StringArgumentType.class) * public String name; * - * @Argument.Define(argType = IntegerArgumentType.class, required = true) + * @Argument.Define // name: "numbers". argType: MultipleNumbersArgumentType + * public Integer[] numbers; + * + * @Argument.Define(required = true) // name: "file". argType: NumberRangeArgumentType * public Integer number; - * } - * }
+ * + * @InitDef + * public static void beforeInit(CommandBuildHelper helper) { + * // set the argument type to NumberRangeArgumentType + * helper., Integer>getArgument("number") + * .withArgType(new NumberRangeArgumentType<>(0, 10); + * } + * }} * *

Defining Sub-Commands

*

@@ -214,19 +223,19 @@ ArgumentBuilder arg(@NotNull String name) { * public Integer numberRange; * * @InitDef - * public static void beforeInit(CommandBuildHelper cmdBuildHelper) { + * public static void beforeInit(CommandBuildHelper helper) { * // set the argument type to NumberRangeArgumentType - * cmdBuildHelper., Integer>getArgument("numberRange") + * helper., Integer>getArgument("numberRange") * .withArgType(new NumberRangeArgumentType<>(0, 10); * } * } * } - * @param cmdBuildHelper A helper object that contains the command being initialized and the list of argument builders that may + * @param helper A helper object that contains the command being initialized and the list of argument builders that may * be altered. */ @InitDef - public static void beforeInit(@NotNull CommandBuildHelper cmdBuildHelper) {} + public static void beforeInit(@NotNull CommandBuildHelper helper) {} /** * This method is called after the Command is initialized. This is after the Arguments are instantiated and added From 6e47087d4a40790cafe70833f7339b9687e00c56 Mon Sep 17 00:00:00 2001 From: darvil82 Date: Tue, 2 Jan 2024 23:26:41 +0100 Subject: [PATCH 17/18] update version --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 8390a2c3..dd8e31aa 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,7 +4,7 @@ plugins { } group = "com.darvil" -version = "0.2.1" +version = "0.3.0" description = "Command line argument parser" dependencies { From 5ff4b9f14c193a78fc2bee789d6d3323396426f6 Mon Sep 17 00:00:00 2001 From: darvil82 Date: Wed, 3 Jan 2024 00:21:18 +0100 Subject: [PATCH 18/18] update readme --- README.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6939e316..81cd81be 100644 --- a/README.md +++ b/README.md @@ -81,4 +81,28 @@ The package is currently available on Repsy and GitHub Packages. ``` > [!NOTE] > The `+` symbol is a wildcard that will automatically use the latest version of the package. -> You can also specify a specific version (e.g. `0.1.0`). \ No newline at end of file +> You can also specify a specific version (e.g. `0.1.0`). + + + +## FAQ + +* ### Your logo has plenty of imperfections, please fix it. + + The logo couldn't be simpler. I made it in five minutes in Figma. I am a terrible designer. + Also nothing is perfect. Heck, we are talking about software here, where bugs are + the norm, so, I think it's fine. + + Also that isn't a question. + +* ### Why the name "Lanat"? + + I had a tough time finding a name for this project. I wanted something short, easy to remember, + and that sounded good. It had to be related to the project in some way. + Sadly most names I came up with were already taken... Anyway, so Lanat is actually an acronym for + **L**iterally **A**ll **N**ames **A**re **T**aken. + Yeah, I'm good at naming things. + + * #### How is "Lanat" related to the project? + + It's not. \ No newline at end of file