Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gengo: Migrate to v2 #7

Merged
merged 1 commit into from
Oct 16, 2024
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 Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ test: vet
@go build -o /tmp/$(TOOL)
$(eval TMPDIR := $(shell mktemp -d))
PKGS=$$(go list ./output_tests/... | paste -sd' ' -); \
/tmp/$(TOOL) --logtostderr --v=${LOGLEVEL} -i $$(echo $$PKGS | sed 's/ /,/g') -O zz_generated -h hack/boilerplate.txt --output-base $(TMPDIR)
/tmp/$(TOOL) --logtostderr --v=${LOGLEVEL} -O zz_generated.go -h hack/boilerplate.txt --output-base $(TMPDIR) $$PKGS
cp -r "$(TMPDIR)/github.com/cilium/deepequal-gen/." ./
rm -rf "$(TMPDIR)"
@if ! git diff --quiet HEAD; then \
Expand Down
42 changes: 42 additions & 0 deletions args/args.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
SPDX-License-Identifier: Apache-2.0
Copyright 2020 Isovalent, Inc.
*/

package args

import (
"fmt"

"github.com/spf13/pflag"
)

type Args struct {
OutputFile string
OutputBase string
BoundingDirs []string // Only deal with types rooted under these dirs.
GoHeaderFile string
}

// New returns default arguments for the generator.
func New() *Args {
return &Args{}
}

// AddFlags add the generator flags to the flag set.
func (args *Args) AddFlags(fs *pflag.FlagSet) {
fs.StringVarP(&args.OutputFile, "output-file", "O", "generated.deepequal.go",
"the name of the file to be generated")
fs.StringVarP(&args.OutputBase, "output-base", "o", args.OutputBase, "Output base; defaults to $GOPATH/src/ or ./ if $GOPATH is not set.")
fs.StringSliceVar(&args.BoundingDirs, "bounding-dirs", args.BoundingDirs,
"Comma-separated list of import paths which bound the types for which deep-copies will be generated.")
fs.StringVarP(&args.GoHeaderFile, "go-header-file", "h", args.GoHeaderFile, "File containing boilerplate header text. The string YEAR will be replaced with the current 4-digit year.")
}

// Validate checks the given arguments.
func (args *Args) Validate() error {
if len(args.OutputFile) == 0 {
return fmt.Errorf("--output-file must be specified")
}
return nil
}
105 changes: 57 additions & 48 deletions generators/deepequal.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@ package generators
import (
"fmt"
"io"
"path/filepath"
"path"
"strings"

"k8s.io/gengo/args"
"k8s.io/gengo/examples/set-gen/sets"
"k8s.io/gengo/generator"
"k8s.io/gengo/namer"
"k8s.io/gengo/types"
"k8s.io/gengo/v2"
"k8s.io/gengo/v2/generator"
"k8s.io/gengo/v2/namer"
"k8s.io/gengo/v2/types"
"k8s.io/klog/v2"

"github.com/cilium/deepequal-gen/args"
)

// CustomArgs is used tby the go2idl framework to pass args specific to this
Expand Down Expand Up @@ -52,7 +53,7 @@ func extractEnabledTypeTag(t *types.Type) *enabledTagValue {
}

