github.com/jmigpin/editor@v1.6.0/util/flagutil/flagset.go (about) 1 package flagutil 2 3 import ( 4 "flag" 5 "strings" 6 ) 7 8 // usefull to allow unknown flags to be collected, to possibly pass them to another program. The main issue is knowning which unknown flags are boolean that won't receive a value after space (ex: -mybool main.go, main.go is not an arg to mybool). In this case, the provided map allows to correct this without having to define the flags in the flagset. 9 func ParseFlagSetSets(fs *flag.FlagSet, args []string, isBool map[string]bool) (unknownArgs, unnamedArgs, binaryArgs []string, _ error) { 10 // fs.parse stops parsing at the first non-flag 11 12 // ex: "-flag1=1 -flag2=2 main.go -arg1 -arg2" 13 // - flags are parsed until "main.go" 14 // - unknown flags go to the unknownArgs 15 // - "main.go" goes to the fl.unnamedArgs 16 // - "-arg1" "-arg2" goes to the fl.binaryArgs 17 18 // don't output help on error (will try to recover) 19 usageFn := fs.Usage 20 fs.Usage = func() {} 21 defer func() { fs.Usage = usageFn }() 22 23 for { 24 err := fs.Parse(args) 25 if err == nil { 26 break 27 } 28 if err == flag.ErrHelp { 29 return nil, nil, nil, err 30 } 31 32 // get failing arg (consumed by fs.parse, need to get from end) 33 k := len(args) - 1 - len(fs.Args()) 34 arg := args[k] 35 unknownArgs = append(unknownArgs, arg) 36 args = args[k+1:] 37 38 // if not a boolean arg, it consumes the next arg 39 name := strings.TrimLeft(arg, "-") 40 if isBool != nil && !isBool[name] { 41 haveVal := strings.Index(arg, "=") >= 1 42 if !haveVal && len(args) > 0 { 43 arg2 := args[0] 44 args = args[1:] 45 unknownArgs = append(unknownArgs, arg2) 46 } 47 } 48 } 49 50 // split unnamed from named afterwards 51 args2 := fs.Args() 52 split1, split2 := len(args2), len(args2) 53 for i, a := range args2 { 54 if a[0] == '-' { 55 split1, split2 = i, i 56 57 // special double dash case (exclude arg) 58 if a == "--" { 59 split2 = i + 1 60 } 61 62 break 63 } 64 } 65 unnamedArgs, binaryArgs = args2[:split1], args2[split2:] 66 67 return 68 }