shellPreprocessArgs converts positional arguments to flag arguments Values are not processed. This function is used to leverage pflags to parse flags interspersed with positional arguments, so a function's required arguments can be placed anywhere. Then we get the unprocessed flags in order to vali
( ctx context.Context, fn *modFunction, args []string, )
| 502 | // Additionally, if there's only one required argument that is a list of strings, |
| 503 | // all positional arguments are used as elements of that list. |
| 504 | func (h *shellCallHandler) shellPreprocessArgs( |
| 505 | ctx context.Context, |
| 506 | fn *modFunction, |
| 507 | args []string, |
| 508 | ) (map[string]any, []string, error) { |
| 509 | // Final map of resolved argument values |
| 510 | values := make(map[string]any, len(fn.Args)) |
| 511 | |
| 512 | flags := pflag.NewFlagSet(fn.CmdName(), pflag.ContinueOnError) |
| 513 | flags.SetOutput(io.MultiWriter( |
| 514 | interp.HandlerCtx(ctx).Stderr, |
| 515 | telemetry.SpanStdio(ctx, InstrumentationLibrary).Stderr, |
| 516 | )) |
| 517 | |
| 518 | opts := fn.OptionalArgs() |
| 519 | reqs := fn.RequiredArgs() |
| 520 | |
| 521 | // All CLI arguments are strings at first, but booleans can be omitted. |
| 522 | // We don't wan't to process values yet, just validate and consume the flags |
| 523 | // so we get the remaining positional args. |
| 524 | |
| 525 | // Add required arguments as flags so they can be specified as named arguments |
| 526 | for _, arg := range reqs { |
| 527 | name := arg.FlagName() |
| 528 | |
| 529 | switch arg.TypeDef.Kind { |
| 530 | case dagger.TypeDefKindListKind: |
| 531 | switch arg.TypeDef.AsList.ElementTypeDef.Kind { |
| 532 | case dagger.TypeDefKindBooleanKind: |
| 533 | flags.BoolSlice(name, nil, "") |
| 534 | default: |
| 535 | flags.StringSlice(name, nil, "") |
| 536 | } |
| 537 | case dagger.TypeDefKindBooleanKind: |
| 538 | flags.Bool(name, false, "") |
| 539 | default: |
| 540 | flags.String(name, "", "") |
| 541 | } |
| 542 | } |
| 543 | |
| 544 | // Add optional arguments as flags |
| 545 | for _, arg := range opts { |
| 546 | name := arg.FlagName() |
| 547 | |
| 548 | switch arg.TypeDef.Kind { |
| 549 | case dagger.TypeDefKindListKind: |
| 550 | switch arg.TypeDef.AsList.ElementTypeDef.Kind { |
| 551 | case dagger.TypeDefKindBooleanKind: |
| 552 | flags.BoolSlice(name, nil, "") |
| 553 | default: |
| 554 | flags.StringSlice(name, nil, "") |
| 555 | } |
| 556 | case dagger.TypeDefKindBooleanKind: |
| 557 | flags.Bool(name, false, "") |
| 558 | default: |
| 559 | flags.String(name, "", "") |
| 560 | } |
| 561 | } |
no test coverage detected