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

CommandParser ignores parent default options when parsing leaf command #4580

Closed
dspx-plcr opened this issue Jan 5, 2025 · 0 comments · Fixed by #4593
Closed

CommandParser ignores parent default options when parsing leaf command #4580

dspx-plcr opened this issue Jan 5, 2025 · 0 comments · Fixed by #4593
Assignees

Comments

@dspx-plcr
Copy link
Contributor

Consider the following setup,

use "cli"

actor Main
  new create(env: Env) =>
    let spec = try make_spec()? else return end
    let cmd =
      match CommandParser(spec).parse(env.args, env.vars)
      | let c: Command => c
      else return
      end

    env.out.print("Value of arg: " + cmd.option("arg").string())

  fun make_spec(): CommandSpec? =>
    let root = CommandSpec.parent("cmd", "My cmd",
      [ OptionSpec.string("arg", "an arg" where default' = "foo") ])?
    let sub = CommandSpec.leaf("sub", "My subcmd")?

    root.add_command(sub)?
    root.add_help()?
    root

When running this, as ./cmd sub, Value of arg: is printed to the command line. I believe the problem is in command_parser.pony on line 101, where parsing a parent command recurses into parsing a sub-command and then returns. Filling in of default options would occur later, on line 147, but we never get that far.

Two possibilities which spring to mind are

  1. when adding a spec to a parent, add a back-reference in the child so that when options() is called, it returns non-duplicated parent options
  2. don't return from parsing a sub command, but keep track of the fact we've already parsed one sub-command

both suggestions raise questions around duplicated options between the parent and child, and how they should work.

As a motivating example, my use case is to have a config file for my command line utility which should apply to all sub-commands, but defaults to a sensible value if the user doesn't specify one.

Also, when debugging this issue, I found it would have been useful to know if an option was set, rather than having just a default fake option returned. There's a couple of places this could be done, but I think the easiest is to have an is_set or something similar on the Command class.

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

Successfully merging a pull request may close this issue.

3 participants