Skip to content

Commit

Permalink
[#444] Bugfix: Usage help shows duplicate aliases if registered with …
Browse files Browse the repository at this point in the history
…same alias multiple times.
  • Loading branch information
remkop committed Aug 15, 2018
1 parent 427b195 commit b8f2fb2
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 8 deletions.
33 changes: 33 additions & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,38 @@
# picocli Release Notes

# <a name="3.6.0"></a> Picocli 3.6.0 (UNRELEASED)
The picocli community is pleased to announce picocli 3.6.0.

This is a bugfix release.

This is the thirty-nineth public release.
Picocli follows [semantic versioning](http://semver.org/).

## <a name="3.6.0"></a> Table of Contents
* [New and noteworthy](#3.6.0-new)
* [Promoted features](#3.6.0-promoted)
* [Fixed issues](#3.6.0-fixes)
* [Deprecations](#3.6.0-deprecated)
* [Potential breaking changes](#3.6.0-breaking-changes)

## <a name="3.6.0-new"></a> New and Noteworthy


## <a name="3.6.0-promoted"></a> Promoted Features
Promoted features are features that were incubating in previous versions of picocli but are now supported and subject to backwards compatibility.

No features have been promoted in this picocli release.

## <a name="3.6.0-fixes"></a> Fixed issues
- [#444] Bugfix: Usage help shows duplicate aliases if registered with same alias multiple times.

## <a name="3.6.0-deprecated"></a> Deprecations
No features were deprecated in this release.

## <a name="3.6.0-breaking-changes"></a> Potential breaking changes
This release has no breaking changes.


# <a name="3.5.2"></a> Picocli 3.5.2
The picocli community is pleased to announce picocli 3.5.2.

Expand Down
15 changes: 8 additions & 7 deletions src/main/java/picocli/CommandLine.java
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,7 @@ public CommandLine addSubcommand(String name, Object command) {
*/
public CommandLine addSubcommand(String name, Object command, String... aliases) {
CommandLine subcommandLine = toCommandLine(command, factory);
List<String> update = new ArrayList<String>(Arrays.asList(subcommandLine.getCommandSpec().aliases()));
update.addAll(Arrays.asList(aliases));
subcommandLine.getCommandSpec().aliases(update.toArray(new String[0]));
subcommandLine.getCommandSpec().aliases.addAll(Arrays.asList(aliases));
getCommandSpec().addSubcommand(name, subcommandLine);
CommandLine.Model.CommandReflection.initParentCommand(subcommandLine.getCommandSpec().userObject(), getCommandSpec().userObject());
return this;
Expand Down Expand Up @@ -3111,7 +3109,7 @@ public static class CommandSpec {
private CommandSpec parent;

private String name;
private String[] aliases = {};
private Set<String> aliases = new LinkedHashSet<String>();
private Boolean isHelpCommand;
private IVersionProvider versionProvider;
private String[] version;
Expand Down Expand Up @@ -3359,7 +3357,7 @@ public CommandSpec addMixin(String name, CommandSpec mixin) {

/** Returns the alias command names of this subcommand.
* @since 3.1 */
public String[] aliases() { return aliases.clone(); }
public String[] aliases() { return aliases.toArray(new String[0]); }

/** Returns the String to use as the program name in the synopsis line of the help message:
* this command's {@link #name() name}, preceded by the qualified name of the parent command, if any.
Expand Down Expand Up @@ -3410,7 +3408,10 @@ public String[] version() {
/** Sets the alternative names by which this subcommand is recognized on the command line.
* @return this CommandSpec for method chaining
* @since 3.1 */
public CommandSpec aliases(String... aliases) { this.aliases = aliases == null ? new String[0] : aliases.clone(); return this; }
public CommandSpec aliases(String... aliases) {
this.aliases = new LinkedHashSet<String>(Arrays.asList(aliases == null ? new String[0] : aliases));
return this;
}

/** Sets version information literals for this command, to print to the console when the user specifies an
* {@linkplain OptionSpec#versionHelp() option} to request version help. Only used if no {@link #versionProvider() versionProvider} is set.
Expand Down Expand Up @@ -7358,7 +7359,7 @@ private static String join(String[] names, int offset, int length, String separa
return result.toString();
}
private static String stringOf(char chr, int length) {
char[] buff = new char[length];
char[] buff = new char[length];
Arrays.fill(buff, chr);
return new String(buff);
}
Expand Down
16 changes: 15 additions & 1 deletion src/test/java/picocli/CommandLineTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2264,7 +2264,7 @@ public void run() {
}
}

@Command(name = "task", aliases = {"t"})
@Command(name = "task", aliases = {"t"}, description = "subcommand with alias")
static class SubCommandWithAlias implements Runnable {
boolean subWasExecuted;
public void run() {
Expand All @@ -2283,6 +2283,20 @@ public void testIssue443SubcommandWithAliasAnnotation() {
assertTrue("sub was executed", sub.subWasExecuted);
}

@Test
public void testIssue444SubcommandWithDuplicateAliases() {
Issue443TopLevelCommand top = new Issue443TopLevelCommand();
SubCommandWithAlias sub = new SubCommandWithAlias();
CommandLine cmd = new CommandLine(top).addSubcommand("task", sub, "t", "t");
Model.CommandSpec subSpec = cmd.getSubcommands().get("task").getCommandSpec();
String expected = String.format("" +
"Usage: cb [COMMAND]%n" +
"Commands:%n" +
" task, t subcommand with alias%n");
assertEquals(expected, cmd.getUsageMessage());
assertArrayEquals(new String[]{"t"}, subSpec.aliases());
}

public static <T> Set<T> setOf(T... elements) {
Set<T> result = new HashSet<T>();
for (T t : elements) { result.add(t); }
Expand Down

0 comments on commit b8f2fb2

Please sign in to comment.