Share source diagnostic CLI parsing

This commit is contained in:
2026-06-02 18:40:17 +00:00
parent 42fb4aa82a
commit 4b6a0a3b74
4 changed files with 77 additions and 46 deletions

View File

@@ -2,7 +2,6 @@ package cli
import (
"context"
"flag"
"fmt"
"io"
@@ -14,33 +13,17 @@ func inspectCommand(ctx context.Context, args []string, stdout, stderr io.Writer
printInspectHelp(stdout)
return exitOK
}
flags := flag.NewFlagSet("inspect", flag.ContinueOnError)
flags.SetOutput(stderr)
configPath := flags.String("config", "", "path to config file")
pipelineID := flags.String("pipeline", "", "pipeline id")
bundlePath := flags.String("bundle", "", "source-root-relative bundle path")
formatFlag := addFormatFlag(flags)
if err := flags.Parse(args); err != nil {
return exitUsage
}
format, ok := parseOutputFormat(stderr, "inspect", *formatFlag)
parsed, ok := parseSourceDiagnosticArgs(stderr, "inspect", args)
if !ok {
return exitUsage
}
path, ok := parseOptionalPathArg(stderr, "inspect", flags.Args())
if !ok {
return exitUsage
}
if !validateInspectModeOK(stderr, "inspect", path, *configPath, *pipelineID, *bundlePath) {
return exitUsage
}
if err := app.Inspect(ctx, app.InspectOptions{
Path: path,
ConfigPath: *configPath,
PipelineID: *pipelineID,
BundlePath: *bundlePath,
Path: parsed.Path,
ConfigPath: parsed.ConfigPath,
PipelineID: parsed.PipelineID,
BundlePath: parsed.BundlePath,
Stdout: stdout,
OutputFormat: format,
OutputFormat: parsed.OutputFormat,
}); err != nil {
return fail(stderr, err)
}

View File

@@ -217,12 +217,24 @@ func TestExecuteValidateArgs(t *testing.T) {
wantCode: exitUsage,
wantStderr: "requires --config",
},
{
name: "bundle without config",
args: []string{"validate", "--bundle", "daily"},
wantCode: exitUsage,
wantStderr: "requires --config",
},
{
name: "config without pipeline",
args: []string{"validate", "--config", "config.yml"},
wantCode: exitUsage,
wantStderr: "requires --pipeline",
},
{
name: "invalid format",
args: []string{"validate", "--format", "xml", validPath},
wantCode: exitUsage,
wantStderr: "format must be text or json",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@@ -343,12 +355,24 @@ func TestExecuteInspectArgs(t *testing.T) {
wantCode: exitUsage,
wantStderr: "requires --config",
},
{
name: "bundle without config",
args: []string{"inspect", "--bundle", "daily"},
wantCode: exitUsage,
wantStderr: "requires --config",
},
{
name: "config without pipeline",
args: []string{"inspect", "--config", "config.yml"},
wantCode: exitUsage,
wantStderr: "requires --pipeline",
},
{
name: "invalid format",
args: []string{"inspect", "--format", "xml", validPath},
wantCode: exitUsage,
wantStderr: "format must be text or json",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

View File

@@ -1,10 +1,51 @@
package cli
import (
"flag"
"fmt"
"io"
"gitea.maximumdirect.net/eric/distributor/internal/app"
)
type sourceDiagnosticArgs struct {
Path string
ConfigPath string
PipelineID string
BundlePath string
OutputFormat app.OutputFormat
}
func parseSourceDiagnosticArgs(stderr io.Writer, command string, args []string) (sourceDiagnosticArgs, bool) {
flags := flag.NewFlagSet(command, flag.ContinueOnError)
flags.SetOutput(stderr)
configPath := flags.String("config", "", "path to config file")
pipelineID := flags.String("pipeline", "", "pipeline id")
bundlePath := flags.String("bundle", "", "source-root-relative bundle path")
formatFlag := addFormatFlag(flags)
if err := flags.Parse(args); err != nil {
return sourceDiagnosticArgs{}, false
}
format, ok := parseOutputFormat(stderr, command, *formatFlag)
if !ok {
return sourceDiagnosticArgs{}, false
}
path, ok := parseOptionalPathArg(stderr, command, flags.Args())
if !ok {
return sourceDiagnosticArgs{}, false
}
if !validateInspectModeOK(stderr, command, path, *configPath, *pipelineID, *bundlePath) {
return sourceDiagnosticArgs{}, false
}
return sourceDiagnosticArgs{
Path: path,
ConfigPath: *configPath,
PipelineID: *pipelineID,
BundlePath: *bundlePath,
OutputFormat: format,
}, true
}
func validateInspectModeOK(stderr io.Writer, command, path, configPath, pipelineID, bundlePath string) bool {
configMode := configPath != "" || pipelineID != "" || bundlePath != ""
if !configMode {

View File

@@ -2,7 +2,6 @@ package cli
import (
"context"
"flag"
"fmt"
"io"
@@ -14,33 +13,17 @@ func validateCommand(ctx context.Context, args []string, stdout, stderr io.Write
printValidateHelp(stdout)
return exitOK
}
flags := flag.NewFlagSet("validate", flag.ContinueOnError)
flags.SetOutput(stderr)
configPath := flags.String("config", "", "path to config file")
pipelineID := flags.String("pipeline", "", "pipeline id")
bundlePath := flags.String("bundle", "", "source-root-relative bundle path")
formatFlag := addFormatFlag(flags)
if err := flags.Parse(args); err != nil {
return exitUsage
}
format, ok := parseOutputFormat(stderr, "validate", *formatFlag)
parsed, ok := parseSourceDiagnosticArgs(stderr, "validate", args)
if !ok {
return exitUsage
}
path, ok := parseOptionalPathArg(stderr, "validate", flags.Args())
if !ok {
return exitUsage
}
if !validateInspectModeOK(stderr, "validate", path, *configPath, *pipelineID, *bundlePath) {
return exitUsage
}
if err := app.Validate(ctx, app.ValidateOptions{
Path: path,
ConfigPath: *configPath,
PipelineID: *pipelineID,
BundlePath: *bundlePath,
Path: parsed.Path,
ConfigPath: parsed.ConfigPath,
PipelineID: parsed.PipelineID,
BundlePath: parsed.BundlePath,
Stdout: stdout,
OutputFormat: format,
OutputFormat: parsed.OutputFormat,
}); err != nil {
return fail(stderr, err)
}