resolveInputFlags resolves @file and - (stdin) for flags with Input sources. Must be called before Validate/DryRun/Execute so that runtime.Str() returns resolved content.
(rctx *RuntimeContext, flags []Flag)
| 1044 | // resolveInputFlags resolves @file and - (stdin) for flags with Input sources. |
| 1045 | // Must be called before Validate/DryRun/Execute so that runtime.Str() returns resolved content. |
| 1046 | func resolveInputFlags(rctx *RuntimeContext, flags []Flag) error { |
| 1047 | for _, fl := range flags { |
| 1048 | if len(fl.Input) == 0 { |
| 1049 | continue |
| 1050 | } |
| 1051 | raw, err := rctx.Cmd.Flags().GetString(fl.Name) |
| 1052 | if err != nil { |
| 1053 | return ValidationErrorf("--%s: Input is only supported for string flags", fl.Name). |
| 1054 | WithParam("--" + fl.Name) |
| 1055 | } |
| 1056 | if raw == "" { |
| 1057 | continue |
| 1058 | } |
| 1059 | |
| 1060 | // stdin: - |
| 1061 | if raw == "-" { |
| 1062 | if !slices.Contains(fl.Input, Stdin) { |
| 1063 | return ValidationErrorf("--%s does not support stdin (-)", fl.Name). |
| 1064 | WithParam("--" + fl.Name) |
| 1065 | } |
| 1066 | // A process has a single stdin, so we reject a second Input flag |
| 1067 | // trying to use `-` after the first one has already consumed it. |
| 1068 | if rctx.stdinConsumed { |
| 1069 | return ValidationErrorf("--%s: stdin (-) can only be used by one flag", fl.Name). |
| 1070 | WithParam("--"+fl.Name). |
| 1071 | WithHint("a process has a single stdin, so only one flag per call may use '-'; pass the others as @file (e.g. --%s @/path/to/file)", fl.Name) |
| 1072 | } |
| 1073 | rctx.stdinConsumed = true |
| 1074 | data, err := io.ReadAll(rctx.IO().In) |
| 1075 | if err != nil { |
| 1076 | return ValidationErrorf("--%s: failed to read from stdin: %v", fl.Name, err). |
| 1077 | WithParam("--" + fl.Name). |
| 1078 | WithCause(err) |
| 1079 | } |
| 1080 | // strip a leading UTF-8 BOM so it can't corrupt the first CSV |
| 1081 | // cell or break JSON parsing downstream. |
| 1082 | rctx.Cmd.Flags().Set(fl.Name, stripUTF8BOM(string(data))) |
| 1083 | continue |
| 1084 | } |
| 1085 | |
| 1086 | // escape: @@ → literal @ |
| 1087 | if strings.HasPrefix(raw, "@@") { |
| 1088 | rctx.Cmd.Flags().Set(fl.Name, raw[1:]) // strip first @ |
| 1089 | continue |
| 1090 | } |
| 1091 | |
| 1092 | // file: @path |
| 1093 | if strings.HasPrefix(raw, "@") { |
| 1094 | if !slices.Contains(fl.Input, File) { |
| 1095 | return ValidationErrorf("--%s does not support file input (@path)", fl.Name). |
| 1096 | WithParam("--" + fl.Name) |
| 1097 | } |
| 1098 | path := strings.TrimSpace(raw[1:]) |
| 1099 | if path == "" { |
| 1100 | return ValidationErrorf("--%s: file path cannot be empty after @", fl.Name). |
| 1101 | WithParam("--" + fl.Name) |
| 1102 | } |
| 1103 | data, err := cmdutil.ReadInputFile(rctx.FileIO(), path) |