lets-cli/lets

Allow to pass non documented options to lets commands

Closed this issue · 10 comments

Actual behaviour

For now if I want to pass options to command I must describe them in options property of command block. If I want to pass non documented options to Lets command, I need to write cmd property as array of strings, then Lets will allow me to add any option to cmd. 

Problem description

If my command script is complex and uses if-else bash blocks, it cannot be described using array syntax with the same level of understanding and laconicism as when I use multiline command. 

Feature description

I need to allow to pass non documented options to my command, even if it was written using multiline/singleline style the same as  using list-of-strings style

Maybe we can collect all non documened options to array of option and add it to env as LETS_ARGV_0, LETS_ARGV_1 and pass count of options in env as LETS_ARGC = 2

Yes, I will be implemented in some kind of what you've described

i`ll take it

sure, great

Unfortunately, go-docops pkg doesnt give us a chance to parse custom args (without description in docops string) and throws error immediately on parsing, so. I see the way, of solving this issue, it to fork docops, or to make a pr to them, before implementing feature with undocumented positional args in lets.

PS. I dont like the idea to modify docops string before we give it to ParseDocopts. Coz then we should handle a part of parsing directly in lets, it`s diverging with concept of using docopts-go.

Another option is to give user to choose to use either options or accept_arguments but not both.

So for example, if I want to use undocumented options, I can

commands:
  run:
    accept_args: true
    cmd: |
      if [[  ${SOME_COND} == "true" ]];
        webpack $@
      else
        echo Can't do the thing
      fi

where $@ is options passed to lets run

It will be something like this

lets run -w --config webpack.my.config.js

But if you want to use options and accept_args at the same time, then yes, it is not possible yet and will require to fork docopts-go.

So, thus we can give a users of lets some kind of undocumented arguments, but without options (but we can fix that later).

Huh, I came up with one idea, based on docopts.

It uses -- as a separator (a double dash "--" in http://docopt.org/)

  run:
    options: |
        usage: lets run [--debug] [--] [<args>...]
    cmd: |
        echo 1 $LETSOPT_DEBUG
        echo 2 $LETSOPT_ARGS

Here [<args>...] means

  • its optional
  • its can be repeatable
  • all repeatable args will be collected under $LETSOPT_ARGS variable

And use it

lets run --debug      
1 true
2
lets run --debug -- -w
1 true
2 -w
lets run --debug -- -w --config webpack.config.js
1 true
2 -w --config webpack.config.js

@danylkaaa Maybe this is suitable for you use case ?

@kindermax yes, it is. So, can I use it already?

yep

in this PR #136 we implemented (actually fixed) storing raw args, so it can be used to pass args even using cmd as string.

See docs - https://github.com/lets-cli/lets/blob/master/docs/docs/advanced_usage.md#positional-arguments-using--or-lets_command_args

Basically $@ will work as expected, also LETS_COMMAND_ARGS were added as well.

Note that it will not work if you are using options (docopts). This can not be done without forking go-docops pkg