You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2019/02/19 03:14:48 UTC
[groovy] branch GROOVY_2_5_X updated: GROOVY-8975:
GroovyCastException on the result of CliBuilder.parseFromSpec (port to
2_5_X)
This is an automated email from the ASF dual-hosted git repository.
paulk pushed a commit to branch GROOVY_2_5_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_2_5_X by this push:
new 1391859 GROOVY-8975: GroovyCastException on the result of CliBuilder.parseFromSpec (port to 2_5_X)
1391859 is described below
commit 13918597aae2cbb8dbb2f644c099e514bce39134
Author: Paul King <pa...@asert.com.au>
AuthorDate: Tue Feb 19 13:08:59 2019 +1000
GROOVY-8975: GroovyCastException on the result of CliBuilder.parseFromSpec (port to 2_5_X)
---
.../src/main/groovy/groovy/cli/commons/CliBuilder.groovy | 14 +++++++-------
.../test/groovy/groovy/cli/commons/CliBuilderTest.groovy | 16 ++++++++++++++--
.../src/main/groovy/groovy/cli/picocli/CliBuilder.groovy | 9 +++++----
.../test/groovy/groovy/cli/picocli/CliBuilderTest.groovy | 14 ++++++++++++++
4 files changed, 40 insertions(+), 13 deletions(-)
diff --git a/subprojects/groovy-cli-commons/src/main/groovy/groovy/cli/commons/CliBuilder.groovy b/subprojects/groovy-cli-commons/src/main/groovy/groovy/cli/commons/CliBuilder.groovy
index 88c64ae..f903ea7 100644
--- a/subprojects/groovy-cli-commons/src/main/groovy/groovy/cli/commons/CliBuilder.groovy
+++ b/subprojects/groovy-cli-commons/src/main/groovy/groovy/cli/commons/CliBuilder.groovy
@@ -30,11 +30,11 @@ import org.apache.commons.cli.HelpFormatter
import org.apache.commons.cli.Option as CliOption
import org.apache.commons.cli.Options
import org.apache.commons.cli.ParseException
+import org.codehaus.groovy.runtime.DefaultGroovyMethods
import org.codehaus.groovy.runtime.InvokerHelper
import org.codehaus.groovy.runtime.MetaClassHelper
import java.lang.annotation.Annotation
-import java.lang.reflect.Array
import java.lang.reflect.Field
import java.lang.reflect.Method
@@ -386,7 +386,7 @@ class CliBuilder {
def cli = parse(args)
def cliOptions = [:]
setOptionsFromAnnotations(cli, optionsClass, cliOptions, false)
- cliOptions as T
+ DefaultGroovyMethods.asType(cliOptions, optionsClass)
}
/**
@@ -417,7 +417,7 @@ class CliBuilder {
}
optionFields.each { Field f ->
Annotation annotation = f.getAnnotation(Option)
- String setterName = "set" + MetaClassHelper.capitalize(f.getName());
+ String setterName = "set" + MetaClassHelper.capitalize(f.getName())
Method m = optionClass.getMethod(setterName, f.getType())
def typedOption = processAddAnnotation(annotation, m, true)
options.addOption(typedOption.cliOption)
@@ -513,7 +513,7 @@ class CliBuilder {
}
optionClass.declaredFields.findAll { it.getAnnotation(Option) }.each { Field f ->
Annotation annotation = f.getAnnotation(Option)
- String setterName = "set" + MetaClassHelper.capitalize(f.getName());
+ String setterName = "set" + MetaClassHelper.capitalize(f.getName())
Method m = optionClass.getMethod(setterName, f.getType())
Map names = calculateNames(annotation.longName(), annotation.shortName(), m, true)
processSetAnnotation(m, t, names.long ?: names.short, cli, true)
@@ -523,7 +523,7 @@ class CliBuilder {
processSetRemaining(m, remaining, t, cli, namesAreSetters)
}
optionClass.declaredFields.findAll{ it.getAnnotation(Unparsed) }.each { Field f ->
- String setterName = "set" + MetaClassHelper.capitalize(f.getName());
+ String setterName = "set" + MetaClassHelper.capitalize(f.getName())
Method m = optionClass.getMethod(setterName, f.getType())
processSetRemaining(m, remaining, t, cli, namesAreSetters)
}
@@ -536,12 +536,12 @@ class CliBuilder {
def type = null
if (isTyped) {
type = resultType.componentType
- result = remaining.collect{ cli.getValue(type, it, null) }
+ result = remaining.collect{ cli.getValue(type, it, null) }.asType(resultType)
} else {
result = remaining.toList()
}
if (namesAreSetters) {
- m.invoke(t, isTyped ? [result.toArray(Array.newInstance(type, result.size()))] as Object[] : result)
+ m.invoke(t, isTyped ? [result] as Object[] : result)
} else {
Map names = calculateNames("", "", m, namesAreSetters)
t.put(names.long, { -> result })
diff --git a/subprojects/groovy-cli-commons/src/test/groovy/groovy/cli/commons/CliBuilderTest.groovy b/subprojects/groovy-cli-commons/src/test/groovy/groovy/cli/commons/CliBuilderTest.groovy
index fd8928a..0d4d5a5 100644
--- a/subprojects/groovy-cli-commons/src/test/groovy/groovy/cli/commons/CliBuilderTest.groovy
+++ b/subprojects/groovy-cli-commons/src/test/groovy/groovy/cli/commons/CliBuilderTest.groovy
@@ -622,7 +622,6 @@ usage: groovy
@Unparsed Integer[] nums()
}
- // this feature is incubating
void testTypedUnparsedFromSpec() {
def argz = '12 34 56'.split()
def cli = new CliBuilder()
@@ -634,7 +633,6 @@ usage: groovy
@Unparsed Integer[] nums
}
- // this feature is incubating
void testTypedUnparsedFromInstance() {
def argz = '12 34 56'.split()
def cli = new CliBuilder()
@@ -661,6 +659,20 @@ usage: groovy
}
}
+ interface StringIntArray {
+ @Option(shortName='u') String user()
+ @Unparsed Integer[] nums()
+ }
+
+ // GROOVY-8975
+ void testTypedCaseWithRemainingArray() {
+ def cli = new CliBuilder()
+ def argz = '--user abc 12 34'.split()
+ StringIntArray hello = cli.parseFromSpec(StringIntArray, argz)
+ assert hello.user() == 'abc'
+ assert hello.nums() == [12, 34]
+ }
+
void testParseFromInstanceFlagEdgeCases() {
def cli = new CliBuilder()
def options = cli.parseFromSpec(FlagEdgeCasesI, '-abc -efg true --ijk foo --lmn bar baz'.split())
diff --git a/subprojects/groovy-cli-picocli/src/main/groovy/groovy/cli/picocli/CliBuilder.groovy b/subprojects/groovy-cli-picocli/src/main/groovy/groovy/cli/picocli/CliBuilder.groovy
index e53003e..914360a 100644
--- a/subprojects/groovy-cli-picocli/src/main/groovy/groovy/cli/picocli/CliBuilder.groovy
+++ b/subprojects/groovy-cli-picocli/src/main/groovy/groovy/cli/picocli/CliBuilder.groovy
@@ -23,6 +23,7 @@ import groovy.cli.Option
import groovy.cli.TypedOption
import groovy.cli.Unparsed
import groovy.transform.Undefined
+import org.codehaus.groovy.runtime.DefaultGroovyMethods
import org.codehaus.groovy.runtime.InvokerHelper
import org.codehaus.groovy.runtime.MetaClassHelper
import picocli.CommandLine
@@ -658,7 +659,7 @@ class CliBuilder {
addOptionsFromAnnotations(optionsClass, cliOptions, true)
addPositionalsFromAnnotations(optionsClass, cliOptions, true)
parse(args)
- cliOptions as T
+ DefaultGroovyMethods.asType(cliOptions, optionsClass)
}
/**
@@ -786,7 +787,7 @@ class CliBuilder {
private ArgSpecAttributes extractAttributesFromField(Field f, target) {
def getter = {
f.accessible = true
- f.get(target);
+ f.get(target)
}
def setter = { newValue ->
f.accessible = true
@@ -799,7 +800,7 @@ class CliBuilder {
}
private PositionalParamSpec createPositionalParamSpec(Unparsed unparsed, ArgSpecAttributes attr, Object target) {
- PositionalParamSpec.Builder builder = PositionalParamSpec.builder();
+ PositionalParamSpec.Builder builder = PositionalParamSpec.builder()
CommandLine.Range arity = CommandLine.Range.valueOf("0..*")
if (attr.type == Object) { attr.type = String[] }
@@ -922,7 +923,7 @@ class CliBuilder {
}
/** Commons-cli constant that specifies the number of argument values is infinite */
- private static final int COMMONS_CLI_UNLIMITED_VALUES = -2;
+ private static final int COMMONS_CLI_UNLIMITED_VALUES = -2
// - argName: String
// - longOpt: String
diff --git a/subprojects/groovy-cli-picocli/src/test/groovy/groovy/cli/picocli/CliBuilderTest.groovy b/subprojects/groovy-cli-picocli/src/test/groovy/groovy/cli/picocli/CliBuilderTest.groovy
index 6740781..6849d3c 100644
--- a/subprojects/groovy-cli-picocli/src/test/groovy/groovy/cli/picocli/CliBuilderTest.groovy
+++ b/subprojects/groovy-cli-picocli/src/test/groovy/groovy/cli/picocli/CliBuilderTest.groovy
@@ -990,6 +990,20 @@ class CliBuilderTest extends GroovyTestCase {
}
}
+ interface StringIntArray {
+ @Option(shortName='u') String user()
+ @Unparsed Integer[] nums()
+ }
+
+ // GROOVY-8975
+ void testTypedCaseWithRemainingArray() {
+ def cli = new CliBuilder()
+ def argz = '--user abc 12 34'.split()
+ StringIntArray hello = cli.parseFromSpec(StringIntArray, argz)
+ assert hello.user() == 'abc'
+ assert hello.nums() == [12, 34]
+ }
+
void testAcceptLongOptionsWithSingleHyphen_usage() {
resetPrintWriter()
CliBuilder cli = new CliBuilder(acceptLongOptionsWithSingleHyphen: true, writer: printWriter)