Skip to content

Commit 1aa6beb

Browse files
committed
Refactor + fixes
1 parent d495eab commit 1aa6beb

11 files changed

+212
-10132
lines changed

pkg/applyconfigurations/gen.go

Lines changed: 74 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424
"go/types"
2525
"io"
2626
"path/filepath"
27-
"regexp"
2827
"sort"
2928
"strings"
3029

@@ -37,11 +36,19 @@ import (
3736
// Based on deepcopy gen but with legacy marker support removed.
3837

3938
var (
40-
enablePkgMarker = markers.Must(markers.MakeDefinition("kubebuilder:object:generate", markers.DescribesPackage, false))
41-
enableTypeMarker = markers.Must(markers.MakeDefinition("kubebuilder:object:generate", markers.DescribesType, false))
42-
isObjectMarker = markers.Must(markers.MakeDefinition("kubebuilder:object:root", markers.DescribesType, false))
39+
enablePkgMarker = markers.Must(markers.MakeDefinition("kubebuilder:ac:generate", markers.DescribesPackage, false))
40+
enableTypeMarker = markers.Must(markers.MakeDefinition("kubebuilder:ac:generate", markers.DescribesType, false))
41+
isObjectMarker = markers.Must(markers.MakeDefinition("kubebuilder:ac:root", markers.DescribesType, false))
4342
)
4443

44+
var importMapping = map[string]string{
45+
"k8s.io/apimachinery/pkg/apis/": "k8s.io/client-go/applyconfigurations/",
46+
"k8s.io/api/": "k8s.io/client-go/applyconfigurations/",
47+
}
48+
49+
const importPathSuffix = "ac"
50+
const packageFileName = "zz_generated.applyconfigurations.go"
51+
4552
// +controllertools:marker:generateHelp
4653

4754
// Generator generates code containing apply configuration type implementations.
@@ -102,21 +109,23 @@ func genObjectInterface(info *markers.TypeInfo) bool {
102109
return false
103110
}
104111

105-
func groupAndPackageVersion(pkg string) string {
106-
parts := strings.Split(pkg, "/")
107-
return parts[len(parts)-2] + "/" + parts[len(parts)-1]
112+
func createApplyConfigPackage(universe *Universe, pkg *loader.Package) *loader.Package {
113+
newPkg := &loader.Package{Package: &packages.Package{}}
114+
dir := filepath.Dir(pkg.CompiledGoFiles[0])
115+
// TODO|jefftree: This forces the package to live in a new "ac" directory. Is this code the best way to accomplish the task?
116+
newPkg.CompiledGoFiles = append(newPkg.CompiledGoFiles, dir + "/" + importPathSuffix+"/")
117+
return newPkg
108118
}
109119

110-
func createApplyConfigPackage(universe Universe, pkg *loader.Package) *loader.Package {
111-
newPkg := &loader.Package{Package: &packages.Package{}}
120+
type PkgInfo struct {
121+
objGenCtx *ObjectGenCtx
122+
pkg *loader.Package
123+
used bool
124+
typeInfo []types.Type
125+
}
112126

113-
if filepath.Dir(pkg.CompiledGoFiles[0]) == universe.baseFilePath {
114-
newPkg.CompiledGoFiles = append(newPkg.CompiledGoFiles, universe.baseFilePath+"/"+universe.importPathSuffix+"/")
115-
} else {
116-
desiredPath := universe.baseFilePath + "/" + universe.importPathSuffix + "/" + groupAndPackageVersion(pkg.PkgPath) + "/"
117-
newPkg.CompiledGoFiles = append(newPkg.CompiledGoFiles, desiredPath)
118-
}
119-
return newPkg
127+
func (p *PkgInfo) GenerateTypes() {
128+
p.typeInfo = p.objGenCtx.generateEligibleTypes(p.pkg)
120129
}
121130

122131
func (d Generator) Generate(ctx *genall.GenerationContext) error {
@@ -140,29 +149,17 @@ func (d Generator) Generate(ctx *genall.GenerationContext) error {
140149
var pkgList []*loader.Package
141150
visited := make(map[string]*loader.Package)
142151

143-
//TODO|jefftree: This might cause problems if multiple packages are provided
144-
crdRoot := ctx.Roots[0]
145-
146152
for _, root := range ctx.Roots {
153+
visited[root.PkgPath] = root
147154
pkgList = append(pkgList, root)
148155
}
149156

150-
for len(pkgList) != 0 {
151-
pkg := pkgList[0]
152-
pkgList = pkgList[1:]
153-
if _, ok := visited[pkg.PkgPath]; ok {
154-
continue
155-
}
156-
157-
visited[pkg.PkgPath] = pkg
158-
157+
for _, pkg := range pkgList {
159158
for _, imp := range pkg.Imports() {
160-
// Only index k8s types
161-
match, _ := regexp.MatchString("k8s.io/.*apis?/.+", imp.PkgPath)
162-
if !match {
159+
if _, ok := visited[imp.PkgPath]; ok {
163160
continue
164161
}
165-
pkgList = append(pkgList, imp)
162+
visited[imp.PkgPath] = imp
166163
}
167164
}
168165

@@ -171,21 +168,15 @@ func (d Generator) Generate(ctx *genall.GenerationContext) error {
171168
eligibleTypes = append(eligibleTypes, objGenCtx.generateEligibleTypes(pkg)...)
172169
}
173170

174-
universe := Universe{
175-
eligibleTypes: eligibleTypes,
176-
baseImportPath: crdRoot.PkgPath,
177-
importPathSuffix: "ac",
178-
baseFilePath: filepath.Dir(crdRoot.CompiledGoFiles[0]),
171+
universe := &Universe{
172+
eligibleTypes: eligibleTypes,
179173
}
180174

181-
// universe.baseImportPath = "k8s.io/client-go/applyconfigurations"
182-
183-
for _, pkg := range visited {
175+
for _, pkg := range pkgList {
184176
outContents := objGenCtx.generateForPackage(universe, pkg)
185177
if outContents == nil {
186178
continue
187179
}
188-
189180
newPkg := createApplyConfigPackage(universe, pkg)
190181
writeOut(ctx, newPkg, outContents)
191182
}
@@ -242,15 +233,49 @@ func (ctx *ObjectGenCtx) generateEligibleTypes(root *loader.Package) []types.Typ
242233

243234
type Universe struct {
244235
eligibleTypes []types.Type
245-
baseImportPath string
246-
importPathSuffix string
247-
baseFilePath string
236+
}
237+
238+
func (u *Universe) existingApplyConfig(typeInfo *types.Named, pkgPath string) (string, bool) {
239+
for prefix, replacePath := range importMapping {
240+
if strings.HasPrefix(pkgPath, prefix) {
241+
path := replacePath + strings.TrimPrefix(pkgPath, prefix)
242+
return path, true
243+
}
244+
}
245+
return "", false
246+
}
247+
248+
func (u *Universe) IsApplyConfigGenerated(typeInfo *types.Named, pkgPath string) bool {
249+
exists := false
250+
for _, b := range u.eligibleTypes {
251+
if b == typeInfo {
252+
exists = true
253+
break
254+
}
255+
}
256+
return exists
257+
}
258+
259+
func (u *Universe) GetApplyConfigPath(typeInfo *types.Named, pkgPath string) (string, bool) {
260+
isApplyConfigGenerated := u.IsApplyConfigGenerated(typeInfo, pkgPath)
261+
if path, ok := u.existingApplyConfig(typeInfo, pkgPath); ok {
262+
if isApplyConfigGenerated {
263+
return path, true
264+
} else {
265+
return pkgPath, false
266+
}
267+
}
268+
// ApplyConfig is necessary but location is not explicitly specified. Assume the ApplyConfig exists at the below directory
269+
if isApplyConfigGenerated {
270+
return pkgPath + "/" + importPathSuffix, true
271+
}
272+
return pkgPath, false
248273
}
249274

250275
// generateForPackage generates apply configuration implementations for
251276
// types in the given package, writing the formatted result to given writer.
252277
// May return nil if source could not be generated.
253-
func (ctx *ObjectGenCtx) generateForPackage(universe Universe, root *loader.Package) []byte {
278+
func (ctx *ObjectGenCtx) generateForPackage(universe *Universe, root *loader.Package) []byte {
254279
byType := make(map[string][]byte)
255280
imports := &importsList{
256281
byPath: make(map[string]string),
@@ -274,17 +299,17 @@ func (ctx *ObjectGenCtx) generateForPackage(universe Universe, root *loader.Pack
274299
codeWriter: &codeWriter{out: outContent},
275300
}
276301

277-
copyCtx.GenerateTypesFor(&universe, root, info)
302+
copyCtx.GenerateTypesFor(universe, root, info)
278303
for _, field := range info.Fields {
279304
if field.Name != "" {
280-
copyCtx.GenerateMemberSet(&universe, field, root, info)
305+
copyCtx.GenerateMemberSet(universe, field, root, info)
281306
}
282307
}
283308

284309
copyCtx.GenerateStructConstructor(root, info)
285310

286311
if isRootType(info) {
287-
copyCtx.GenerateTypeGetter(&universe, root, info)
312+
copyCtx.GenerateRootFunctions(universe, root, info)
288313
}
289314

290315
outBytes := outContent.Bytes()
@@ -335,7 +360,7 @@ func writeTypes(pkg *loader.Package, out io.Writer, byType map[string][]byte) {
335360
// writeFormatted outputs the given code, after gofmt-ing it. If we couldn't gofmt,
336361
// we write the unformatted code for debugging purposes.
337362
func writeOut(ctx *genall.GenerationContext, root *loader.Package, outBytes []byte) {
338-
outputFile, err := ctx.Open(root, "zz_generated.applyconfigurations.go")
363+
outputFile, err := ctx.Open(root, packageFileName)
339364
if err != nil {
340365
root.AddError(err)
341366
return

0 commit comments

Comments
 (0)