From b7a66f6cc4386153cc9865332eb3cdcf25f0719f Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Sun, 24 May 2026 14:59:14 +0000 Subject: [PATCH] Refactor single-input config path normalization helpers --- internal/config/config.go | 52 ++++++++++++++++++++-------------- internal/config/config_test.go | 38 +++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 22 deletions(-) diff --git a/internal/config/config.go b/internal/config/config.go index 3e6cf7d..3895f03 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -212,11 +212,8 @@ func NewMergeConfig(opts MergeOptions) (Config, error) { // NewTrimConfig validates raw trim options and returns normalized config. func NewTrimConfig(opts TrimOptions) (TrimConfig, error) { - inputFile := filepath.Clean(strings.TrimSpace(opts.InputFile)) - if strings.TrimSpace(opts.InputFile) == "" { - return TrimConfig{}, errors.New("--input-file is required") - } - if err := requireFile(inputFile, "--input-file"); err != nil { + inputFile, err := normalizeSingleInputFile(opts.InputFile, "--input-file") + if err != nil { return TrimConfig{}, err } @@ -225,12 +222,9 @@ func NewTrimConfig(opts TrimOptions) (TrimConfig, error) { return TrimConfig{}, err } - reportFile := "" - if strings.TrimSpace(opts.ReportFile) != "" { - reportFile, err = normalizeOutputPath(opts.ReportFile, "--report-file") - if err != nil { - return TrimConfig{}, err - } + reportFile, err := normalizeOptionalOutputPath(opts.ReportFile, "--report-file") + if err != nil { + return TrimConfig{}, err } keep := strings.TrimSpace(opts.Keep) @@ -269,11 +263,8 @@ func NewTrimConfig(opts TrimOptions) (TrimConfig, error) { // NewNormalizeConfig validates raw normalize options and returns normalized config. func NewNormalizeConfig(opts NormalizeOptions) (NormalizeConfig, error) { - inputFile := filepath.Clean(strings.TrimSpace(opts.InputFile)) - if strings.TrimSpace(opts.InputFile) == "" { - return NormalizeConfig{}, errors.New("--input-file is required") - } - if err := requireFile(inputFile, "--input-file"); err != nil { + inputFile, err := normalizeSingleInputFile(opts.InputFile, "--input-file") + if err != nil { return NormalizeConfig{}, err } @@ -282,12 +273,9 @@ func NewNormalizeConfig(opts NormalizeOptions) (NormalizeConfig, error) { return NormalizeConfig{}, err } - reportFile := "" - if strings.TrimSpace(opts.ReportFile) != "" { - reportFile, err = normalizeOutputPath(opts.ReportFile, "--report-file") - if err != nil { - return NormalizeConfig{}, err - } + reportFile, err := normalizeOptionalOutputPath(opts.ReportFile, "--report-file") + if err != nil { + return NormalizeConfig{}, err } outputSchema, err := resolveOutputSchema(opts.OutputSchema) @@ -383,6 +371,26 @@ func normalizeInputFiles(paths []string) ([]string, error) { return normalized, nil } +func normalizeSingleInputFile(path string, flag string) (string, error) { + path = strings.TrimSpace(path) + if path == "" { + return "", fmt.Errorf("%s is required", flag) + } + + clean := filepath.Clean(path) + if err := requireFile(clean, flag); err != nil { + return "", err + } + return clean, nil +} + +func normalizeOptionalOutputPath(path string, flag string) (string, error) { + if strings.TrimSpace(path) == "" { + return "", nil + } + return normalizeOutputPath(path, flag) +} + func normalizeOutputPath(path string, flag string) (string, error) { path = strings.TrimSpace(path) if path == "" { diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 11e4bcd..905651a 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -692,6 +692,25 @@ func TestNewTrimConfigAcceptsOutputSchemaOverride(t *testing.T) { } } +func TestNewTrimConfigTreatsWhitespaceReportFileAsOmitted(t *testing.T) { + dir := t.TempDir() + input := writeTempFile(t, dir, "input.json") + output := filepath.Join(dir, "trimmed.json") + + cfg, err := NewTrimConfig(TrimOptions{ + InputFile: input, + OutputFile: output, + Keep: "1", + ReportFile: " \t ", + }) + if err != nil { + t.Fatalf("config failed: %v", err) + } + if cfg.ReportFile != "" { + t.Fatalf("report file = %q, want empty", cfg.ReportFile) + } +} + func TestNewTrimConfigRejectsInvalidOutputSchemaOverride(t *testing.T) { dir := t.TempDir() input := writeTempFile(t, dir, "input.json") @@ -812,6 +831,25 @@ func TestNewNormalizeConfigRejectsUnknownOutputModule(t *testing.T) { } } +func TestNewNormalizeConfigTreatsWhitespaceReportFileAsOmitted(t *testing.T) { + dir := t.TempDir() + input := writeTempFile(t, dir, "input.json") + output := filepath.Join(dir, "normalized.json") + + cfg, err := NewNormalizeConfig(NormalizeOptions{ + InputFile: input, + OutputFile: output, + ReportFile: "\n\t ", + OutputModules: DefaultOutputModules, + }) + if err != nil { + t.Fatalf("config failed: %v", err) + } + if cfg.ReportFile != "" { + t.Fatalf("report file = %q, want empty", cfg.ReportFile) + } +} + func assertPositiveFloatEnvValidation(t *testing.T, envName string) { t.Helper()