Mercurial > hg > thermostat-ng > agent
changeset 2428:88f534ba35ba
Add tab completions for parent command options to subcommands
Reviewed-by: jerboaa
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-August/020646.html
author | Andrew Azores <aazores@redhat.com> |
---|---|
date | Wed, 24 Aug 2016 08:57:17 -0400 |
parents | bc83ef2d7047 |
children | 01d03f3c18cd |
files | launcher/src/main/java/com/redhat/thermostat/launcher/internal/TabCompletion.java launcher/src/test/java/com/redhat/thermostat/launcher/internal/TabCompletionTest.java |
diffstat | 2 files changed, 83 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/TabCompletion.java Tue Aug 23 18:47:09 2016 +0200 +++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/TabCompletion.java Wed Aug 24 08:57:17 2016 -0400 @@ -67,17 +67,21 @@ private TreeCompleter treeCompleter; private Map<String, TreeCompleter.Node> commandMap; + private Map<TreeCompleter.Node, Set<TreeCompleter.Node>> subcommandMap; public TabCompletion() { - this(new TreeCompleter(), new HashMap<String, TreeCompleter.Node>()); + this(new TreeCompleter(), new HashMap<String, TreeCompleter.Node>(), + new HashMap<TreeCompleter.Node, Set<TreeCompleter.Node>>()); } /* * Testing only */ - TabCompletion(TreeCompleter treeCompleter, Map<String, TreeCompleter.Node> commandMap) { + TabCompletion(TreeCompleter treeCompleter, Map<String, TreeCompleter.Node> commandMap, + Map<TreeCompleter.Node, Set<TreeCompleter.Node>> subcommandMap) { this.treeCompleter = treeCompleter; this.commandMap = commandMap; + this.subcommandMap = subcommandMap; treeCompleter.setAlphabeticalCompletions(true); } @@ -160,6 +164,9 @@ } private void addSubCommandCompletionsIfRequired(TreeCompleter.Node commandNode, CompleterService service) { + for (TreeCompleter.Node subcommand : getSubcommands(commandNode)) { + addTopLevelCommandOptionCompletions(subcommand, service); + } Map<String, Map<CliCommandOption, ? extends TabCompleter>> subcommandCompleters = service.getSubcommandCompleters(); if (subcommandCompleters == null || subcommandCompleters.isEmpty()) { return; @@ -175,11 +182,17 @@ TreeCompleter.Node completionNode = new TreeCompleter.Node(subcommand + " completer", completer); completionNode.setRestartNode(commandNode); addNodeByOption(subcommandNode, cliCommandOption, completionNode); - addTopLevelCommandOptionCompletions(subcommandNode, service); } } } + private Set<TreeCompleter.Node> getSubcommands(TreeCompleter.Node commandNode) { + if (!subcommandMap.containsKey(commandNode)) { + return Collections.emptySet(); + } + return subcommandMap.get(commandNode); + } + public void removeCompleterService(CompleterService service) { for (String commandName : getCommandsForService(service)) { TreeCompleter.Node command = commandMap.get(commandName); @@ -213,6 +226,9 @@ } private void removeSubCommandCompletionsIfRequired(TreeCompleter.Node commandNode, CompleterService service) { + for (TreeCompleter.Node subcommand : getSubcommands(commandNode)) { + removeTopLevelCommandOptionCompletions(subcommand, service); + } Map<String, Map<CliCommandOption, ? extends TabCompleter>> subcommandCompleters = service.getSubcommandCompleters(); if (subcommandCompleters == null || subcommandCompleters.isEmpty()) { return; @@ -244,7 +260,7 @@ String commandName = info.getName(); TreeCompleter.Node command = getCommandByName(commandName); - setupSubcommandCompletion(command, info.getSubcommands()); + setupSubcommandCompletion(command, info); for (Option option : (Collection<Option>) info.getOptions().getOptions()) { setupDefaultCompletion(command, option); @@ -257,16 +273,21 @@ } } - private void setupSubcommandCompletion(TreeCompleter.Node commandNode, List<PluginConfiguration.Subcommand> subcommands) { + private void setupSubcommandCompletion(TreeCompleter.Node commandNode, CommandInfo commandInfo) { + List<PluginConfiguration.Subcommand> subcommands = commandInfo.getSubcommands(); for (PluginConfiguration.Subcommand subcommand : subcommands) { - TreeCompleter.Node node = createStringNode(subcommand.getName()); - node.setRestartNode(commandNode); + TreeCompleter.Node subcommandNode = createStringNode(subcommand.getName()); + subcommandNode.setRestartNode(commandNode); + for (Option option : (Collection<Option>) commandInfo.getOptions().getOptions()) { + setupDefaultCompletion(subcommandNode, option); + } if (subcommand.getOptions() != null) { for (Option option : (Collection<Option>) subcommand.getOptions().getOptions()) { - setupDefaultCompletion(node, option); + setupDefaultCompletion(subcommandNode, option); } } - commandNode.addBranch(node); + commandNode.addBranch(subcommandNode); + registerSubcommand(commandNode, subcommandNode); } } @@ -284,6 +305,13 @@ } } + private void registerSubcommand(TreeCompleter.Node commandNode, TreeCompleter.Node subcommandNode) { + if (!subcommandMap.containsKey(commandNode)) { + subcommandMap.put(commandNode, new HashSet<TreeCompleter.Node>()); + } + subcommandMap.get(commandNode).add(subcommandNode); + } + private void addHelpOptionIfRequired(TreeCompleter.Node command) { if (HelpCommand.COMMAND_NAME.equals(command.getTag())) { return;
--- a/launcher/src/test/java/com/redhat/thermostat/launcher/internal/TabCompletionTest.java Tue Aug 23 18:47:09 2016 +0200 +++ b/launcher/src/test/java/com/redhat/thermostat/launcher/internal/TabCompletionTest.java Wed Aug 24 08:57:17 2016 -0400 @@ -46,6 +46,7 @@ import org.junit.Before; import org.junit.Test; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; @@ -72,13 +73,15 @@ private TabCompletion tabCompletion; private TreeCompleter treeCompleter; private Map<String, TreeCompleter.Node> commandMap; + private Map<TreeCompleter.Node, Set<TreeCompleter.Node>> subcommandMap; @Before @SuppressWarnings("unchecked") public void setup() { treeCompleter = mock(TreeCompleter.class); commandMap = new HashMap<>(); - tabCompletion = new TabCompletion(treeCompleter, commandMap); + subcommandMap = new HashMap<>(); + tabCompletion = new TabCompletion(treeCompleter, commandMap, subcommandMap); } @Test @@ -300,4 +303,46 @@ verify(treeCompleter, times(2)).addBranch(isA(TreeCompleter.Node.class)); } + @Test + public void testSubcommandsReceiveParentOptionCompletions() { + Options parentOptions = new Options(); + parentOptions.addOption("p", "parent", true, "parent option"); + + Options subcommandOptions = new Options(); + subcommandOptions.addOption("s", "subcommand", true, "subcommand option"); + + PluginConfiguration.Subcommand subcommand = mock(PluginConfiguration.Subcommand.class); + when(subcommand.getName()).thenReturn("sub"); + when(subcommand.getDescription()).thenReturn("sub desc"); + when(subcommand.getOptions()).thenReturn(subcommandOptions); + + CommandInfo parent = mock(CommandInfo.class); + when(parent.getName()).thenReturn("parent"); + when(parent.getBundles()).thenReturn(Collections.<BundleInformation>emptyList()); + when(parent.getDescription()).thenReturn("parent desc"); + when(parent.getSubcommands()).thenReturn(Collections.singletonList(subcommand)); + when(parent.getEnvironments()).thenReturn(EnumSet.of(Environment.CLI, Environment.SHELL)); + when(parent.getOptions()).thenReturn(parentOptions); + + CommandInfoSource infoSource = mock(CommandInfoSource.class); + when(infoSource.getCommandInfos()).thenReturn(Collections.singletonList(parent)); + when(infoSource.getCommandInfo(parent.getName())).thenReturn(parent); + + tabCompletion.setupTabCompletion(infoSource); + + assertThat(commandMap.keySet(), is(equalTo(Collections.singleton(parent.getName())))); + assertThat(subcommandMap.size(), is(1)); + TreeCompleter.Node parentNode = new ArrayList<>(subcommandMap.keySet()).get(0); + assertThat(parentNode.getTag(), is("parent")); + TreeCompleter.Node subcommandNode = new ArrayList<>(new ArrayList<>(subcommandMap.values()).get(0)).get(0); + assertThat(subcommandNode.getTag(), is("sub")); + + List<TreeCompleter.Node> subcommandChildren = subcommandNode.getBranches(); + HashSet<String> childTags = new HashSet<>(); + for (TreeCompleter.Node node : subcommandChildren) { + childTags.add(node.getTag()); + } + assertThat(childTags, is(equalTo(new HashSet<>(Arrays.asList("-s", "--subcommand", "-p", "--parent"))))); + } + }