Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exit on help, version or invalid arguments #424

Closed
gerardbosch opened this issue Jul 30, 2018 · 6 comments
Closed

Exit on help, version or invalid arguments #424

gerardbosch opened this issue Jul 30, 2018 · 6 comments

Comments

@gerardbosch
Copy link

Typically, when you run a command line application using the help or version flag (--help, --version) you expect that the program exits itself after printing usage information.

Picocli has a built-in feature to alleviate the programmer of writing the help and version logic, but in this case Picocli doesn't exit application —invoking for example system exit with a status code of success— but let the application to continue running.

When using the convenience CommandLine.run(), CommandLine.call() I would expect the described behavior to happen. Currently, usage information is printed but application doesn't exit and continues running with no simple way to configure it to work as described (related discussion: #397 ).

I propose to print usage and exit to be the default behavior. I don't know if any other use case could need the application to continue but in that case I would propose an annotation based configuration to override the defaults like the one proposed in ticket #397 .

Kind regards!

@remkop
Copy link
Owner

remkop commented Jul 30, 2018

Thanks for raising this. I agree this can be improved.

I like your idea for annotation attributes, something like:

@Command(name = "cmd",
        exitCodeOnUsageHelp = 0, 
        exitCodeOnVersionHelp = 0, 
        exitCodeOnInvalidInput = 64,
        exitCodeOnExecutionException = 123)
class MyCommand { ... }

The javadoc for these attributes should clearly say that these settings are only used when the input is processed with one of the convenience methods: run, call or parseWithHandlers, and ignored otherwise (that is, ignored when parse, parseArgs or populateCommand are used to process arguments).

Picocli should only call System.exit if these exitCode values are explicitly set.

Do you think you'll be able to provide a pull request for this?

@gerardbosch
Copy link
Author

gerardbosch commented Aug 1, 2018

As I have been trying a little more in depth Picocli for my Spring Command Line/Application Runner, I have realized that I can achieve the behavior I was looking for, simply by delegating the start of Spring application inside the run() or call() method of the Runnable/Callable class that contains the Picocli annotations (aka annotated object) instead of starting it in the main method.

That is because Picocli will never call run()/call() methods when --help or --version are present or when invalid arguments are provided, and application simply finishes and exits in these cases (the aim I was pursuing). The only objection here is that the exit code on invalid arguments is equally 0, which denotes success (but it is not).

So at this point, probably this issue stops making sense, at least partially. But maybe this way of working could be pointed in the Github and website documentation.

I put here an example of how I start my Spring application, handling command line arguments with Picocli. In my case I made the Main class itself the one holding CLI annotations:

@SpringBootApplication
@Command(description = "Application description",
        versionProvider = MyVersionProvider.class,
        mixinStandardHelpOptions = true)
public class ValidatorApplication implements Runnable {

    @Parameters(paramLabel = "FILE", description = "Primary XML file to validate.")
    public static String primaryFile;

    @Option(names = {"-p", "--previous-year"}, paramLabel = "PREV_YEAR_FILE",
            description = "Previous year XML file. Some specific validations require previous year file. If not " +
                    "provided, these validations are not performed.")
    public static String prevYearFile;


    public static void main(String[] args) {
        CommandLine.run(new ValidatorApplication(), args);
    }

    @Override
    public void run() {
        // Start Spring application
        SpringApplication.run(ValidatorApplication.class);
    }

Note that command line parameters and options are public static. This way I can easily access it from any class in the application simply doing e.g. ValidatorApplication.primaryFile.

@remkop
Copy link
Owner

remkop commented Aug 1, 2018

Glad to hear that. Sounds like you would like to see documentation on using picocli with Spring Boot. I don't have any experience with Spring, so contributions / pull requests welcome!

About the original request: I like the idea of having annotations to control the exit code on usage help and version info, and I will probably add this in a future release.

@remkop remkop added this to the 3.7 milestone Sep 28, 2018
@remkop remkop modified the milestones: 3.7, 3.8 Oct 19, 2018
@remkop remkop modified the milestones: 4.1, 4.0-alpha-3 Apr 24, 2019
remkop added a commit that referenced this issue Apr 24, 2019
…te` and `tryExecute` methods: configurable convenience methods with improved exit code support.

* The new `execute` and `tryExecute` methods are similar to the `run`, `call` and `invoke` methods, but are not static, so they allow parser configuration.
* In addition, these methods, in combination with the new `IExitCodeGenerator` and `IExitCodeExceptionMapper` interfaces, offer clean exit code support.
* Finally, the `tryExecute` method rethrows any exception thrown from the Runnable, Callable or Method, while `execute` is guaranteed to never throw an exception.
* Many variants of the previous `run`, `call` and `invoke` convenience methods are now deprecated in favor of the new `execute` methods.
* Many methods on `AbstractHandler` are now deprecated.

Still TODO: tests and documentation.
@remkop
Copy link
Owner

remkop commented Apr 24, 2019

An initial version just landed in master. Please check it out if you have a chance.

remkop added a commit that referenced this issue Apr 26, 2019
remkop added a commit that referenced this issue Apr 26, 2019
remkop added a commit that referenced this issue Apr 27, 2019
remkop added a commit that referenced this issue Apr 30, 2019
remkop added a commit that referenced this issue May 1, 2019
…invoke() methods and associated classes and interfaces; update Javadoc
@remkop remkop closed this as completed in 1161b05 May 2, 2019
remkop added a commit that referenced this issue May 3, 2019
…er interface to simplify custom implementations; unwrap the `ExecutionException` in the `CommandLine.execute` method
@remkop
Copy link
Owner

remkop commented May 14, 2019

@gerardbosch

picocli-4.0-alpha-3 has been released with improved exit code support and exception handling.

This is the last alpha! Please take a look and provide feedback if you have a chance.

@gerardbosch
Copy link
Author

Thanks @remkop , I cannot check it out at this moment, but I keep it present :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants