// filterArgsByFlagSet returns a list of args which are parsed by the given flag set // and another list with those which do not match func filterArgsByFlagSet(args []string, flags *pflag.FlagSet) ([]string, []string) { matched := []string{} notMatched := []string{} for _, arg := range args { err := flags.Parse([]string{arg}) if err != nil { notMatched = append(notMatched, arg) } else { matched = append(matched, arg) } } return matched, notMatched }
// parseApps looks through the args for support of per-app argument lists delimited with "--" and "---". // Between per-app argument lists flags.Parse() is called using the supplied FlagSet. // Anything not consumed by flags.Parse() and not found to be a per-app argument list is treated as an image. // allowAppArgs controls whether "--" prefixed per-app arguments will be accepted or not. func parseApps(al *apps.Apps, args []string, flags *pflag.FlagSet, allowAppArgs bool) error { nAppsLastAppArgs := al.Count() // valid args here may either be: // not-"--"; flags handled by *flags or an image specifier // "--"; app arguments begin // "---"; conclude app arguments // between "--" and "---" pairs anything is permitted. inAppArgs := false for i := 0; i < len(args); i++ { a := args[i] if inAppArgs { switch a { case "---": // conclude this app's args inAppArgs = false default: // keep appending to this app's args app := al.Last() app.Args = append(app.Args, a) } } else { switch a { case "--": if !allowAppArgs { return fmt.Errorf("app arguments unsupported") } // begin app's args inAppArgs = true // catch some likely mistakes if nAppsLastAppArgs == al.Count() { if al.Count() == 0 { return fmt.Errorf("an image is required before any app arguments") } return fmt.Errorf("only one set of app arguments allowed per image") } nAppsLastAppArgs = al.Count() case "---": // ignore triple dashes since they aren't images // TODO(vc): I don't think ignoring this is appropriate, probably should error; it implies malformed argv. // "---" is not an image separator, it's an optional argument list terminator. // encountering it outside of inAppArgs is likely to be "--" typoed default: // consume any potential inter-app flags if err := flags.Parse(args[i:]); err != nil { return err } nInterFlags := (len(args[i:]) - flags.NArg()) if nInterFlags > 0 { // XXX(vc): flag.Parse() annoyingly consumes the "--", reclaim it here if necessary if args[i+nInterFlags-1] == "--" { nInterFlags-- } // advance past what flags.Parse() consumed i += nInterFlags - 1 // - 1 because of i++ } else { // flags.Parse() didn't want this arg, treat as image al.Create(a) } } } } return al.Validate() }