Add better support for modified option names
- Longnames in a command option if modified via name modifier didn't provide enough backmapping info for command execution experience being accurate. - Add new getLongNamesModified() into CommandOption which is populated if name modifier is used. - Add more hints in CommandExecution for modified option names. - This should bring annotation, legacy annotation and programmatic commands up to date. - Backport #777 - Fixes #783
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2022 the original author or authors.
|
||||
* Copyright 2022-2023 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.
|
||||
@@ -148,8 +148,9 @@ public interface CommandContext {
|
||||
return results.results().stream()
|
||||
.filter(r -> {
|
||||
Stream<String> l = Arrays.asList(r.option().getLongNames()).stream();
|
||||
Stream<String> lm = Arrays.asList(r.option().getLongNamesModified()).stream();
|
||||
Stream<String> s = Arrays.asList(r.option().getShortNames()).stream().map(n -> Character.toString(n));
|
||||
return Stream.concat(l, s)
|
||||
return Stream.concat(Stream.concat(l, lm), s)
|
||||
.filter(o -> ObjectUtils.nullSafeEquals(o, name))
|
||||
.findFirst()
|
||||
.isPresent();
|
||||
|
||||
@@ -198,6 +198,11 @@ public interface CommandExecution {
|
||||
messageBuilder.setHeader(ArgumentHeaderMethodArgumentResolver.ARGUMENT_PREFIX + n, r.value());
|
||||
paramValues.put(n, r.value());
|
||||
}
|
||||
// need to provide backmapping for orinal names which were modified
|
||||
for (String n : r.option().getLongNamesModified()) {
|
||||
messageBuilder.setHeader(ArgumentHeaderMethodArgumentResolver.ARGUMENT_PREFIX + n, r.value());
|
||||
paramValues.put(n, r.value());
|
||||
}
|
||||
}
|
||||
if (r.option().getShortNames() != null) {
|
||||
for (Character n : r.option().getShortNames()) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2022 the original author or authors.
|
||||
* Copyright 2022-2023 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.
|
||||
@@ -32,6 +32,14 @@ public interface CommandOption {
|
||||
*/
|
||||
String[] getLongNames();
|
||||
|
||||
/**
|
||||
* Gets a modified long names of an option. Set within a command registration if
|
||||
* option name modifier were used to have an info about original names.
|
||||
*
|
||||
* @return modified long names of an option
|
||||
*/
|
||||
String[] getLongNamesModified();
|
||||
|
||||
/**
|
||||
* Gets a short names of an option.
|
||||
*
|
||||
@@ -111,7 +119,7 @@ public interface CommandOption {
|
||||
* @return default command option
|
||||
*/
|
||||
public static CommandOption of(String[] longNames, Character[] shortNames, String description) {
|
||||
return of(longNames, shortNames, description, null, false, null, null, null, null, null, null);
|
||||
return of(longNames, null, shortNames, description, null, false, null, null, null, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,13 +133,14 @@ public interface CommandOption {
|
||||
*/
|
||||
public static CommandOption of(String[] longNames, Character[] shortNames, String description,
|
||||
ResolvableType type) {
|
||||
return of(longNames, shortNames, description, type, false, null, null, null, null, null, null);
|
||||
return of(longNames, null, shortNames, description, type, false, null, null, null, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instance of a default {@link CommandOption}.
|
||||
*
|
||||
* @param longNames the long names
|
||||
* @param longNamesModified the modified long names
|
||||
* @param shortNames the short names
|
||||
* @param description the description
|
||||
* @param type the type
|
||||
@@ -144,10 +153,10 @@ public interface CommandOption {
|
||||
* @param completion the completion
|
||||
* @return default command option
|
||||
*/
|
||||
public static CommandOption of(String[] longNames, Character[] shortNames, String description,
|
||||
public static CommandOption of(String[] longNames, String[] longNamesModified, Character[] shortNames, String description,
|
||||
ResolvableType type, boolean required, String defaultValue, Integer position, Integer arityMin,
|
||||
Integer arityMax, String label, CompletionResolver completion) {
|
||||
return new DefaultCommandOption(longNames, shortNames, description, type, required, defaultValue, position,
|
||||
return new DefaultCommandOption(longNames, longNamesModified, shortNames, description, type, required, defaultValue, position,
|
||||
arityMin, arityMax, label, completion);
|
||||
}
|
||||
|
||||
@@ -157,6 +166,7 @@ public interface CommandOption {
|
||||
public static class DefaultCommandOption implements CommandOption {
|
||||
|
||||
private String[] longNames;
|
||||
private String[] longNamesModified;
|
||||
private Character[] shortNames;
|
||||
private String description;
|
||||
private ResolvableType type;
|
||||
@@ -168,11 +178,12 @@ public interface CommandOption {
|
||||
private String label;
|
||||
private CompletionResolver completion;
|
||||
|
||||
public DefaultCommandOption(String[] longNames, Character[] shortNames, String description,
|
||||
public DefaultCommandOption(String[] longNames, String[] longNamesModified, Character[] shortNames, String description,
|
||||
ResolvableType type, boolean required, String defaultValue, Integer position,
|
||||
Integer arityMin, Integer arityMax, String label,
|
||||
CompletionResolver completion) {
|
||||
this.longNames = longNames != null ? longNames : new String[0];
|
||||
this.longNamesModified = longNamesModified != null ? longNamesModified : new String[0];
|
||||
this.shortNames = shortNames != null ? shortNames : new Character[0];
|
||||
this.description = description;
|
||||
this.type = type;
|
||||
@@ -190,6 +201,11 @@ public interface CommandOption {
|
||||
return longNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getLongNamesModified() {
|
||||
return longNamesModified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Character[] getShortNames() {
|
||||
return shortNames;
|
||||
|
||||
@@ -1245,11 +1245,13 @@ public interface CommandRegistration {
|
||||
options = optionSpecs.stream()
|
||||
.map(o -> {
|
||||
String[] longNames = o.getLongNames();
|
||||
String[] longNamesModified = null;
|
||||
Function<String, String> modifier = o.getOptionNameModifier();
|
||||
if (modifier != null) {
|
||||
longNamesModified = Arrays.copyOf(longNames, longNames.length);
|
||||
longNames = Arrays.stream(longNames).map(modifier).toArray(String[]::new);
|
||||
}
|
||||
return CommandOption.of(longNames, o.getShortNames(), o.getDescription(), o.getType(),
|
||||
return CommandOption.of(longNames, longNamesModified, o.getShortNames(), o.getDescription(), o.getType(),
|
||||
o.isRequired(), o.getDefaultValue(), o.getPosition(), o.getArityMin(), o.getArityMax(),
|
||||
o.getLabel(), o.getCompletion());
|
||||
})
|
||||
|
||||
@@ -564,4 +564,22 @@ public class CommandExecutionTests extends AbstractCommandTests {
|
||||
Object result = execution.evaluate(new String[] { "command1", "--arg1", "myarg1value" });
|
||||
assertThat(result).isInstanceOf(CommandNotCurrentlyAvailable.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecutionWithModifiedLongOption() {
|
||||
CommandRegistration r1 = CommandRegistration.builder()
|
||||
.command("command1")
|
||||
.withOption()
|
||||
.longNames("arg1")
|
||||
.nameModifier(orig -> "x" + orig)
|
||||
.and()
|
||||
.withTarget()
|
||||
.function(function1)
|
||||
.and()
|
||||
.build();
|
||||
commandCatalog.register(r1);
|
||||
Object result = execution.evaluate(new String[] { "command1", "--xarg1", "myarg1value" });
|
||||
assertThat(result).isEqualTo("himyarg1value");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user