From d60e4184b76e1199c1fdd671c97508291f1d3a03 Mon Sep 17 00:00:00 2001 From: NewbieOrange Date: Sat, 11 Sep 2021 13:50:34 +0800 Subject: [PATCH 1/3] [#1388] Fix subcommand aliases autocomplete regression --- src/main/java/picocli/AutoComplete.java | 2 +- src/test/java/picocli/AutoCompleteTest.java | 31 +++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/main/java/picocli/AutoComplete.java b/src/main/java/picocli/AutoComplete.java index 5c6b224dd..6c183c235 100644 --- a/src/main/java/picocli/AutoComplete.java +++ b/src/main/java/picocli/AutoComplete.java @@ -560,7 +560,7 @@ private static void generateFunctionCallsToArrContains(StringBuilder buff, int count = functionCalls.size(); CommandSpec spec = descriptor.commandLine.getCommandSpec(); String full = spec.qualifiedName(" "); - String withoutTopLevelCommand = full.substring(spec.root().name().length() + 1); + String withoutTopLevelCommand = full.substring(spec.root().name().length() + 1).replace(spec.name(), descriptor.commandName); functionCalls.add(format(" if CompWordsContainsArray \"${cmds%2$d[@]}\"; then %1$s; return $?; fi\n", descriptor.functionName, count)); buff.append( format(" local cmds%2$d=(%1$s)\n", withoutTopLevelCommand, count)); diff --git a/src/test/java/picocli/AutoCompleteTest.java b/src/test/java/picocli/AutoCompleteTest.java index 61e3a4085..46a618289 100644 --- a/src/test/java/picocli/AutoCompleteTest.java +++ b/src/test/java/picocli/AutoCompleteTest.java @@ -1896,4 +1896,35 @@ public void testIssue1352_SubcommandNameResourceBundle() throws FileNotFoundExce } } + @CommandLine.Command(name = "aliases", aliases = {"a"}) + static class Issue1388AliasesCommand {} + + @CommandLine.Command(name = "aliases-parent", subcommands = {Issue1388AliasesCommand.class}) + static class Issue1388AliasesParentCommand {} + + @Test + public void testIssue1388_AliasesCommand() throws FileNotFoundException { + File existingScript = new File("aliases-parent_completion"); + if (existingScript.exists()) { + assertTrue(existingScript.delete()); + } + try { + AutoComplete.main(Issue1388AliasesParentCommand.class.getName()); + + assertEquals("", systemErrRule.getLog()); + assertEquals("", systemOutRule.getLog()); + + assertTrue("Expected file '" + existingScript.getAbsolutePath() + "' to exist", + existingScript.exists()); + + Scanner scanner = new Scanner(existingScript); + scanner.useDelimiter("\\Z"); // end of file + String script = scanner.next(); + scanner.close(); + assertThat(script, containsString("local cmds0=(aliases)")); + assertThat(script, containsString("local cmds1=(a)")); + } finally { + existingScript.delete(); + } + } } From 06eddecef1c81994a5eed57926b89193521c1db1 Mon Sep 17 00:00:00 2001 From: NewbieOrange Date: Sat, 11 Sep 2021 14:46:05 +0800 Subject: [PATCH 2/3] [#1352] Fix subcommand resource bundle test regression --- src/main/java/picocli/CommandLine.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/picocli/CommandLine.java b/src/main/java/picocli/CommandLine.java index bdd5e6b9b..fa50525d8 100644 --- a/src/main/java/picocli/CommandLine.java +++ b/src/main/java/picocli/CommandLine.java @@ -6412,7 +6412,7 @@ public CommandSpec addSubcommand(String name, CommandSpec subcommand) { */ public CommandSpec addSubcommand(String name, CommandLine subCommandLine) { CommandSpec subSpec = subCommandLine.getCommandSpec(); - String actualName = validateSubcommandName(name, subSpec); + String actualName = interpolator.interpolateCommandName(validateSubcommandName(name, subSpec)); Tracer t = new Tracer(); if (t.isDebug()) {t.debug("Adding subcommand '%s' to '%s'%n", actualName, this.qualifiedName());} String previousName = commands.getCaseSensitiveKey(actualName); @@ -6422,7 +6422,7 @@ public CommandSpec addSubcommand(String name, CommandLine subCommandLine) { subSpec.parent(this); for (String alias : subSpec.aliases()) { if (t.isDebug()) {t.debug("Adding alias '%s' for '%s'%n", (parent == null ? "" : parent.qualifiedName() + " ") + alias, this.qualifiedName());} - previous = commands.put(alias, subCommandLine); + previous = commands.put(interpolator.interpolate(alias), subCommandLine); if (previous != null && previous != subCommandLine) { throw new DuplicateNameException("Alias '" + alias + "' for subcommand '" + actualName + "' is already used by another subcommand of '" + this.name() + "'"); } } subSpec.initCommandHierarchyWithResourceBundle(resourceBundleBaseName(), resourceBundle()); From b52b1c36711387351f630481d6b2ab9466966e38 Mon Sep 17 00:00:00 2001 From: NewbieOrange Date: Tue, 14 Sep 2021 00:37:05 +0800 Subject: [PATCH 3/3] Fix logical fault of possibly replacing other command names --- src/main/java/picocli/AutoComplete.java | 3 ++- src/main/java/picocli/CommandLine.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/picocli/AutoComplete.java b/src/main/java/picocli/AutoComplete.java index 6c183c235..a2d22703c 100644 --- a/src/main/java/picocli/AutoComplete.java +++ b/src/main/java/picocli/AutoComplete.java @@ -560,7 +560,8 @@ private static void generateFunctionCallsToArrContains(StringBuilder buff, int count = functionCalls.size(); CommandSpec spec = descriptor.commandLine.getCommandSpec(); String full = spec.qualifiedName(" "); - String withoutTopLevelCommand = full.substring(spec.root().name().length() + 1).replace(spec.name(), descriptor.commandName); + String withoutTopLevelCommand = full.substring(spec.root().name().length() + 1, + full.length() - spec.name().length()) + descriptor.commandName; functionCalls.add(format(" if CompWordsContainsArray \"${cmds%2$d[@]}\"; then %1$s; return $?; fi\n", descriptor.functionName, count)); buff.append( format(" local cmds%2$d=(%1$s)\n", withoutTopLevelCommand, count)); diff --git a/src/main/java/picocli/CommandLine.java b/src/main/java/picocli/CommandLine.java index fa50525d8..0f22b6499 100644 --- a/src/main/java/picocli/CommandLine.java +++ b/src/main/java/picocli/CommandLine.java @@ -6412,7 +6412,7 @@ public CommandSpec addSubcommand(String name, CommandSpec subcommand) { */ public CommandSpec addSubcommand(String name, CommandLine subCommandLine) { CommandSpec subSpec = subCommandLine.getCommandSpec(); - String actualName = interpolator.interpolateCommandName(validateSubcommandName(name, subSpec)); + String actualName = validateSubcommandName(interpolator.interpolateCommandName(name), subSpec); Tracer t = new Tracer(); if (t.isDebug()) {t.debug("Adding subcommand '%s' to '%s'%n", actualName, this.qualifiedName());} String previousName = commands.getCaseSensitiveKey(actualName);