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

Can a command's default arguments be loaded from config yaml? #24

Open
jameswilson opened this issue Oct 26, 2018 · 7 comments
Open

Can a command's default arguments be loaded from config yaml? #24

jameswilson opened this issue Oct 26, 2018 · 7 comments

Comments

@jameswilson
Copy link

jameswilson commented Oct 26, 2018

Hi Greg,

Given the following CLI command:

$ clitoolname my:foo --option1 value1 --option2 value2 argument1 argument2

I know this package helps to read the command's default options from config.yml like this:

command:
  my:
    foo:
      options:
        option1: value1
        option2: value2   

But is it possible to store the default arguments in yaml? I couldn't find any documentation or examples of how to do this.

@greg-1-anderson
Copy link
Member

I think there's a discussion about this somewhere, but I can't recall where.

The issue with default options is that it is non-ambiguous how to override the defaults. For arguments, it's not so clear. This feature could potentially be provided if there was a clear definition of how it should work.

@jameswilson
Copy link
Author

jameswilson commented Oct 26, 2018

That's an excellent point, it sounds like a challenging problem to solve. Just thinking out loud a bit here, trying to work through the problem space...

Case 0: command w/ a single required argument, no default provided.

Nothing special here; the command execution fails with error message about missing argument, unless there is an argument present on the command line.

Case 1: command w/ a single required argument, default provided in config.yml

The default argument is loaded from config unless there is an argument present on the command line.

command:
  my:
    foo:
      options:
        option1: value1
        option2: value2
      arguments:
        - argument1

Case 2: command w/ two required arguments, second argument has a default in config.yml

It seems exceedingly rare that you'd ever design something with two arguments where the first argument is variable, and the second argument has a default. But anyway, to handle this, config.yml would need to use a keyed index to know which of the two arguments you're providing a default for.

command:
  my:
    foo:
      options:
        option1: value1
        option2: value2
      arguments:
        # 0: argument1  # commented out because we're not providing a default for item 1.
        1: argument2  #assuming we start the index from 0, then index 1 means argument 2 this is messy

Case 3: command w/ two required arguments, first argument has a default in config.yml

Things fall apart here. There is absolutely no way for the end user to specify a second (or third or forth) argument without also providing (and therefore overriding) the first default argument that was stored in code. The only time this would work is if arguments 2 and 3 were not required and the end user didnt provide any arguments, would the default argument 1 be picked up from the config file.

Case 4: command w/ two required arguments, both have defaults in config.yml

Similar to case 3, this falls apart as soon as the developer wants to override the second argument on the command line. You can't do that unless you override both arguments.

To support case four, we wouldn't necessarily need indexed items like case 2, and would only need something similar to case 1

command:
  my:
    foo:
      options:
        option1: value1
        option2: value2
      arguments:
        - argument1
        - argument2

Maybe if case 3 and 4 are just documented as inherent limitations, this could be coded, and it would work for the vast majority of cases.

did I miss any cases?

@greg-1-anderson
Copy link
Member

Case 3 we can definitely say is not supported -- as with programming languages, you must provide defaults from right to left.

Case 4 we can also dispense with.

Can we handle cases where the command takes variable arguments (e.g. function foo($required, array $varags)?

@jameswilson
Copy link
Author

Can we handle cases where the command takes variable arguments (e.g. function foo($required, array $varags)?

Good question, I don't see why not... so:

Case 5: command w/ variable number of arguments, any number of which have defaults in config.yml

This is mostly just an extension of case 1 and case 4, whereby the assumption is that the commands would need to be defined top-to-bottom in yaml list format (similar to left-to-right on command line).

command:
  my:
    foo:
      options:
        option1: value1
        option2: value2
      arguments:
        - argument1
        - argument2
        - argumentN

I thought of another case that might need thinking about -- maybe it would be ok though:

Case 6: default arguments placed in command group

For functional parity with how options can be placed up-the-chain inside the command group and inherited downward to all commands, I wonder how this would work for arguments. For instance (from the example below):

A) would my:foo override argumentA with argumentC and inherit argumentB (this is similar in theory to how option inheritance works)

OR

B) would the fact that the child command implements arguments means that my:foo overrides ALL arguments with the ones provided. I probably like the later (6.B) more, even though it kind of varies from how options work.

command:
  my:
    arguments:
      - argumentA
      - argumentB
    foo: 
       arguments:
         - argumentC

@jameswilson
Copy link
Author

as with programming languages, you must provide defaults from right to left.

Did you mean left to right?

@jameswilson
Copy link
Author

jameswilson commented Oct 26, 2018

Oh wait. I think i get you -- right to left:

function foo($arg1,  $arg2 = "default val", $arg3 = "another default val")

Not sure how that translates into the defaults in YAML though. I'm getting confused 😟

@greg-1-anderson
Copy link
Member

In programming languages, you must define default arguments from right to left, is what I meant. Argument n-1 cannot have a default value unless argument n has a default value. You must provide arguments (overriding defaults, if any) from left to right.

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

No branches or pull requests

2 participants