Skip to content

Commit

Permalink
feat: codegen version check (#259)
Browse files Browse the repository at this point in the history
  • Loading branch information
sysulq authored Dec 6, 2024
1 parent a053608 commit 2e70e2a
Show file tree
Hide file tree
Showing 11 changed files with 214 additions and 6 deletions.
1 change: 1 addition & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ tasks:
-covermode=atomic ./... ./tests/... \
-coverpkg .,./cmd/...,./internal/...,./interceptor/...
git checkout tests/case1/kod_gen_mock.go
git checkout tests/graphcase/kod_gen.go
sources:
- "**/**.go"
generates:
Expand Down
34 changes: 28 additions & 6 deletions cmd/kod/internal/generate_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"golang.org/x/tools/go/packages"

"github.com/go-kod/kod/internal/callgraph"
"github.com/go-kod/kod/internal/version"
)

const (
Expand Down Expand Up @@ -562,19 +563,14 @@ func (g *generator) generate() error {
return nil
}

// // Process components in deterministic order.
// sort.Slice(g.components, func(i, j int) bool {
// return g.components[i].intfName() < g.components[j].intfName()
// })

// Generate the file body.
var body bytes.Buffer
{
fn := func(format string, args ...interface{}) {
fmt.Fprintln(&body, fmt.Sprintf(format, args...))
}
// g.generateVersionCheck(fn)
g.generateRegisteredComponents(fn)
g.generateVersionCheck(fn)
g.generateInstanceChecks(fn)
g.generateLocalStubs(fn)

Expand Down Expand Up @@ -678,6 +674,32 @@ func (g *generator) generateFullMethodNames(p printFn) {
p(`)`)
}

func (g *generator) generateVersionCheck(p printFn) {
selfVersion := version.SelfVersion()

p(``)
p(`// CodeGen version check.`)
p("var _ kod.CodeGenLatestVersion = kod.CodeGenVersion[[%d][%d]struct{}](%s)",
version.CodeGenMajor, version.CodeGenMinor,
fmt.Sprintf("`"+`
ERROR: You generated this file with 'kod generate' %s (codegen
version %s). The generated code is incompatible with the version of the
github.com/go-kod/kod module that you're using. The kod module
version can be found in your go.mod file or by running the following command.
go list -m github.com/go-kod/kod
We recommend updating the kod module and the 'kod generate' command by
running the following.
go get github.com/go-kod/kod@latest
go install github.com/go-kod/kod/cmd/kod@latest
Then, re-run 'kod generate' and re-build your code. If the problem persists,
please file an issue at https://github.com/go-kod/kod/issues.
`+"`", selfVersion, version.CodeGenSemVersion))
}

// generateInstanceChecks generates code that checks that every component
// implementation type implements kod.InstanceOf[T] for the appropriate T.
func (g *generator) generateInstanceChecks(p printFn) {
Expand Down
19 changes: 19 additions & 0 deletions examples/helloworld/kod_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 38 additions & 0 deletions internal/version/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package version

import (
"fmt"
"runtime/debug"

"github.com/samber/lo"
)

const (
// CodeGenMajor is the major version of the generated code.
CodeGenMajor = 0
// CodeGenMinor is the minor version of the generated code.
CodeGenMinor = 1
// codeGenPatch is the patch version of the generated code.
codeGenPatch = 0
)

// CodeGenSemVersion is the version of the generated code.
var CodeGenSemVersion = SemVer{Major: CodeGenMajor, Minor: CodeGenMinor, Patch: codeGenPatch}

// SemVer represents a semantic version.
type SemVer struct {
Major int
Minor int
Patch int
}

// String returns the string representation of the semantic version.
func (v SemVer) String() string {
return fmt.Sprintf("v%d.%d.%d", v.Major, v.Minor, v.Patch)
}

// SelfVersion returns the version of the running tool binary.
func SelfVersion() string {
info := lo.Must(debug.ReadBuildInfo())
return info.Main.Version
}
19 changes: 19 additions & 0 deletions tests/case1/kod_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions tests/case2/kod_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions tests/case3/kod_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions tests/case4/kod_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions tests/case5/kod_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions tests/graphcase/kod_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package kod

import (
"github.com/go-kod/kod/internal/version"
)

// The following types are used to check, at compile time, that every
// kod_gen.go file uses the codegen API version that is linked into the binary.
type (
// CodeGenVersion is the version of the codegen API.
CodeGenVersion[_ any] string
// CodeGenLatestVersion is the latest version of the codegen API.
CodeGenLatestVersion = CodeGenVersion[[version.CodeGenMajor][version.CodeGenMinor]struct{}]
)

0 comments on commit 2e70e2a

Please sign in to comment.