IGNITE-19949 Fix dynamic completer for same options (#3644)
Now you can define --option for multiple commands, and they won't be conflicting.
diff --git a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/DynamicCompleterRegistry.java b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/DynamicCompleterRegistry.java
index 12f2dc1..3622a61 100644
--- a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/DynamicCompleterRegistry.java
+++ b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/DynamicCompleterRegistry.java
@@ -27,6 +27,7 @@
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
+import org.jetbrains.annotations.Nullable;
/**
* Registry that holds all available dynamic completers.
@@ -115,11 +116,7 @@
String lastNotEmptyWord = findLastNotEmptyWord(words);
String preLastNotEmptyWord = findLastNotEmptyWordBeforeWordFromEnd(words, lastNotEmptyWord);
- if (cursorWord.equals(lastNotEmptyWord)) {
- if (exclusiveDisableOptions.contains(lastNotEmptyWord) || exclusiveDisableOptions.contains(preLastNotEmptyWord)) {
- return false;
- }
- } else if (exclusiveDisableOptions.contains(lastNotEmptyWord)) {
+ if (shouldBeDisabled(preLastNotEmptyWord, lastNotEmptyWord, cursorWord)) {
return false;
}
@@ -154,5 +151,36 @@
return factory.getDynamicCompleter(words);
}
}
+
+ private boolean shouldBeDisabled(String preLastNotEmptyWord, String lastNotEmptyWord, String cursorWord) {
+ boolean enableOverridesDisable = intersect(conf.enableOptions(), exclusiveDisableOptions);
+ if (enableOverridesDisable) {
+ return false;
+ }
+
+ if (cursorWord.equals(lastNotEmptyWord)) {
+ if (exclusiveDisableOptions.contains(lastNotEmptyWord) || exclusiveDisableOptions.contains(preLastNotEmptyWord)) {
+ return true;
+ }
+ } else if (exclusiveDisableOptions.contains(lastNotEmptyWord)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean intersect(@Nullable Set<String> a, @Nullable Set<String> b) {
+ if (a == null || b == null) {
+ return false;
+ }
+
+ for (String s : a) {
+ if (b.contains(s)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
}
}
diff --git a/modules/cli/src/test/java/org/apache/ignite/internal/cli/core/repl/completer/DynamicCompleterRegistryTest.java b/modules/cli/src/test/java/org/apache/ignite/internal/cli/core/repl/completer/DynamicCompleterRegistryTest.java
index 26ab52e..3acced6 100644
--- a/modules/cli/src/test/java/org/apache/ignite/internal/cli/core/repl/completer/DynamicCompleterRegistryTest.java
+++ b/modules/cli/src/test/java/org/apache/ignite/internal/cli/core/repl/completer/DynamicCompleterRegistryTest.java
@@ -81,10 +81,13 @@
registry.register(CompleterConf.forCommand("command2"), words -> completer3);
// When find completers for "command1"
- List<DynamicCompleter> completers = registry.findCompleters(words("command1", "subcommand1"));
+ List<DynamicCompleter> completers1 = registry.findCompleters(words("command1", "subcommand1"));
// Then
- assertThat(completers, containsInAnyOrder(completer1, completer2));
+ assertThat(completers1, containsInAnyOrder(completer1, completer2));
+ // And
+ List<DynamicCompleter> completers2 = registry.findCompleters(words("command2"));
+ assertThat(completers2, contains(completer3));
}
@Test
@@ -342,4 +345,57 @@
// Then completer is not returned
assertThat(completersWithPositional, is(empty()));
}
+
+ @Test
+ void sameOptionDifferentCompleters() {
+ // Given
+ registry.register(
+ CompleterConf.builder()
+ .command("command", "subcommand1")
+ .enableOptions("--to")
+ .exclusiveEnableOptions().build(),
+ words -> completer1
+ );
+
+ registry.register(
+ CompleterConf.builder()
+ .command("command", "subcommand2")
+ .enableOptions("--to")
+ .exclusiveEnableOptions().build(),
+ words -> completer2);
+
+ // Then
+ assertThat(registry.findCompleters(words("command", "subcommand1", "--to")), containsInAnyOrder(completer1));
+ // And
+ assertThat(registry.findCompleters(words("command", "subcommand2", "--to")), containsInAnyOrder(completer2));
+ }
+
+ @Test
+ void positionParameterIsNotCollapsedWithOptions() {
+ registry.register(
+ CompleterConf.builder()
+ .enableOptions(Options.NODE_NAME)
+ .exclusiveEnableOptions().build(),
+ words -> completer1
+ );
+
+ registry.register(
+ CompleterConf.builder()
+ .command("cluster", "config", "show")
+ .command("cluster", "config", "update")
+ .singlePositionalParameter().build(),
+ words -> completer2
+ );
+
+ // Then
+ assertThat(
+ registry.findCompleters(words("cluster", "config", "update", Options.NODE_NAME.fullName(), "")),
+ hasSize(1)
+ );
+ // And
+ assertThat(
+ registry.findCompleters(words("cluster", "config", "update", "")),
+ hasSize(1)
+ );
+ }
}