diff --git a/build.gradle.kts b/build.gradle.kts
index bd593c21..fba61275 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -4,7 +4,7 @@ plugins {
}
group = "com.darvil"
-version = "0.2.0"
+version = "0.2.1"
description = "Command line argument parser"
dependencies {
diff --git a/src/main/java/lanat/Argument.java b/src/main/java/lanat/Argument.java
index 99a9e5af..9f157e5c 100644
--- a/src/main/java/lanat/Argument.java
+++ b/src/main/java/lanat/Argument.java
@@ -406,11 +406,12 @@ public void setRepresentationColor(@NotNull Color color) {
/* no, | is not a typo. We don't want the OR operator to short-circuit, we want all of them to be evaluated
* because the methods have side effects (they add errors to the parser) */
- TInner returnValue = (finalValue == null | !this.finishParsing$checkExclusivity() | !this.finishParsing$checkUsageCount())
+ TInner returnValue = (finalValue == null | !this.finishParsing$checkGroupRestrictions() | !this.finishParsing$checkUsageCount())
? defaultValue
: finalValue;
- if (this.parentGroup != null) this.parentGroup.setArgUsed();
+ if (this.parentGroup != null && this.getUsageCount() >= 1)
+ this.parentGroup.setArgUsed();
// if the argument type has a value defined (even if it wasn't used), use that. Otherwise, use the default value
return returnValue;
@@ -442,20 +443,19 @@ public void setRepresentationColor(@NotNull Color color) {
}
/**
- * Checks if the argument is part of an exclusive group, and if so, checks if there is any violation of exclusivity
+ * Checks if the argument is part of a restricted group, and if so, checks if there is any violation of restrictions
* in the group hierarchy.
- *
- * @return {@code true} if there is no violation of exclusivity in the group hierarchy.
+ * @return {@code true} if there is no violation of restrictions in the group hierarchy.
*/
- private boolean finishParsing$checkExclusivity() {
- // check if the parent group of this argument is exclusive, and if so, check if any other argument in it has been used
+ private boolean finishParsing$checkGroupRestrictions() {
+ // check if the parent group of this argument is restricted, and if so, check if any other argument in it has been used
if (this.parentGroup == null || this.getUsageCount() == 0) return true;
- ArgumentGroup exclusivityResult = this.parentGroup.checkExclusivity(null);
- if (exclusivityResult == null) return true;
+ ArgumentGroup restrictionViolator = this.parentGroup.getRestrictionViolator(null);
+ if (restrictionViolator == null) return true;
- this.parentCommand.getParser().addError(new ParseErrors.MultipleArgsInExclusiveGroupUsedError(
- this.argType.getLastTokensIndicesPair(), exclusivityResult
+ this.parentCommand.getParser().addError(new ParseErrors.MultipleArgsInRestrictedGroupUsedError(
+ this.argType.getLastTokensIndicesPair(), restrictionViolator
));
return false;
}
diff --git a/src/main/java/lanat/ArgumentGroup.java b/src/main/java/lanat/ArgumentGroup.java
index 7faded90..8343600d 100644
--- a/src/main/java/lanat/ArgumentGroup.java
+++ b/src/main/java/lanat/ArgumentGroup.java
@@ -13,17 +13,17 @@
/**
*
Argument Group
*
- * Represents a group of arguments. This is used to group arguments together, and to set exclusivity between them.
- * When a group is exclusive, it means that only one argument in it can be used at a time.
+ * Represents a group of arguments. This is used to group arguments together, and to set a restriction between them.
+ * When a group is restricted, it means that only one argument in it can be used at a time.
*
* Groups can also be used to simply indicate arguments that are related to each other, and to set a description
* to this relation. This is useful for the help message representation.
*
- * Groups can be nested, meaning that a group can contain other groups. This is useful for setting exclusivity between
+ * Groups can be nested, meaning that a group can contain other groups. This is useful for setting restrictions between
* arguments that are in different groups. For example, given the following group tree:
*
* +-----------------------+
- * | Group 1 (exclusive) |
+ * | Group 1 (restricted) |
* |-----------------------|
* | Argument 1 |
* +-----------------------+
@@ -31,7 +31,7 @@
* +---------------------------+
* | |
* +---------------+ +-------------------------+
- * | Group 2 | | Group 3 (exclusive) |
+ * | Group 2 | | Group 3 (restricted) |
* |---------------| |-------------------------|
* | Argument 2.1 | | Argument 3.1 |
* | Argument 2.2 | | Argument 3.2 |
@@ -40,14 +40,14 @@
*
* -
* If {@code Argument 1} is used, then none of the arguments in the child groups can be used, because {@code Group 1}
- * is exclusive.
+ * is restricted.
*
* -
* If {@code Argument 3.1} is used, then none of the arguments in the rest of the tree can be used, because
- * both {@code Group 3} and its parent {@code Group 1} are exclusive.
+ * both {@code Group 3} and its parent {@code Group 1} are restricted.
*
* -
- * If {@code Argument 2.1} is used, {@code Argument 2.2} can still be used, because {@code Group 2} is not exclusive.
+ * If {@code Argument 2.1} is used, {@code Argument 2.2} can still be used, because {@code Group 2} is not restricted.
* No other arguments in the tree can be used though.
*
*
@@ -85,11 +85,11 @@ public class ArgumentGroup
* them.
*/
private final @NotNull List<@NotNull ArgumentGroup> subGroups = new ArrayList<>();
- private boolean isExclusive = false;
+ private boolean isRestricted = false;
/**
* When set to {@code true}, indicates that one argument in this group has been used. This is used when later
- * checking for exclusivity in the groups tree at {@link ArgumentGroup#checkExclusivity(ArgumentGroup)}
+ * checking for restrictions in the groups tree at {@link ArgumentGroup#getRestrictionViolator(ArgumentGroup)}
*/
private boolean argumentUsed = false;
@@ -184,42 +184,42 @@ public Command getParentCommand() {
}
/**
- * Sets this group to be exclusive, meaning that only one argument in it can be used at a time.
- * @see ArgumentGroup#isExclusive()
+ * Sets this group to be restricted, meaning that only one argument in it can be used at a time.
+ * @see ArgumentGroup#isRestricted()
*/
- public void setExclusive(boolean isExclusive) {
- this.isExclusive = isExclusive;
+ public void setRestricted(boolean isRestricted) {
+ this.isRestricted = isRestricted;
}
/**
- * Returns {@code true} if this group is exclusive.
- * @return {@code true} if this group is exclusive.
- * @see ArgumentGroup#setExclusive(boolean)
+ * Returns {@code true} if this group is restricted.
+ * @return {@code true} if this group is restricted.
+ * @see ArgumentGroup#setRestricted(boolean)
*/
- public boolean isExclusive() {
- return this.isExclusive;
+ public boolean isRestricted() {
+ return this.isRestricted;
}
/**
- * Checks if there is any violation of exclusivity in this group's tree, from this group to the root. This is done
+ * Checks if there is any violation of restrictions in this group's tree, from this group to the root. This is done
* by checking if this or any of the group's siblings have been used (except for the childCallee, which is the group
* that called this method). If none of them have been used, the parent group is checked, and so on.
*
* @param childCallee The group that called this method. This is used to avoid checking the group that called this
- * method, because it is the one that is being checked for exclusivity. This can be {@code null} if this is
+ * method, because it is the one that is being checked for restriction. This can be {@code null} if this is
* the first call to this method.
* @return The group that caused the violation, or {@code null} if there is no violation.
*/
- @Nullable ArgumentGroup checkExclusivity(@Nullable ArgumentGroup childCallee) {
+ @Nullable ArgumentGroup getRestrictionViolator(@Nullable ArgumentGroup childCallee) {
if (
- this.isExclusive && (
+ this.isRestricted && (
this.argumentUsed || this.subGroups.stream().filter(g -> g != childCallee).anyMatch(g -> g.argumentUsed)
)
)
return this;
if (this.parentGroup != null)
- return this.parentGroup.checkExclusivity(this);
+ return this.parentGroup.getRestrictionViolator(this);
return null;
}
@@ -234,7 +234,7 @@ public boolean isEmpty() {
/**
- * Marks that an argument in this group has been used. This is used to later check for exclusivity.
+ * Marks that an argument in this group has been used. This is used to later check for restrictions.
* This also marks the parent group as used, and so on until reaching the root of the groups tree, thus marking the
* path of the used argument.
*/
diff --git a/src/main/java/lanat/helpRepresentation/ArgumentGroupRepr.java b/src/main/java/lanat/helpRepresentation/ArgumentGroupRepr.java
index 6d965afd..d25c8d3d 100644
--- a/src/main/java/lanat/helpRepresentation/ArgumentGroupRepr.java
+++ b/src/main/java/lanat/helpRepresentation/ArgumentGroupRepr.java
@@ -32,7 +32,7 @@ private ArgumentGroupRepr() {}
return null;
final var name = new TextFormatter(group.getName() + ':').addFormat(FormatOption.BOLD);
- if (group.isExclusive())
+ if (group.isRestricted())
name.addFormat(FormatOption.UNDERLINE);
return '\n' + name.toString() + '\n' + HelpFormatter.indent(description, group);
@@ -62,7 +62,7 @@ private ArgumentGroupRepr() {}
if (description == null && argumentDescriptions.isEmpty())
return "";
- if (group.isExclusive())
+ if (group.isRestricted())
name.addFormat(FormatOption.UNDERLINE);
if (description != null)
@@ -92,8 +92,8 @@ public static String getRepresentation(@NotNull ArgumentGroup group) {
// its empty, nothing to append
if (group.isEmpty()) return "";
- // if this group isn't exclusive, we just want to append the arguments, basically
- if (group.isExclusive())
+ // if this group isn't restricted, we just want to append the arguments, basically
+ if (group.isRestricted())
buff.append('(');
final var arguments = Argument.sortByPriority(group.getArguments());
@@ -103,7 +103,7 @@ public static String getRepresentation(@NotNull ArgumentGroup group) {
buff.append(ArgumentRepr.getRepresentation(arg));
if (i < arguments.size() - 1) {
buff.append(' ');
- if (group.isExclusive())
+ if (group.isRestricted())
buff.append('|').append(' ');
}
}
@@ -112,7 +112,7 @@ public static String getRepresentation(@NotNull ArgumentGroup group) {
if (!arguments.isEmpty() && !groups.isEmpty()) {
buff.append(' ');
- if (group.isExclusive())
+ if (group.isRestricted())
buff.append("| ");
}
@@ -121,12 +121,12 @@ public static String getRepresentation(@NotNull ArgumentGroup group) {
buff.append(ArgumentGroupRepr.getRepresentation(grp)); // append the group's representation recursively
if (i < groups.size() - 1) {
buff.append(' ');
- if (grp.isExclusive())
+ if (grp.isRestricted())
buff.append('|').append(' ');
}
}
- if (group.isExclusive())
+ if (group.isRestricted())
buff.append(')');
return buff.toString();
diff --git a/src/main/java/lanat/parsing/errors/ParseErrors.java b/src/main/java/lanat/parsing/errors/ParseErrors.java
index d93329e5..adfaa0e6 100644
--- a/src/main/java/lanat/parsing/errors/ParseErrors.java
+++ b/src/main/java/lanat/parsing/errors/ParseErrors.java
@@ -152,11 +152,11 @@ public void handle(@NotNull ErrorFormattingContext fmt, @NotNull ParseErrorConte
}
/**
- * Error that occurs when multiple arguments in an exclusive group are used.
+ * Error that occurs when multiple arguments in a restricted group are used.
* @param indicesPair The indices of the tokens that caused the error. (start, end)
- * @param group The exclusive group that contains the arguments.
+ * @param group The restricted group that contains the arguments.
*/
- public record MultipleArgsInExclusiveGroupUsedError(
+ public record MultipleArgsInRestrictedGroupUsedError(
@NotNull Pair indicesPair,
@NotNull ArgumentGroup group
) implements Error.ParseError
@@ -164,7 +164,7 @@ public record MultipleArgsInExclusiveGroupUsedError(
@Override
public void handle(@NotNull ErrorFormattingContext fmt, @NotNull ParseErrorContext ctx) {
fmt
- .withContent("Multiple arguments in exclusive group '" + this.group.getName() + "' used.")
+ .withContent("Multiple arguments in restricted group '" + this.group.getName() + "' used.")
.highlight(this.indicesPair.first(), this.indicesPair.second(), false);
}
}
diff --git a/src/test/java/lanat/test/UnitTests.java b/src/test/java/lanat/test/UnitTests.java
index 0c1a1297..1da4470f 100644
--- a/src/test/java/lanat/test/UnitTests.java
+++ b/src/test/java/lanat/test/UnitTests.java
@@ -82,8 +82,8 @@ protected TestingParser setParser() {
this.addCommand(new Command("subCommand2") {{
this.setErrorCode(0b1000);
- this.addGroup(new ArgumentGroup("exclusive-group") {{
- this.setExclusive(true);
+ this.addGroup(new ArgumentGroup("restricted-group") {{
+ this.setRestricted(true);
this.addArgument(Argument.createOfBoolType("extra"));
this.addArgument(Argument.create(new IntegerArgumentType(), 'c').positional());
}});
diff --git a/src/test/java/lanat/test/exampleTests/CommandTemplateExample.java b/src/test/java/lanat/test/exampleTests/CommandTemplateExample.java
index 0e9b275e..980f6dc5 100644
--- a/src/test/java/lanat/test/exampleTests/CommandTemplateExample.java
+++ b/src/test/java/lanat/test/exampleTests/CommandTemplateExample.java
@@ -61,7 +61,7 @@ protected boolean checkFile(@NotNull File file) {
@InitDef
public static void afterInit(@NotNull Command cmd) {
cmd.addGroup(new ArgumentGroup("test-group") {{
- this.setExclusive(true);
+ this.setRestricted(true);
this.addArgument(cmd.getArgument("string"));
this.addArgument(cmd.getArgument("number"));
}});
diff --git a/src/test/java/lanat/test/units/TestArgumentGroups.java b/src/test/java/lanat/test/units/TestArgumentGroups.java
index 5b9b8ad8..8002fbb4 100644
--- a/src/test/java/lanat/test/units/TestArgumentGroups.java
+++ b/src/test/java/lanat/test/units/TestArgumentGroups.java
@@ -15,7 +15,7 @@ protected TestingParser setParser() {
final var parser = super.setParser();
parser.addGroup(new ArgumentGroup("group") {{
- this.setExclusive(true);
+ this.setRestricted(true);
this.addArgument(Argument.createOfBoolType("group-arg"));
this.addArgument(Argument.createOfBoolType("group-arg2"));
}});
@@ -24,8 +24,8 @@ protected TestingParser setParser() {
}
@Test
- @DisplayName("Test exclusive group")
- public void testExclusiveGroup() {
+ @DisplayName("Test restricted group")
+ public void testRestrictedGroup() {
var parsedArgs = this.parser.parseGetValues("--group-arg --group-arg2");
assertEquals(Boolean.TRUE, parsedArgs.get("group-arg").orElse(null));
assertEquals(Boolean.FALSE, parsedArgs.get("group-arg2").orElse(null)); // group-arg2 should not be present
diff --git a/src/test/java/lanat/test/units/TestTerminalOutput.java b/src/test/java/lanat/test/units/TestTerminalOutput.java
index e76e0af3..85289b8b 100644
--- a/src/test/java/lanat/test/units/TestTerminalOutput.java
+++ b/src/test/java/lanat/test/units/TestTerminalOutput.java
@@ -119,12 +119,12 @@ public void testIncorrectUsageCount() {
}
@Test
- @DisplayName("Test group exclusivity error")
- public void testGroupExclusivityError() {
+ @DisplayName("Test group restriction error")
+ public void testGroupRestrictionError() {
this.assertErrorOutput("foo subCommand2 --extra --c 5", """
ERROR
Testing foo subCommand2 --extra -> --c 5 <-
- Multiple arguments in exclusive group 'exclusive-group' used.""");
+ Multiple arguments in restricted group 'restricted-group' used.""");
}
@Test