jawher / mow.cli

A versatile library for building CLI applications in Go
MIT License
871 stars 55 forks source link

StringsOpt can not start with dashes #108

Open mpldr opened 4 years ago

mpldr commented 4 years ago

If you want to supply additional options to pass to another program the syntax is limited.

Assuming that the option --args takes in these arguments and no one-character-alternative has been set, the = is required.

Meaning the following:

fails: --arg --wait
fails: --arg -w
works: --arg=--wait
works: --arg=-w

I can understand the reason for this but still feel this bahaviour to be inconsistent.

TomFreudenberg commented 2 years ago

Hm - seems to me you missed the "--" seperator?

From README in Section https://github.com/jawher/mow.cli#spec-strings

...

The -- operator can be used to automatically treat everything following it as arguments. In other words, placing a -- in the spec string automatically inserts a -- in the same position in the program call arguments. This lets you write programs such as the POSIX time utility for example:

x.Spec = "-lp [-- CMD [ARG...]]"

// Allows parsing of the following shell command:
//   $ app -p ps -aux
mpldr commented 2 years ago

The thing is that -- is not the correct solution. It's not an argument but a parameter, as you can see in the example I provided. To give a real-world example:

Usage: br [--editor] [--arg...] FILES...

Arguments:             
  FILES                the source files that will be added to the editor

Options:
      --editor         executable of the editor (env $EDITOR) (default "vi")
      --arg            arguments for the editor (default ["{}"])

(removed some options, but you should get the gist) The issue is with --arg which allows passing arguments for the editor.

TomFreudenberg commented 2 years ago

Moritz @mpldr

I am sorry, I do not get what you expect.

Shouldn't it

br --editor FILES... [-- ARG...]

so let you call

br --editor file1.txt file2.txt -- -w

Just as I would expect it from documentation?

mpldr commented 2 years ago

No, a call would be something like:

br --editor sed --arg=-ie --arg 's/1/2/g' --arg {} *.txt

or

br --editor vim --arg {} --arg +%s/1/2/g --arg +x *.txt

TomFreudenberg commented 2 years ago

Ah, ok, got it.

Will it work already if you use parenthesis?

br --editor vim --arg "{}" --arg "+%s/1/2/g" --arg "+x" *.txt

while *.txt will become automatically

br --editor vim --arg "{}" --arg "+%s/1/2/g" --arg "+x" file1.txt file2.txt filea.txt

if the files exist on command call.

mpldr commented 2 years ago

The problem is not the vim version, it just served for illustration. The interesting part is the --arg=-ie for sed. Not the Shell-Side expansion of globbing patterns.

TomFreudenberg commented 2 years ago

Yes, for sure, got all from previous posts!

I just wonder and asked if the parenthesis will already help to function StingOpts.

So, I asked for the sequence part:

--arg "-ie" --arg "+%s/1/2/g" --arg "+x"

only, and if that will already work and StingOpts detects the args correctly also without an equal sign = in between.

If I got it right from your posts, this will work, correct?

--arg="-ie" --arg="+%s/1/2/g" --arg="+x"

But also with parenthesis and without the equal sign?

mpldr commented 2 years ago

Because of how (most) shells work, unfortunately this does not change anything. The quotation marks (I guess by parenthesis you mean them) are only used by the shell to call the process and determine where an argument starts. The quotation marks themselves are not added to the process's arguments. An easy way to try it out would be to run:

package main
import "os"
import "fmt"
func main() { fmt.Println(os.Args) } // the quotation marks would be printed here as well
TomFreudenberg commented 2 years ago

Ok, got that also - for sorry

I just look if something will allow the parser to catch the second value after --arg as a string value and not a new argument.

Maybe that will be stayed safe thru the shell?

--arg '"-ie"' --arg '"+%s/1/2/g"' --arg '"+x"'

Its not the solution - just as a test if the parser currently would recognize those correctly

mpldr commented 2 years ago

here is what it looks like to the program: [/tmp/go-build861777601/b001/exe/main --arg "-ie" --arg "+%s/1/2/g" --arg "+x"]

and the actual program tells me:

> ./bulkrename --editor sed --arg '"-ie"' --arg 's/6/4/g' *
sed: -e expression #1, char 1: unknown command: `"'
TomFreudenberg commented 2 years ago

Well, thanks for feedback.

Did I get it correctly, that even the params do not work for the forwarded sed, this time the values are correctly attached to the --arg param of the mow.cli app?

So if you would drop the (") inside your golang mow.cli app then the call for sed will work?

If so, the parser needs a patch to identifiy - as string after an argument

mpldr commented 2 years ago

I mean… technically it would be possible to remove this, but I am not a fan of special behaviour and this might very well cause some issues. While there might not be a "correct" answer on this, there might be a "best solution"… (I mean… I documented this behaviour with my program but just wanted to bring it up)