Skip to content

When using "help <SubCommand>", the exit code is 0, despite exitCodeOnUsageHelp = ExitCode.USAGE #2355

Closed

Description

@marco-brandizi

The title says almost all: I have a CLI app that is arranged as main command + subcommands. When I issue something like: java MainCommand help subCommand, the OS exit code is 0, not 2, despite both MainCommand.class and SubCommand are annotated with:

@Command ( ... exitCodeOnUsageHelp = ExitCode.USAGE, exitCodeOnVersionHelp = ExitCode.USAGE)

when doing java MainCommand -h, it exits with 2 as expected. Unless I'm missing something, to me it is a bug.

Until this is changed, it's possible to write a workaround like: in the static main(), check if the first argument is 'help'.

Activity

  1. remkop commented on Dec 9, 2024

    @remkop
    Owner

    I think you are correct, and this is a bug in the implementation of picocli.CommandLine.HelpCommand.

    This class currently implements Runnable.
    To fix the issue, it should implement Callable<Integer> and should either
    return subcommand.getCommandSpec().exitCodeOnUsageHelp() if a subcommand was specified, or
    return parent.getCommandSpec().exitCodeOnUsageHelp() if not.

    Will you be able to provide a pull request with tests for this?

  2. added this to the 4.7.7 milestone on Dec 9, 2024
  3. added a commit that references this issue on Dec 11, 2024
    2987a24
  4. marco-brandizi commented on Dec 11, 2024

    @marco-brandizi
    Author

    Hi @remkop, I've tried to write a fix, but unfortunately, I don't have much time and I barely managed to change HelpCommand. It's hard to write a test and even without any changes, my clone doesn't build for me, mvn clean package gives me errors (starting with package org.junit does not exist), I can't use Gradle.

  5. remkop commented on Dec 20, 2024

    @remkop
    Owner

    Note to self:

    // src/test/java/picocli/HelpSubCommandTest.java
    
        @Command(name = "issue2355", exitCodeOnUsageHelp = 123)
        static class Issue2355 implements Runnable {
            @Override public void run() {}
        }
    
        @Test
        public void testIssue2355ExitCode() {
            @Command(name = "top", subcommands = Issue2355.class) class Top { }
            int actual = new CommandLine(new Top()).execute("help", "issue2355");
            assertEquals(123, actual);
        }
  6. added a commit that references this issue on Jan 5, 2025
  7. added a commit that references this issue on Apr 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions