remkop / picocli

Picocli is a modern framework for building powerful, user-friendly, GraalVM-enabled command line apps with ease. It supports colors, autocompletion, subcommands, and more. In 1 source file so apps can include as source & avoid adding a dependency. Written in Java, usable from Groovy, Kotlin, Scala, etc.

Home Page:https://picocli.info

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Clarification about repeatable subcommand

sbernard31 opened this issue · comments

I wanted to create something like :

Command C with repeatable : 
   subcommand SA with repeatable :
       subcommand SA1 with option -opt1 and -opt2
   subcommand SB with repeatable :
       subcommand SB1 with option -opt1 and -opt2

I was expected I will be able to do call looking like :

C SA SA1 -opt1 \
  SB SB1 -opt2

But it failed with something like : Unmatched argument at index 4: 'SB'

I would like to be sure it's not supported ?

Hi @sbernard31, I believe the user manual mentions this; it's not supported to "go up the hierarchy".

So, this would be supported:


C SA SA1 -opt1 \
     SB1 -opt2 \
     SA1 -opt1 \
     SB1 -opt2

But once the parser is at the SA1/SB1 subcommand level it doesn't expect to encounter parent commands of these, only sibling commands or more deeply nested subcommands.

Thx for answer.

I believe the user manual mentions this; it's not supported to "go up the hierarchy".

Maybe you refer to https://picocli.info/#_repeatable_subcommands_specification

Note that it is not valid to specify a subcommand followed by its parent command

(In my case this is not the parent but this is same level as the parent)

So, this would be supported:

C SA SA1 -opt1
SB1 -opt2
SA1 -opt1
SB1 -opt2

Yep but this doesn't really match my use case.

But once the parser is at the SA1/SB1 subcommand level it doesn't expect to encounter parent commands of these, only sibling commands or more deeply nested subcommands.

Does it exist an elegant way to change the parsing ?

Maybe I'm wrong but current behavior lead to some strange surprising behavior where
- toplevelcmd subcmd-A subcmd-B subsubB will work
- toplevelcmd subcmd-B subsubB subcmd-A will not.

but from a user point of view, he just execute 2 "action" in 2 different order 🤔.

Intuitively I understood that an "action" is a leaf in command graph (https://picocli.info/#_repeatable_subcommands_specification)

About :

Does it exist an elegant way to change the parsing ?

I tried to dig in the code to see if there is a way to change/customize/extend this behavior and unfortunately I didn't find anything.
Logic seems to be directly implemented in Interpreter code.

Could you confirm if I'm right ? 🙏

Hard blow for me because :

  1. I take several days to code my command hierarchy but finally it doesn't work. Before to go I tested with toplevelcmd subcmd-A subcmd-B subsubB 😬
  2. For now, I strictly have no idea as how I could design my CLI interface to match picocli constraint... 😞

The parsing code for repeatable subcommands is not easily customizable I’m afraid.

You may need to restructure your application somehow. One idea is to use more options and fewer sub-subcommands, but you are more familiar with your objectives.

You may need to restructure your application somehow. One idea is to use more options and fewer sub-subcommands, but you are more familiar with your objectives.

I can describe my use case :

I need a way configure transport layer of my application :

  1. choosing the kind of implementation (different possible implementation based on different library)
  2. selecting available protocol for this implementation
  3. Eventually configure it with options (option available depends of implementation/protocol).

(This is even more complicated than that but I hope this is enough to understand the issue)

So for example I hoped I could do :

java -jar myapp transport \
    library1 protocol1 -protocol1option value \
             protocol2  \
    library2 protocol3 -protocol3option value

Using subcommand make easy:

  • to attach specific option only to specific protocol/implementation,
  • to add supported protocol to an implementation.
  • to extend the application by just adding a new subcommand (to add protocol or implementation)
  • to have discoverable documentation with split help.

It seems the feature was requested several time by the past :