func extractEnabledTag(comments []string) *enabledTagValue {
tagVals := types.ExtractCommentTags("+", comments)[tagEnabledName]
tagVals := gengo.ExtractCommentTags("+", comments)[tagEnabledName]
if tagVals == nil {
// No match for the tag.
return nil
Expand Down Expand Up @@ -93,7 +94,7 @@ func extractEnabledTag(comments []string) *enabledTagValue {
}

func extractTag(tagName string, comments []string) *enabledTagValue {
tagVals := types.ExtractCommentTags("+", comments)[tagName]
tagVals := gengo.ExtractCommentTags("+", comments)[tagName]
if tagVals == nil {
// No match for the tag.
return nil
Expand Down Expand Up @@ -146,30 +147,27 @@ func DefaultNameSystem() string {
return "public"
}

func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages {
boilerplate, err := arguments.LoadGoBoilerplate()
func GetTargets(context *generator.Context, args *args.Args) []generator.Target {
boilerplate, err := gengo.GoBoilerplate(args.GoHeaderFile, gengo.StdBuildTag, gengo.StdGeneratedBy)
if err != nil {
klog.Fatalf("Failed loading boilerplate: %v", err)
}

inputs := sets.NewString(context.Inputs...)
packages := generator.Packages{}
header := append([]byte(fmt.Sprintf("// +build !%s\n\n", arguments.GeneratedBuildTag)), boilerplate...)

boundingDirs := make([]string, 0)
if customArgs, ok := arguments.CustomArgs.(*CustomArgs); ok {
if customArgs.BoundingDirs == nil {
customArgs.BoundingDirs = context.Inputs
}
for i := range customArgs.BoundingDirs {
// Strip any trailing slashes - they are not exactly "correct" but
// this is friendlier.
boundingDirs = append(boundingDirs, strings.TrimRight(customArgs.BoundingDirs[i], "/"))
}
boundingDirs := []string{}
if args.BoundingDirs == nil {
args.BoundingDirs = context.Inputs
}
for i := range args.BoundingDirs {
// Strip any trailing slashes - they are not exactly "correct" but
// this is friendlier.
boundingDirs = append(boundingDirs, strings.TrimRight(args.BoundingDirs[i], "/"))
}

targets := []generator.Target{}

for i := range inputs {
for _, i := range context.Inputs {
klog.V(5).Infof("Considering pkg %q", i)

pkg := context.Universe[i]
if pkg == nil {
// If the input had no Go files, for example.
Expand Down Expand Up @@ -215,28 +213,31 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat

if pkgNeedsGeneration {
klog.V(3).Infof("Package %q needs generation", i)
path := pkg.Path

p := pkg.Path
// if the source path is within a /vendor/ directory (for example,
// k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/meta/v1), allow
// generation to output to the proper relative path (under vendor).
// Otherwise, the generator will create the file in the wrong location
// in the output directory.
// TODO: build a more fundamental concept in gengo for dealing with modifications
// to vendored packages.
if strings.HasPrefix(pkg.SourcePath, arguments.OutputBase) {
expandedPath := strings.TrimPrefix(pkg.SourcePath, arguments.OutputBase)
if strings.HasPrefix(pkg.Dir, args.OutputBase) {
expandedPath := strings.TrimPrefix(pkg.Dir, args.OutputBase)
if strings.Contains(expandedPath, "/vendor/") {
path = expandedPath
p = expandedPath
}
}
packages = append(packages,
&generator.DefaultPackage{
PackageName: strings.Split(filepath.Base(pkg.Path), ".")[0],
PackagePath: path,
HeaderText: header,
GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) {

targets = append(targets,
&generator.SimpleTarget{
PkgName: strings.Split(path.Base(pkg.Path), ".")[0],
PkgPath: p,
PkgDir: path.Join(args.OutputBase, p), // output pkg is the same as the input
HeaderComment: boilerplate,
GeneratorsFunc: func(c *generator.Context) (generators []generator.Generator) {
return []generator.Generator{
NewGenDeepEqual(arguments.OutputFileBaseName, pkg.Path, boundingDirs, ptagValue == tagValuePackage, ptagRegister),
NewGenDeepEqual(args.OutputFile, pkg.Path, boundingDirs, ptagValue == tagValuePackage, ptagRegister),
}
},
FilterFunc: func(c *generator.Context, t *types.Type) bool {
Expand All @@ -245,23 +246,23 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
})
}
}
return packages
return targets
}

// genDeepEqual produces a file with autogenerated deep-copy functions.
type genDeepEqual struct {
generator.DefaultGen
generator.GoGenerator
targetPackage string
boundingDirs []string
allTypes bool
registerTypes bool
imports namer.ImportTracker
}

func NewGenDeepEqual(sanitizedName, targetPackage string, boundingDirs []string, allTypes, registerTypes bool) generator.Generator {
func NewGenDeepEqual(outputFilename, targetPackage string, boundingDirs []string, allTypes, registerTypes bool) generator.Generator {
return &genDeepEqual{
DefaultGen: generator.DefaultGen{
OptionalName: sanitizedName,
GoGenerator: generator.GoGenerator{
OutputFilename: outputFilename,
},
targetPackage: targetPackage,
boundingDirs: boundingDirs,
Expand Down Expand Up @@ -347,11 +348,11 @@ func deepEqualMethod(t *types.Type) (*types.Signature, error) {
if len(f.Signature.Parameters) != 1 {
return nil, fmt.Errorf("type %v: invalid %s signature, expected exactly one parameter", t, methodName)
}
if len(f.Signature.Results) != 1 || f.Signature.Results[0].Name.Name != "bool" {
if len(f.Signature.Results) != 1 || f.Signature.Results[0].Type.Name.Name != "bool" {
return nil, fmt.Errorf("type %v: invalid %s signature, expected bool result type", t, methodName)
}

ptrParam := f.Signature.Parameters[0].Kind == types.Pointer && f.Signature.Parameters[0].Elem.Name == t.Name
ptrParam := f.Signature.Parameters[0].Type.Kind == types.Pointer && f.Signature.Parameters[0].Type.Elem.Name == t.Name

if !ptrParam {
return nil, fmt.Errorf("type %v: invalid %s signature, expected parameter of type *%s", t, methodName, t.Name.Name)
Expand Down Expand Up @@ -808,11 +809,19 @@ func createFakeMethodEntries(pkg *types.Package, allTypes bool) {
Kind: types.Pointer,
Elem: &types.Type{Name: t.Name},
},
Parameters: []*types.Type{{
Kind: types.Pointer,
Elem: &types.Type{Name: t.Name},
}},
Results: []*types.Type{types.Bool},
Parameters: []*types.ParamResult{
{
Type: &types.Type{
Kind: types.Pointer,
Elem: &types.Type{Name: t.Name},
},
},
},
Results: []*types.ParamResult{
{
Type: types.Bool,
},
},
CommentLines: []string{fakeCommentLine},
},
}
Expand Down
68 changes: 39 additions & 29 deletions generators/deepequal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ package generators
import (
"testing"

"k8s.io/gengo/types"
"k8s.io/gengo/v2/types"
)

func Test_isRootedUnder(t *testing.T) {
Expand Down Expand Up @@ -124,8 +124,8 @@ func Test_deepEqualMethod(t *testing.T) {
Kind: types.Pointer,
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
},
Parameters: []*types.Type{},
Results: []*types.Type{},
Parameters: []*types.ParamResult{},
Results: []*types.ParamResult{},
},
},
},
Expand All @@ -146,8 +146,8 @@ func Test_deepEqualMethod(t *testing.T) {
Kind: types.Pointer,
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
},
Parameters: []*types.Type{},
Results: []*types.Type{},
Parameters: []*types.ParamResult{},
Results: []*types.ParamResult{},
},
},
},
Expand All @@ -169,16 +169,17 @@ func Test_deepEqualMethod(t *testing.T) {
Kind: types.Pointer,
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
},
Parameters: []*types.Type{
Parameters: []*types.ParamResult{
{
Kind: types.Pointer,
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
Type: &types.Type{
Kind: types.Pointer,
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
},
},
},
Results: []*types.Type{
Results: []*types.ParamResult{
{
Name: types.Name{Name: "int"},
Kind: types.Builtin,
Type: &types.Type{Name: types.Name{Name: "int"}, Kind: types.Builtin},
},
},
},
Expand All @@ -202,10 +203,12 @@ func Test_deepEqualMethod(t *testing.T) {
Kind: types.Pointer,
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
},
Parameters: []*types.Type{
{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
Parameters: []*types.ParamResult{
{
Type: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
},
},
Results: []*types.Type{},
Results: []*types.ParamResult{},
},
},
},
Expand All @@ -224,10 +227,12 @@ func Test_deepEqualMethod(t *testing.T) {
Kind: types.Func,
Signature: &types.Signature{
Receiver: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
Parameters: []*types.Type{
{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
Parameters: []*types.ParamResult{
{
Type: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
},
},
Results: []*types.Type{},
Results: []*types.ParamResult{},
},
},
},
Expand All @@ -246,16 +251,17 @@ func Test_deepEqualMethod(t *testing.T) {
Kind: types.Func,
Signature: &types.Signature{
Receiver: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
Parameters: []*types.Type{
Parameters: []*types.ParamResult{
{
Kind: types.Pointer,
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
Type: &types.Type{
Kind: types.Pointer,
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
},
},
},
Results: []*types.Type{
Results: []*types.ParamResult{
{
Name: types.Name{Name: "bool"},
Kind: types.Builtin,
Type: &types.Type{Name: types.Name{Name: "bool"}, Kind: types.Builtin},
},
},
},
Expand All @@ -278,16 +284,20 @@ func Test_deepEqualMethod(t *testing.T) {
Kind: types.Pointer,
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
},
Parameters: []*types.Type{
Parameters: []*types.ParamResult{
{
Kind: types.Pointer,
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
Type: &types.Type{
Kind: types.Pointer,
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
},
},
},
Results: []*types.Type{
Results: []*types.ParamResult{
{
Name: types.Name{Name: "bool"},
Kind: types.Builtin,
Type: &types.Type{
Name: types.Name{Name: "bool"},
Kind: types.Builtin,
},
},
},
},
Expand Down
Loading