| 223 | } |
| 224 | |
| 225 | func wrapArgsForRun(rootCmd *cobra.Command, args []string) []string { |
| 226 | // if the first argument is not "run", we don't need to do anything. If there |
| 227 | // are 2 or fewer arguments, we also don't need to do anything because there |
| 228 | // are no flags after a non-run non-flag arg. |
| 229 | // IMPROVEMENT: technically users can pass a flag before the subcommand "run" |
| 230 | if len(args) <= 2 || args[0] != "run" || slices.Contains(args, "--") { |
| 231 | return args |
| 232 | } |
| 233 | |
| 234 | cmd, found := lo.Find( |
| 235 | rootCmd.Commands(), |
| 236 | func(item *cobra.Command) bool { return item.Name() == "run" }, |
| 237 | ) |
| 238 | if !found { |
| 239 | return args |
| 240 | } |
| 241 | _ = cmd.InheritedFlags() // bug in cobra requires this to be called to ensure flags contains inherited flags. |
| 242 | runFlags := cmd.Flags() |
| 243 | // typical args can be of the form: |
| 244 | // run --flag1 val1 -f val2 --flag3=val3 --bool-flag python --version |
| 245 | // We handle each different type of flag |
| 246 | // (flag with equals, long-form, short-form, and defaulted flags) |
| 247 | // Note that defaulted does not mean initial value, it only means flags |
| 248 | // that don't require a value. |
| 249 | // For example, --bool-flag has NoOptDefVal set to "true". |
| 250 | i := 1 |
| 251 | for i < len(args) { |
| 252 | arg := args[i] |
| 253 | if !strings.HasPrefix(arg, "-") { |
| 254 | // We found and argument that is not part of the flags, so we can stop |
| 255 | // This inserts a "--" before the first non-flag argument |
| 256 | // Turning |
| 257 | // run --flag1 val1 command --flag2 val2 |
| 258 | // into |
| 259 | // run --flag1 val1 -- command --flag2 val2 |
| 260 | return append(args[:i+1], append([]string{"--"}, args[i+1:]...)...) |
| 261 | } |
| 262 | |
| 263 | if strings.HasPrefix(arg, "-") && strings.Contains(arg, "=") { |
| 264 | // This is a flag with an equals sign, so we can skip it |
| 265 | i++ |
| 266 | continue |
| 267 | } |
| 268 | |
| 269 | var flag *pflag.Flag |
| 270 | if strings.HasPrefix(arg, "--") { |
| 271 | flag = runFlags.Lookup(strings.TrimLeft(arg, "-")) |
| 272 | } else { |
| 273 | flag = runFlags.ShorthandLookup(strings.TrimLeft(arg, "-")) |
| 274 | } |
| 275 | if flag == nil { |
| 276 | // found an invalid flag, just return args as-is |
| 277 | return args |
| 278 | } |
| 279 | if flag.NoOptDefVal == "" { |
| 280 | // This is a non-boolean flag, e.g. --flag1 val1 |
| 281 | i += 2 |
| 282 | } else { |