Skip to content

Optional parameters in command-methods keep their List values once set when reusing commandLine #570

@SysLord

Description

@SysLord

Applies for example when using interactive shell mode with jline2.
Workaround: Never use a commandLine instance twice.

    @Test
    public void testOptionalListParameterInCommandClass() {
        @Command() class TestCommand implements Callable<String>{
            @Parameters(arity="0..*") private List<String> values;
            public String call() throws Exception { return values == null ? "null" : values.toString(); }
        }
        
        // seems to be working for @Command-class @Parameters
        CommandLine commandLine = new CommandLine(new TestCommand());
        List<Object> firstExecutionResultWithParametersGiven = commandLine.parseWithHandlers(
                new RunLast(), 
                new DefaultExceptionHandler<List<Object>>(), 
                new String[] {"arg0", "arg1"});
        List<Object> secondExecutionResultWithoutParameters = commandLine.parseWithHandlers(
                new RunLast(), 
                new DefaultExceptionHandler<List<Object>>(), 
                new String[] {});
        assertEquals("[arg0, arg1]", firstExecutionResultWithParametersGiven.get(0));
        assertEquals("null", secondExecutionResultWithoutParameters.get(0));
    }
    
    @Test
    public void testOptionalListParameterShouldNotRememberValuesInCommandMethods() {
        @Command() class TestCommand {
            @Command(name="method")
            public String methodCommand(@Parameters(arity="0..*") List<String> methodValues) {
                return methodValues == null ? "null" : methodValues.toString();
            }
        }
        CommandLine commandLine = new CommandLine(new TestCommand());
        
        // problematic for @Command-method @Parameters        
        List<Object> methodFirstExecutionResultWithParametersGiven = commandLine.parseWithHandlers(
                new RunLast(), 
                new DefaultExceptionHandler<List<Object>>(), 
                new String[] {"method","arg0", "arg1"});
        List<Object> methodSecondExecutionResultWithoutParameters = commandLine.parseWithHandlers(
                new RunLast(), 
                new DefaultExceptionHandler<List<Object>>(), 
                new String[] {"method"});

        assertEquals("[arg0, arg1]", methodFirstExecutionResultWithParametersGiven.get(0));
        // fails, still "[arg0, arg1]"
        assertEquals("null", methodSecondExecutionResultWithoutParameters.get(0));
    }

Side note just in case the question comes up: On the question why we would use parseWithHandlers, I would say that we need to use the class-factory for Bean instantiation, but interactive mode already instantiated a command for auto complete info. But no interface CommandLine.call(instance, factory, yada);

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions