Skip to content

Commit

Permalink
Merge pull request #19 from rundeck/enh/handler
Browse files Browse the repository at this point in the history
Update CommandInvoker, easier to implement with defaults
  • Loading branch information
gschueler authored Mar 27, 2020
2 parents 9a9d7a8 + cac17b1 commit 0be0034
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,6 @@ class Toolbelt {
return false
}

@Override
boolean isDefault() {
return false
}

@Override
boolean run(final String[] args) throws CommandRunFailure, InputError {
Map<String, Object> params = [:]
Expand Down
62 changes: 32 additions & 30 deletions toolbelt/src/main/java/org/rundeck/toolbelt/ToolBelt.java
Original file line number Diff line number Diff line change
Expand Up @@ -403,11 +403,6 @@ public boolean isSolo() {
return false;
}

@Override
public boolean isDefault() {
return false;
}

public CommandSet(final CommandSet commandSet) {
this.name = commandSet.name;
this.commands = new HashMap<>(commandSet.commands);
Expand Down Expand Up @@ -678,14 +673,6 @@ public static List<String> tail(final List<String> args) {
}

private void introspect(final Object instance) {
if(instance instanceof CommandInvoker){
CommandInvoker cmd=(CommandInvoker)instance;
commands.commands.put(cmd.getName(), cmd);
if(cmd.getSynonyms()!=null && cmd.getSynonyms().size()>0){
cmd.getSynonyms().forEach(synonym -> commands.commandSynonyms.put(synonym, cmd));
}
return;
}
introspect(commands, instance);
}

Expand Down Expand Up @@ -772,6 +759,14 @@ public InvalidPath(final String message) {
}

private void addCommandForParent(CommandSet parent, final Object instance) {
if(instance instanceof CommandInvoker){
CommandInvoker cmd=(CommandInvoker)instance;
parent.commands.put(cmd.getName(), cmd);
if(cmd.getSynonyms()!=null && cmd.getSynonyms().size()>0){
cmd.getSynonyms().forEach(synonym -> parent.commandSynonyms.put(synonym, cmd));
}
return;
}
HashMap<String, CommandInvoker> subCommands = new HashMap<>();
HashMap<String, CommandInvoker> subSynonyms = new HashMap<>();
//look for methods
Expand All @@ -793,13 +788,14 @@ private void addCommandForParent(CommandSet parent, final Object instance) {
isSub = true;
}

boolean isHidden = false;
boolean isHidden = null != annotation1 && annotation1.isHidden();
Hidden annotation2 = aClass.getAnnotation(Hidden.class);
if (null != annotation2) {
isHidden = true;
}
Method[] methods = aClass.getMethods();
String defInvoke = null;

Method[] methods = aClass.getMethods();
for (Method method : methods) {
Command annotation = method.getAnnotation(Command.class);
if (annotation != null) {
Expand Down Expand Up @@ -948,32 +944,43 @@ public CommandOutput defaultOutput() {
}

public static interface CommandInvoker {
String getName();

String getDescription();
default String getName(){
return this.getClass().getSimpleName().toLowerCase();
}

boolean isSolo();
default String getDescription(){
return null;
}

boolean isDefault();
default boolean isSolo(){
return false;
}

boolean isHidden();
default boolean isHidden(){
return false;
}

Set<String> getSynonyms();
default Set<String> getSynonyms(){
return null;
}

boolean run(String[] args) throws CommandRunFailure;

void getHelp();
default void getHelp(){

}
}

private static class MethodInvoker implements CommandInvoker {
private static class MethodInvoker
implements CommandInvoker
{
private String name;
private Set<String> synonyms;
Method method;
Object instance;
private String description;
private boolean solo;
private boolean hidden;
private boolean isdefault;
CommandContext context;

MethodInvoker(
Expand Down Expand Up @@ -1105,11 +1112,6 @@ public boolean isSolo() {
return solo;
}

@Override
public boolean isDefault() {
return isdefault;
}

@Override
public boolean isHidden() {
return hidden;
Expand Down
120 changes: 120 additions & 0 deletions toolbelt/src/test/groovy/org/rundeck/toolbelt/ToolBeltSpec.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -488,4 +488,124 @@ class ToolBeltSpec extends Specification {
1 * myEh.handleError({ it instanceof MyError }, _) >> true

}

static class TestCH implements ToolBelt.CommandInvoker {
String[] sawArgs
boolean result

@Override
boolean run(final String[] args) {
this.sawArgs = args
return result
}
String description;
boolean helped

void getHelp() {
helped = true
}
}

def "invoke handler handles all args"() {
given:
def sut = new TestCH()
sut.result = expect

def output = new TestOutput()
def tool = ToolBelt.belt('test').
add(sut).
commandOutput(output).
commandInput(new SimpleCommandInput()).
buckle()
when:
def result = tool.runMain((['testch'] + args) as String[], false)

then:
output.output == []
result == expect
sut.sawArgs == args

where:
expect | args
true | []
true | ['asdf']
false | []
false | ['asdf']
}

@SubCommand(path = ['a', 'b'], descriptions = ['xyz', 'zyd'])
static class TestCH2 extends TestCH{

}
def "invoke handler subcommand handles all args"() {
given:
def sut = new TestCH2()
sut.result = expect

def output = new TestOutput()
def tool = ToolBelt.belt('test').
add(sut).
commandOutput(output).
commandInput(new SimpleCommandInput()).
buckle()
when:
def result = tool.runMain((['a', 'b', 'testch2'] + args) as String[], false)

then:
output.output == []
result == expect
sut.sawArgs == args

where:
expect | args
true | []
true | ['asdf']
false | []
false | ['asdf']
}

def "invoke handler description"() {
given:
def sut = new TestCH()
sut.result = true
sut.description = expect

def output = new TestOutput()
def tool = ToolBelt.belt('test').
add(sut).
commandOutput(output).
defaultHelpCommands().
commandInput(new SimpleCommandInput()).
buckle()
when:
def result = tool.runMain((['help']) as String[], false)

then:
output.output.contains('Available commands:\n')
output.output.contains(' testch - ' + expect)

where:
value | expect
null | ''
'asdf' | 'asdf'
}

def "invoke handler help"() {
given:
def sut = new TestCH()
sut.result = true

def output = new TestOutput()
def tool = ToolBelt.belt('test').
add(sut).
commandOutput(output).
defaultHelpCommands().
commandInput(new SimpleCommandInput()).
buckle()
when:
def result = tool.runMain((['testch', 'help']) as String[], false)

then:
sut.helped
}
}

0 comments on commit 0be0034

Please sign in to comment.