Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ A spec flows through three stages, one per `internal/` package:

1. **parse** (`internal/parser`): load and validate the spec with libopenapi, resolve `$ref`s.
2. **analyze** (`internal/analyzer`): lower the spec into the intermediate representation (`internal/ir`): operations, params, types, pagination. This is where naming, disambiguation, and pagination detection happen.
3. **generate** (`internal/generator`): render the IR through `text/template` files (`internal/templates/*.tmpl`, embedded via `embed.go`) and post-process each file with `goimports` (`WriteFiles`).
3. **generate** (`internal/generator`): render the IR through `text/template` files (`internal/templates/*.tmpl`, embedded via `embed.go`) then `WriteFiles` fixes each file's imports against a fixed stdlib table and gofmts it (large files print in parallel chunks).

Supporting packages: `internal/naming` (OpenAPI identifier → Go identifier), `cmd/` (the Cobra CLI).

Expand Down
4 changes: 1 addition & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require (
github.com/giraffesyo/openapi-go-naming v0.1.1
github.com/pb33f/libopenapi v0.40.1
github.com/spf13/cobra v1.10.2
golang.org/x/tools v0.50.0
go.yaml.in/yaml/v4 v4.0.0-rc.6
)

require (
Expand All @@ -16,7 +16,5 @@ require (
github.com/pb33f/jsonpath v0.8.3 // indirect
github.com/pb33f/ordered-map/v2 v2.3.1 // indirect
github.com/spf13/pflag v1.0.9 // indirect
go.yaml.in/yaml/v4 v4.0.0-rc.6 // indirect
golang.org/x/mod v0.41.0 // indirect
golang.org/x/sync v0.23.0 // indirect
)
6 changes: 0 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/giraffesyo/openapi-go-naming v0.1.1 h1:5/kK3FAIPtpEpmwvPk/moYVrdlznzY9s7015nBYMsZY=
github.com/giraffesyo/openapi-go-naming v0.1.1/go.mod h1:20Q7TQ9sJpWQ5aUvmMdNlp70IRpl3JlLp6rH7dBD2ns=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/pb33f/jsonpath v0.8.3 h1:gdOUYn31vic8iRSSR4I2SEv7UQf2WxLeDcUnDPpGZNE=
Expand All @@ -31,12 +29,8 @@ github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
go.yaml.in/yaml/v4 v4.0.0-rc.6 h1:1h7H1ohdUh93/FyE4YaDa1Zh64K6VVbjF4K6WUxMtH4=
go.yaml.in/yaml/v4 v4.0.0-rc.6/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0=
golang.org/x/mod v0.41.0 h1:qJmnOUb4YB+FsEuM3HcWucdZASCPGhsX6uljO6pog0c=
golang.org/x/mod v0.41.0/go.mod h1:Ek9pY8RKWXwsWvd3rQiHYtMqkjSUV+s1Rj7j4H5Ur6o=
golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk=
golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0=
golang.org/x/tools v0.50.0 h1:c2ifzfcuY7L90lZ2aKd8S4K2NpASF08SZx9ZuJkHmSU=
golang.org/x/tools v0.50.0/go.mod h1:7ulVMw3831Mwi5EZD6RomGyffr4VFjuNYXf2BbCEAV0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
2 changes: 1 addition & 1 deletion internal/generator/e2e_combinations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func TestE2E_Combinations(t *testing.T) {

// containsCollapsed reports whether haystack holds needle once the runs of
// whitespace in both are flattened. The generated files reach this test before
// goimports aligns them, so an assertion written the way the output looks would
// gofmt aligns them, so an assertion written the way the output looks would
// depend on alignment that has not happened yet.
func containsCollapsed(haystack, needle string) bool {
return strings.Contains(strings.Join(strings.Fields(haystack), " "), strings.Join(strings.Fields(needle), " "))
Expand Down
25 changes: 18 additions & 7 deletions internal/generator/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package generator

import (
"bytes"
"errors"
"fmt"
"sync"
"text/template"

"github.com/parallelworks/openapi-client-generator/internal/ir"
Expand Down Expand Up @@ -56,13 +58,22 @@ func (g *Generator) Generate() ([]GeneratedFile, error) {
{"streaming.go.tmpl", "streaming.go"},
}

var files []GeneratedFile
for _, spec := range specs {
var buf bytes.Buffer
if err := g.templates.ExecuteTemplate(&buf, spec.tmplName, g.pkg); err != nil {
return nil, fmt.Errorf("executing template %s: %w", spec.tmplName, err)
}
files = append(files, GeneratedFile{Name: spec.fileName, Content: buf.Bytes()})
files := make([]GeneratedFile, len(specs))
errs := make([]error, len(specs))
var wg sync.WaitGroup
for i, spec := range specs {
wg.Go(func() {
var buf bytes.Buffer
if err := g.templates.ExecuteTemplate(&buf, spec.tmplName, g.pkg); err != nil {
errs[i] = fmt.Errorf("executing template %s: %w", spec.tmplName, err)
return
}
files[i] = GeneratedFile{Name: spec.fileName, Content: buf.Bytes()}
})
}
wg.Wait()
if err := errors.Join(errs...); err != nil {
return nil, err
}
return files, nil
}
15 changes: 5 additions & 10 deletions internal/generator/generator_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package generator

import (
"go/parser"
"go/token"
"strings"
"testing"

"github.com/parallelworks/openapi-client-generator/internal/ir"
"golang.org/x/tools/imports"
)

func TestGenerate_StructAndEnum(t *testing.T) {
Expand Down Expand Up @@ -127,7 +128,7 @@ func TestGenerate_StructAndEnum(t *testing.T) {
}
}

func TestGenerate_GoimportsSucceeds(t *testing.T) {
func TestGenerate_OutputParses(t *testing.T) {
pkg := &ir.Package{
Name: "testpkg",
Types: []*ir.TypeDef{
Expand Down Expand Up @@ -160,14 +161,8 @@ func TestGenerate_GoimportsSucceeds(t *testing.T) {
t.Fatal("expected at least 1 generated file")
}

// Verify goimports can process the output without error
_, err = imports.Process(files[0].Name, files[0].Content, &imports.Options{
Comments: true,
TabIndent: true,
TabWidth: 8,
})
if err != nil {
t.Errorf("goimports failed on generated output: %v\n\nRaw output:\n%s", err, string(files[0].Content))
if _, err := parser.ParseFile(token.NewFileSet(), files[0].Name, files[0].Content, parser.ParseComments); err != nil {
t.Errorf("generated output does not parse: %v\n\nRaw output:\n%s", err, string(files[0].Content))
}
}

Expand Down
Loading
Loading