Skip to content

Fix alias usage in help command #459

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
@ShellComponent
public class AliasCommands {

@ShellMethod(key = { "alias anno main1", "alias anno main2" }, group = "Alias Commands")
private final static String DESCRIPTION = "main1 with main2 as alias";

@ShellMethod(key = { "alias anno main1", "alias anno main2" }, group = "Alias Commands", value = DESCRIPTION)
public String annoMain1() {
return "Hello annoMain1";
}
Expand All @@ -33,6 +35,7 @@ public CommandRegistration regMain1() {
return CommandRegistration.builder()
.command("alias", "reg", "main1")
.group("Alias Commands")
.description(DESCRIPTION)
.withAlias()
.command("alias", "reg", "main2")
.group("Alias Commands")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,15 @@
class CommandInfoModel {

private String name;
private List<String> aliases;
private String description;
private List<CommandParameterInfoModel> parameters;
private CommandAvailabilityInfoModel availability;

CommandInfoModel(String name, String description, List<CommandParameterInfoModel> parameters,
CommandInfoModel(String name, List<String> aliases, String description, List<CommandParameterInfoModel> parameters,
CommandAvailabilityInfoModel availability) {
this.name = name;
this.aliases = aliases;
this.description = description;
this.parameters = parameters;
this.availability = availability;
Expand Down Expand Up @@ -68,6 +70,9 @@ static CommandInfoModel of(String name, CommandRegistration registration) {
})
.collect(Collectors.toList());

List<String> aliases = registration.getAliases().stream().map(ca -> ca.getCommand())
.collect(Collectors.toList());

String description = registration.getDescription();
boolean available = true;
String availReason = "";
Expand All @@ -77,7 +82,7 @@ static CommandInfoModel of(String name, CommandRegistration registration) {
availReason = a.getReason();
}
CommandAvailabilityInfoModel availModel = CommandAvailabilityInfoModel.of(available, availReason);
return new CommandInfoModel(name, description, parameters, availModel);
return new CommandInfoModel(name, aliases, description, parameters, availModel);
}

private static String commandOptionType(CommandOption o) {
Expand All @@ -93,6 +98,10 @@ public String getName() {
return name;
}

public List<String> getAliases() {
return this.aliases;
}

public String getDescription() {
return description;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package org.springframework.shell.standard.commands;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
Expand Down Expand Up @@ -54,14 +55,18 @@ class GroupsInfoModel {
* @return a groups info model
*/
static GroupsInfoModel of(boolean showGroups, Map<String, CommandRegistration> registrations) {
// throw away registrations aliases as those are then handled in a model
// collect commands into groups with sorting
SortedMap<String, Map<String, CommandRegistration>> commandsByGroupAndName = registrations.entrySet().stream()
HashSet<CommandRegistration> regsWithoutAliases = new HashSet<>(registrations.values());
SortedMap<String, Map<String, CommandRegistration>> commandsByGroupAndName = regsWithoutAliases.stream()
.collect(Collectors.toMap(r -> r.getCommand(), r -> r)).entrySet().stream()
.collect(Collectors.groupingBy(
e -> StringUtils.hasText(e.getValue().getGroup()) ? e.getValue().getGroup() : "Default",
TreeMap::new,
Collectors.toMap(Entry::getKey, Entry::getValue)
));


// build model
List<GroupCommandInfoModel> gcims = commandsByGroupAndName.entrySet().stream()
.map(e -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ availability(availability) ::= <<
<endif>
>>

// ALIASES
aliases(aliases) ::= <<
<if(aliases)>
<("ALSO KNOWN AS"); format="style-highlight">
<(aliases); separator=", ">
<endif>
>>

// main
main(model) ::= <<
<name(model.name, model.description)>
Expand All @@ -74,4 +82,5 @@ main(model) ::= <<

<options(model.parameters)>
<availability(model.availability)>
<aliases(model.aliases)>
>>
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ availabilityDesc(hasUnavailableCommands) ::= <<
<endif>
>>

commandName(command) ::= <%
<[command.name, command.aliases]; format="style-highlight", separator=", ">
%>

command(command) ::= <<
<availability(command.availability)><(command.name); format="style-highlight"><(":"); format="style-highlight"> <command.description>
<availability(command.availability)><commandName(command); format="style-highlight"><(":"); format="style-highlight"> <command.description>

>>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.shell.standard.commands;

import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class CommandAvailabilityInfoModelTests {

@Test
void hasDefaults() {
CommandAvailabilityInfoModel caim = CommandAvailabilityInfoModel.of(true, null);
assertThat(caim.getAvailable()).isTrue();
assertThat(caim.getReason()).isNull();

caim = CommandAvailabilityInfoModel.of(false, "fakereason");
assertThat(caim.getAvailable()).isFalse();
assertThat(caim.getReason()).isEqualTo("fakereason");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* Copyright 2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.shell.standard.commands;

import org.junit.jupiter.api.Test;

import org.springframework.shell.command.CommandRegistration;

import static org.assertj.core.api.Assertions.assertThat;

public class CommandInfoModelTests {

@Test
void hasGivenName() {
CommandRegistration r1 = CommandRegistration.builder()
.command("main1")
.withTarget()
.consumer(ctx -> {})
.and()
.build();
CommandInfoModel cim = CommandInfoModel.of("main1", r1);
assertThat(cim.getName()).isEqualTo("main1");
}

@Test
void hasGivenDescription() {
CommandRegistration r1 = CommandRegistration.builder()
.command("main1")
.description("desc1")
.withTarget()
.consumer(ctx -> {})
.and()
.build();
CommandInfoModel cim = CommandInfoModel.of("main1", r1);
assertThat(cim.getDescription()).isEqualTo("desc1");
}

@Test
void hasNoParameters() {
CommandRegistration r1 = CommandRegistration.builder()
.command("main1")
.withTarget()
.consumer(ctx -> {})
.and()
.build();
CommandInfoModel cim = CommandInfoModel.of("main1", r1);
assertThat(cim.getParameters()).isEmpty();
}

@Test
void hasExpectedDefaultAvailability() {
CommandRegistration r1 = CommandRegistration.builder()
.command("main1")
.withTarget()
.consumer(ctx -> {})
.and()
.build();
CommandInfoModel cim = CommandInfoModel.of("main1", r1);
assertThat(cim.getAvailability()).isNotNull();
assertThat(cim.getAvailability().getAvailable()).isTrue();
assertThat(cim.getAvailability().getReason()).isNull();
}

@Test
void hasNoAliases() {
CommandRegistration r1 = CommandRegistration.builder()
.command("main1")
.withTarget()
.consumer(ctx -> {})
.and()
.build();
CommandInfoModel cim = CommandInfoModel.of("main1", r1);
assertThat(cim.getAliases()).isEmpty();
}

@Test
void hasAliases() {
CommandRegistration r1 = CommandRegistration.builder()
.command("main1")
.withAlias()
.command("alias1")
.and()
.withTarget()
.consumer(ctx -> {})
.and()
.build();
CommandInfoModel cim = CommandInfoModel.of("main1", r1);
assertThat(cim.getAliases()).containsExactly("alias1");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright 2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.shell.standard.commands;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import org.springframework.shell.command.CommandCatalog;
import org.springframework.shell.command.CommandRegistration;

import static org.assertj.core.api.Assertions.assertThat;

public class GroupsInfoModelTests {

private CommandCatalog commandCatalog;

@BeforeEach
void setup() {
this.commandCatalog = CommandCatalog.of();
}

@Test
void showGroupsIsSet() {
GroupsInfoModel gim = buildGIM(true);
assertThat(gim.getShowGroups()).isTrue();

gim = buildGIM(false);
assertThat(gim.getShowGroups()).isFalse();
}

@Test
void simpleCommandsAreSeparated() {
CommandRegistration r1 = CommandRegistration.builder()
.command("main1")
.withTarget()
.consumer(ctx -> {})
.and()
.build();
CommandRegistration r2 = CommandRegistration.builder()
.command("main2")
.withTarget()
.consumer(ctx -> {})
.and()
.build();
this.commandCatalog.register(r1, r2);
GroupsInfoModel gim = buildGIM();

assertThat(gim.getCommands()).hasSize(2);
assertThat(gim.getGroups()).hasSize(1);
}

@Test
void aliasNotAddedToTopModel() {
CommandRegistration r1 = CommandRegistration.builder()
.command("main1")
.withAlias()
.command("alias1")
.and()
.withTarget()
.consumer(ctx -> {})
.and()
.build();
this.commandCatalog.register(r1);
GroupsInfoModel gim = buildGIM();

assertThat(gim.getCommands()).hasSize(1);
}

private GroupsInfoModel buildGIM(boolean showGroups) {
return GroupsInfoModel.of(showGroups, this.commandCatalog.getRegistrations());
}

private GroupsInfoModel buildGIM() {
return buildGIM(true);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
AVAILABLE COMMANDS

Default
1st-command: A rather extensive description of some command.
yet-another-command: The second command. This one is known under several aliases as well.
third-command: The last command.
second-command: The second command. This one is known under several aliases as well.
first-command: A rather extensive description of some command.
second-command, yet-another-command: The second command. This one is known under several aliases as well.
first-command, 1st-command: A rather extensive description of some command.

Example Group
second-group-command: The second command in a separate group.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
AVAILABLE COMMANDS

1st-command: A rather extensive description of some command.
yet-another-command: The second command. This one is known under several aliases as well.
third-command: The last command.
second-command: The second command. This one is known under several aliases as well.
first-command: A rather extensive description of some command.
second-command, yet-another-command: The second command. This one is known under several aliases as well.
first-command, 1st-command: A rather extensive description of some command.
second-group-command: The second command in a separate group.
first-group-command: The first command in a separate group.