-
Notifications
You must be signed in to change notification settings - Fork 366
Description
The canonical command-line processing for wrappers (such as time and xargs) is for the wrapper to parse its options until it sees the name of the "wrappee" (e.g. ls in time ls -l). All remaining arguments on the command line are treated as arguments to that wrappee.
E.g. consider this program:
package main
import (
"fmt"
"io"
"os"
"github.com/spf13/pflag"
)
var (
test1Flag = pflag.Bool("t1", false, "test flag one (bool)")
test2Flag = pflag.Bool("t2", false, "test another flag (bool)")
test3Flag = pflag.Int("t3", 5, "test a third flag (int)")
)
var stdout io.Writer = os.Stdout
var stderr io.Writer = os.Stderr
func main() {
pflag.Usage = func() {
usage := "Usage: %s [<options>] [<command>] [<command-args>] ...\n\n"
usage += "Flags:\n"
fmt.Fprintf(stderr, usage, os.Args[0])
pflag.PrintDefaults()
}
pflag.Parse()
fmt.Fprintf(stderr, "t1=%v t2=%v t3=%v\n#args=%v command-with-args=%v\n",
*test1Flag, *test2Flag, *test3Flag,
pflag.NArg(), pflag.Args())
}
The following examples show undesirable processing happening (but it's technically correct, in that nothing in the above code tells pflags to stop processing options after seeing the first non-option):
[1] craig@doe:~/.go/src/github.com/jcburley/wrapit$ ./wrapit
t1=false t2=false t3=5
#args=0 command-with-args=[]
[1] craig@doe:~/.go/src/github.com/jcburley/wrapit$ ./wrapit x a b --t1 --t3 6
t1=true t2=false t3=6
#args=3 command-with-args=[x a b]
[1] craig@doe:~/.go/src/github.com/jcburley/wrapit$ ./wrapit --t2 x --t3 7 a b --t1 --t3 6
t1=true t2=true t3=6
#args=3 command-with-args=[x a b]
[1] craig@doe:~/.go/src/github.com/jcburley/wrapit$
The desired outputs would be:
[1] craig@doe:~/.go/src/github.com/jcburley/wrapit$ ./wrapit # Same output.
t1=false t2=false t3=5
#args=0 command-with-args=[]
[1] craig@doe:~/.go/src/github.com/jcburley/wrapit$ ./wrapit x a b --t1 --t3 6
t1=false t2=false t3=5
#args=6 command-with-args=[x a b --t1 --t3 6]
[1] craig@doe:~/.go/src/github.com/jcburley/wrapit$ ./wrapit --t2 x --t3 7 a b --t1 --t3 6
t1=false t2=true t3=5
#args=8 command-with-args=[x --t3 7 a b --t1 --t3 6]
[1] craig@doe:~/.go/src/github.com/jcburley/wrapit$
This differs from #160 in the crucial aspect that any flags, beyond the first non-option (x in the examples above), are not considered "unknown" -- they would be not processed at all, so would have no effect on the pertinent variables even if recognized.
E.g. consider the time utility:
[1] craig@doe:~/.go/src/github.com/jcburley/wrapit$ time echo hey
hey
real 0m0.000s
user 0m0.000s
sys 0m0.000s
[1] craig@doe:~/.go/src/github.com/jcburley/wrapit$ time -p echo hey
hey
real 0.00
user 0.00
sys 0.00
[1] craig@doe:~/.go/src/github.com/jcburley/wrapit$ time echo hey -p
hey -p
real 0m0.000s
user 0m0.000s
sys 0m0.000s
[1] craig@doe:~/.go/src/github.com/jcburley/wrapit$
Here, the -p option is not interpreted to have its meaning when it appears after the first non-option (echo), so it is passed, unscathed, to that command.