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

Hide the default System section from the HELP command #1429

Open
allguitars opened this issue Sep 10, 2021 · 5 comments
Open

Hide the default System section from the HELP command #1429

allguitars opened this issue Sep 10, 2021 · 5 comments
Labels
status: feedback-provided 💬 Feedback has been provided theme: shell An issue or change related to interactive (JLine) applications

Comments

@allguitars
Copy link

allguitars commented Sep 10, 2021

Hi,

I am currently working on a project where we have implemented a few custom commands. When I just type help command (without any subcommand), it displays two sections. One is the default System commands that are registered inherently showing help and exit commands. The other section shows our custom commands.

However, our application is currently not supporting the exit command so we want to hide this part. How do I remove or hide the System section from the help menu?

2021-09-11_001

@allguitars allguitars changed the title Hide the default System commands from the root help command Hide the default System section from the HELP command Sep 10, 2021
@remkop
Copy link
Owner

remkop commented Sep 10, 2021

Hi!
That’s hard to say without seeing the code, but I guess you would undo (or comment out) what you did to show these sections.

@allguitars
Copy link
Author

allguitars commented Sep 11, 2021

Hi Remko,

Here is how we build up the command registries.

@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
class NormalMode implements CliMode {
    private MessageSource i18n
    private Supplier<Path> pwd
    private CommandLine parentCommandLine

    @Autowired
    NormalMode(
        MessageSource messageSource,
        @Qualifier("currentWorkingDir") Supplier<Path> pwd,
        @Qualifier("rootCommandLine") CommandLine rootCommandLine,
        SetupCommand setupCommand,
        SetFactoryCommand setFactoryCommand,
        ShowCommand showCommand,
        ServiceCommand serviceCommand,
        BackDoorCommand backDoorCommand
    ) {
        this.i18n = messageSource
        this.pwd = pwd
        this.parentCommandLine = rootCommandLine
        attachSubCommands(
            rootCommandLine,
            setupCommand,
            setFactoryCommand,
            showCommand,
            serviceCommand,
            backDoorCommand
        )
    }

    protected void attachSubCommands(CommandLine commandLine, CliCommand<?>... subCommands) {
        for (CliCommand<?> command : subCommands) {
            commandLine.addSubcommand(command)
        }
    }

    @Override
    Supplier<String> supplyPromptString() {
        return () -> i18n.getMessage("mode.normal.prompt", null, Locale.getDefault())
    }

    @Override
    Supplier<Path> supplyCurrentWorkingDirectory() {
        return pwd
    }

    @Override
    CommandRegistry getCommandRegistry() {
        return new PicocliCommands(pwd, parentCommandLine) {
            @Override
            String name() {
                return i18n.getMessage("mode.normal.name", null, Locale.getDefault())
            }
        }
    }
}

Let me paste one of the command implementation here.
The business logic was made under its subcommand.
And I include the CommandLine.HelpCommand class here so that we can allow the user to type show help to see what subcommands we offer.

@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@Command(name = "show",
        subcommands = [
            ShowInterfaceCommand,
            ShowPm2ServiceCommand,
            ShowSystemCommand,
            CommandLine.HelpCommand ],
        description = "Show system information")
@Slf4j
final class ShowCommand extends AbstractCliCommand<Integer> {

    @Override
    Integer call() throws Exception {
        return 0
    }

}

At the point of reading the user's commands as shown below, we instantiate a SystemRegistryImpl object, set the command registries and create the LineReader object and then start to continuously read in user's command and execute it.

    @Override
    void repl(CliMode mode) throws EndOfFileException, Exception {
        SystemRegistry aggregator = new SystemRegistryImpl(parser, terminal, mode.supplyCurrentWorkingDirectory(),
                null)
        aggregator.setCommandRegistries(mode.getCommandRegistry())

        LineReader lineReader = LineReaderBuilder
                .builder()
                .terminal(terminal)
                .parser(parser)
                .option(Option.CASE_INSENSITIVE, true)
                .option(Option.AUTO_GROUP, false)
                .option(Option.GROUP, false)
                .completer(aggregator.completer()).variable(LineReader.LIST_MAX, 50).build()

        while (true) {
            try {
                aggregator.cleanUp()
                String line = lineReader.readLine(mode.supplyPromptString().get())
                aggregator.execute(line)
            } catch (UserInterruptException ctrlc) {
                log.error("The user pressed Ctrl C.", ctrlc)
 
           ...          

We did not interfere with how the API will perform the root help behavior, that is, when we just type the help command, it prints out all the commands including the System section shown in the screenshot. We understand that it should print out all the custom commands listed under the Normal Mode section, but how can we get rid of the System section so the user will not know they can type the exit or help command.

Cheers,
Dave

@remkop
Copy link
Owner

remkop commented Sep 11, 2021

Oh I see now, this is a JLine3 application, that was not clear to me initially.

Not sure if this is possible, but it may be.
I believe that the Exit command is a JLine3 command, that does not use the picocli API...
You will have to dig a bit into the integration code that combines JLine3 with picocli, and where these commands are added.

@remkop
Copy link
Owner

remkop commented Sep 28, 2021

@allguitars it has been a while so it may not be on your radar any longer, but another suggestion I could make is to contact the JLine3 project and ask if they have any suggestions.

@remkop remkop added the theme: shell An issue or change related to interactive (JLine) applications label Jan 19, 2022
@remkop
Copy link
Owner

remkop commented Jan 19, 2022

@allguitars Is this still an issue for you or can I close this ticket?

@remkop remkop added the status: feedback-provided 💬 Feedback has been provided label Feb 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: feedback-provided 💬 Feedback has been provided theme: shell An issue or change related to interactive (JLine) applications
Projects
None yet
Development

No branches or pull requests

2 participants