Skip to content

Commit 3e5824d

Browse files
committed
refactor: reduce code duplication in config validation
- Merge validateSpawnCommands and validateRecycleCommands into generic validateTemplates helper - Extract extractFieldErrors helper to unify error extraction in outputJSON and outputText
1 parent 92e1fa1 commit 3e5824d

2 files changed

Lines changed: 31 additions & 53 deletions

File tree

internal/commands/cmd_config_validate.go

Lines changed: 24 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -81,56 +81,46 @@ func (cmd *ConfigValidateCmd) outputJSON(c *cli.Command, validationErr error, wa
8181
Warnings: warnings,
8282
}
8383

84-
if validationErr != nil {
85-
var fieldErrs criterio.FieldErrors
86-
if errors.As(validationErr, &fieldErrs) {
87-
for _, fe := range fieldErrs {
88-
out.Errors = append(out.Errors, fieldError{
89-
Field: fe.Field,
90-
Message: fe.Err.Error(),
91-
})
92-
}
93-
} else {
94-
out.Errors = append(out.Errors, fieldError{
95-
Message: validationErr.Error(),
96-
})
97-
}
84+
for _, fe := range extractFieldErrors(validationErr) {
85+
out.Errors = append(out.Errors, fieldError{Field: fe.Field, Message: fe.Err.Error()})
9886
}
9987

10088
enc := json.NewEncoder(c.Root().Writer)
10189
enc.SetIndent("", " ")
10290
return enc.Encode(out)
10391
}
10492

93+
// extractFieldErrors extracts field errors from a validation error.
94+
func extractFieldErrors(err error) criterio.FieldErrors {
95+
if err == nil {
96+
return nil
97+
}
98+
var fieldErrs criterio.FieldErrors
99+
if errors.As(err, &fieldErrs) {
100+
return fieldErrs
101+
}
102+
return criterio.FieldErrors{{Err: err}}
103+
}
104+
105105
func (cmd *ConfigValidateCmd) outputText(p *printer.Printer, validationErr error, warnings []config.ValidationWarning) error {
106-
// Print errors first (grouped)
107-
errorCount := 0
108-
if validationErr != nil {
109-
p.Printf("Errors")
106+
fieldErrs := extractFieldErrors(validationErr)
110107

111-
var fieldErrs criterio.FieldErrors
112-
if errors.As(validationErr, &fieldErrs) {
113-
errorCount = len(fieldErrs)
114-
for _, fe := range fieldErrs {
115-
if fe.Field != "" {
116-
p.Printf(" %s %s: %s", printer.Cross, fe.Field, fe.Err.Error())
117-
} else {
118-
p.Printf(" %s %s", printer.Cross, fe.Err.Error())
119-
}
108+
if len(fieldErrs) > 0 {
109+
p.Printf("Errors")
110+
for _, fe := range fieldErrs {
111+
if fe.Field != "" {
112+
p.Printf(" %s %s: %s", printer.Cross, fe.Field, fe.Err.Error())
113+
} else {
114+
p.Printf(" %s %s", printer.Cross, fe.Err.Error())
120115
}
121-
} else {
122-
errorCount = 1
123-
p.Printf(" %s %s", printer.Cross, validationErr.Error())
124116
}
125117
}
126118

127-
// Print warnings second (grouped)
128119
if len(warnings) > 0 {
129-
if errorCount > 0 {
120+
if len(fieldErrs) > 0 {
130121
p.Printf("")
131122
}
132123
p.Printf("Warnings")
133-
134124
for _, warn := range warnings {
135125
msg := warn.Message
136126
if warn.Item != "" {
@@ -140,7 +130,6 @@ func (cmd *ConfigValidateCmd) outputText(p *printer.Printer, validationErr error
140130
}
141131
}
142132

143-
// Print summary
144133
p.Printf("")
145134
if validationErr == nil {
146135
if len(warnings) > 0 {
@@ -151,6 +140,6 @@ func (cmd *ConfigValidateCmd) outputText(p *printer.Printer, validationErr error
151140
return nil
152141
}
153142

154-
p.Errorf("%d error(s), %d warning(s)", errorCount, len(warnings))
143+
p.Errorf("%d error(s), %d warning(s)", len(fieldErrs), len(warnings))
155144
return cli.Exit("", 1)
156145
}

internal/core/config/validate.go

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ func (c *Config) ValidateDeep(configPath string) error {
4949

5050
return criterio.ValidateStruct(
5151
c.validateFileAccess(configPath),
52-
c.validateSpawnCommands(),
53-
c.validateRecycleCommands(),
52+
validateTemplates("commands.spawn", c.Commands.Spawn, SpawnTemplateData{}),
53+
validateTemplates("commands.recycle", c.Commands.Recycle, RecycleTemplateData{}),
5454
c.validateHooks(),
5555
c.validateKeybindingTemplates(),
5656
)
@@ -137,23 +137,12 @@ func isDirectoryOrNotExist(path string) error {
137137
return nil
138138
}
139139

140-
// validateSpawnCommands checks template syntax for spawn commands.
141-
func (c *Config) validateSpawnCommands() error {
140+
// validateTemplates checks template syntax for a slice of command templates.
141+
func validateTemplates(fieldPrefix string, commands []string, data any) error {
142142
var errs criterio.FieldErrorsBuilder
143-
for i, cmd := range c.Commands.Spawn {
144-
if err := validateTemplate(cmd, SpawnTemplateData{}); err != nil {
145-
errs = errs.Append(fmt.Sprintf("commands.spawn[%d]", i), fmt.Errorf("template error: %w", err))
146-
}
147-
}
148-
return errs.ToError()
149-
}
150-
151-
// validateRecycleCommands checks template syntax for recycle commands.
152-
func (c *Config) validateRecycleCommands() error {
153-
var errs criterio.FieldErrorsBuilder
154-
for i, cmd := range c.Commands.Recycle {
155-
if err := validateTemplate(cmd, RecycleTemplateData{}); err != nil {
156-
errs = errs.Append(fmt.Sprintf("commands.recycle[%d]", i), fmt.Errorf("template error: %w", err))
143+
for i, cmd := range commands {
144+
if err := validateTemplate(cmd, data); err != nil {
145+
errs = errs.Append(fmt.Sprintf("%s[%d]", fieldPrefix, i), fmt.Errorf("template error: %w", err))
157146
}
158147
}
159148
return errs.ToError()

0 commit comments

Comments
 (0)