Skip to content

Commit 7517e09

Browse files
authored
respect output file path on gofmt failure (#2356)
When `imports.Process` rejected the generated source, `Generate()` discarded the code and stuffed a line-numbered dump of it into the returned error. The CLI then printed that error to stderr and never wrote the requested `-o` (or config `output:`) file, so users saw a huge stderr spew with no output file produced. Return the raw pre-format code from `Generate()` alongside the error, and have the CLI write it to the configured destination before exiting. The error message itself is now a single line referencing the failing source line; users can open the written file to inspect the broken code directly. `addLineNumbers` is dropped — it was only used by the removed in-error code dump. Closes: #2340
1 parent 9643421 commit 7517e09

2 files changed

Lines changed: 23 additions & 34 deletions

File tree

cmd/oapi-codegen/oapi-codegen.go

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -320,21 +320,27 @@ func main() {
320320
opts.NoVCSVersionOverride = &noVCSVersionOverride
321321
}
322322

323-
code, err := codegen.Generate(swagger, opts.Configuration)
324-
if err != nil {
325-
errExit("error generating code: %s\n", err)
323+
code, genErr := codegen.Generate(swagger, opts.Configuration)
324+
325+
// Always emit any generated code to the requested destination, even when
326+
// generation returned an error (e.g. the formatter rejected the output).
327+
// Writing to the output file lets the user inspect the broken source
328+
// directly instead of having it interleaved with stderr.
329+
if code != "" {
330+
if opts.OutputFile != "" {
331+
if err := os.MkdirAll(filepath.Dir(opts.OutputFile), 0o755); err != nil {
332+
errExit("error unable to create directory: %s\n", err)
333+
}
334+
if err := os.WriteFile(opts.OutputFile, []byte(code), 0o644); err != nil {
335+
errExit("error writing generated code to file: %s\n", err)
336+
}
337+
} else {
338+
fmt.Print(code)
339+
}
326340
}
327341

328-
if opts.OutputFile != "" {
329-
if err := os.MkdirAll(filepath.Dir(opts.OutputFile), 0o755); err != nil {
330-
errExit("error unable to create directory: %s\n", err)
331-
}
332-
err = os.WriteFile(opts.OutputFile, []byte(code), 0o644)
333-
if err != nil {
334-
errExit("error writing generated code to file: %s\n", err)
335-
}
336-
} else {
337-
fmt.Print(code)
342+
if genErr != nil {
343+
errExit("error generating code: %s\n", genErr)
338344
}
339345
}
340346

pkg/codegen/codegen.go

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -517,34 +517,17 @@ func Generate(spec *openapi3.T, opts Configuration) (string, error) {
517517

518518
outBytes, err := imports.Process(opts.PackageName+".go", []byte(goCode), nil)
519519
if err != nil {
520-
// if we don't get a line number
521520
errLine := -1
522521
var scanErr scanner.ErrorList
523522
if errors.As(err, &scanErr) && scanErr.Len() > 0 {
524-
// for now, only return the first error's information
525523
errLine = scanErr[0].Pos.Line
526524
}
527-
return "", fmt.Errorf("error formatting Go code:\n%s\nerror was: %w", addLineNumbers(goCode, errLine), err)
528-
}
529-
return string(outBytes), nil
530-
}
531-
532-
func addLineNumbers(goCode string, lineWithError int) string {
533-
var out []string
534-
lines := strings.Split(goCode, "\n")
535-
for i, line := range lines {
536-
// lines for humans start at 1
537-
lineNumber := i + 1
538-
539-
errLine := " "
540-
if lineNumber == lineWithError {
541-
errLine = "❗"
525+
if errLine > 0 {
526+
return goCode, fmt.Errorf("error formatting Go code at line %d: %w", errLine, err)
542527
}
543-
544-
out = append(out, fmt.Sprintf("%s%5d: %s", errLine, lineNumber, line))
528+
return goCode, fmt.Errorf("error formatting Go code: %w", err)
545529
}
546-
547-
return strings.Join(out, "\n")
530+
return string(outBytes), nil
548531
}
549532

550533
func GenerateTypeDefinitions(t *template.Template, swagger *openapi3.T, ops []OperationDefinition, excludeSchemas []string) (string, error) {

0 commit comments

Comments
 (0)