Skip to content

Commit

Permalink
apply fixes from kubernetes/kubernetes#111934
Browse files Browse the repository at this point in the history
  • Loading branch information
deads2k committed Aug 22, 2022
1 parent fea40fb commit 47330cc
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 191 deletions.
5 changes: 3 additions & 2 deletions cmd/applyconfiguration-gen/args/args.go
Expand Up @@ -50,8 +50,9 @@ func NewDefaults() (*args.GeneratorArgs, *CustomArgs) {
customArgs := &CustomArgs{
ExternalApplyConfigurations: map[types.Name]string{
// Always include TypeMeta and ObjectMeta. They are sufficient for the vast majority of use cases.
{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "TypeMeta"}: "k8s.io/client-go/applyconfigurations/meta/v1",
{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "ObjectMeta"}: "k8s.io/client-go/applyconfigurations/meta/v1",
{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "TypeMeta"}: "k8s.io/client-go/applyconfigurations/meta/v1",
{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "ObjectMeta"}: "k8s.io/client-go/applyconfigurations/meta/v1",
{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "OwnerReference"}: "k8s.io/client-go/applyconfigurations/meta/v1",
},
}
genericArgs.CustomArgs = customArgs
Expand Down
17 changes: 7 additions & 10 deletions cmd/applyconfiguration-gen/args/externaltypes.go
Expand Up @@ -28,7 +28,6 @@ import (

type externalApplyConfigurationValue struct {
externals *map[types.Name]string
changed bool
}

func NewExternalApplyConfigurationValue(externals *map[types.Name]string, def []string) *externalApplyConfigurationValue {
Expand All @@ -45,10 +44,6 @@ func NewExternalApplyConfigurationValue(externals *map[types.Name]string, def []
var _ flag.Value = &externalApplyConfigurationValue{}

func (s *externalApplyConfigurationValue) set(vs []string) error {
if !s.changed {
*s.externals = map[types.Name]string{}
}

for _, input := range vs {
typ, pkg, err := parseExternalMapping(input)
if err != nil {
Expand All @@ -71,6 +66,7 @@ func (s *externalApplyConfigurationValue) Set(val string) error {
if err := s.set(vs); err != nil {
return err
}

return nil
}

Expand Down Expand Up @@ -114,12 +110,13 @@ func parseExternalMapping(mapping string) (typ types.Name, pkg string, err error
}
packageTypeStr := parts[0]
pkg = parts[1]
ptParts := strings.Split(packageTypeStr, ".")
if len(ptParts) != 2 {
return types.Name{}, "", fmt.Errorf("expected package and type of the form <package>#<typeName> but got %s", packageTypeStr)
// need to split on the *last* dot, since k8s.io (and other valid packages) have a dot in it
lastDot := strings.LastIndex(packageTypeStr, ".")
if lastDot == -1 || lastDot == len(packageTypeStr)-1 {
return types.Name{}, "", fmt.Errorf("expected package and type of the form <package>.<typeName> but got %s", packageTypeStr)
}
structPkg := ptParts[0]
structType := ptParts[1]
structPkg := packageTypeStr[:lastDot]
structType := packageTypeStr[lastDot+1:]

return types.Name{Package: structPkg, Name: structType}, pkg, nil
}
86 changes: 74 additions & 12 deletions cmd/applyconfiguration-gen/generators/applyconfiguration.go
Expand Up @@ -97,9 +97,12 @@ func (g *applyConfigurationGenerator) GenerateType(c *generator.Context, t *type
g.generateStruct(sw, typeParams)

if typeParams.Tags.GenerateClient {
if typeParams.Tags.NonNamespaced {
switch {
case !hasObjectMetaField(t):
sw.Do(clientgenTypeConstructorWithoutObjectMeta, typeParams)
case typeParams.Tags.NonNamespaced:
sw.Do(clientgenTypeConstructorNonNamespaced, typeParams)
} else {
default:
sw.Do(clientgenTypeConstructorNamespaced, typeParams)
}
if typeParams.OpenAPIType != nil {
Expand All @@ -118,7 +121,16 @@ func (g *applyConfigurationGenerator) GenerateType(c *generator.Context, t *type

func hasTypeMetaField(t *types.Type) bool {
for _, member := range t.Members {
if typeMeta.Name == member.Type.Name {
if typeMeta.Name == member.Type.Name && member.Embedded {
return true
}
}
return false
}

func hasObjectMetaField(t *types.Type) bool {
for _, member := range t.Members {
if objectMeta.Name == member.Type.Name && member.Embedded {
return true
}
}
Expand Down Expand Up @@ -157,20 +169,20 @@ func (g *applyConfigurationGenerator) generateWithFuncs(t *types.Type, typeParam
EmbeddedIn: embed,
}
if memberParams.Member.Embedded {

g.generateWithFuncs(member.Type, typeParams, sw, &memberParams)
if !jsonTags.inline {
// non-inlined embeds are nillable and need a "ensure exists" utility function
sw.Do(ensureEmbedExists, memberParams)
}
continue
}

// For slices where the items are generated apply configuration types, accept varargs of
// pointers of the type as "with" function arguments so the "with" function can be used like so:
// WithFoos(Foo().WithName("x"), Foo().WithName("y"))
if t := deref(member.Type); t.Kind == types.Slice && g.refGraph.isApplyConfig(t.Elem) {
memberParams.ArgType = &types.Type{Kind: types.Pointer, Elem: memberType.Elem}
g.generateMemberWithForSlice(sw, memberParams)
g.generateMemberWithForSlice(sw, member, memberParams)
continue
}
// Note: There are no maps where the values are generated apply configurations (because
Expand All @@ -182,7 +194,7 @@ func (g *applyConfigurationGenerator) generateWithFuncs(t *types.Type, typeParam
switch memberParams.Member.Type.Kind {
case types.Slice:
memberParams.ArgType = memberType.Elem
g.generateMemberWithForSlice(sw, memberParams)
g.generateMemberWithForSlice(sw, member, memberParams)
case types.Map:
g.generateMemberWithForMap(sw, memberParams)
default:
Expand Down Expand Up @@ -252,20 +264,39 @@ func (g *applyConfigurationGenerator) generateMemberWith(sw *generator.SnippetWr
sw.Do("}\n", memberParams)
}

func (g *applyConfigurationGenerator) generateMemberWithForSlice(sw *generator.SnippetWriter, memberParams memberParams) {
func (g *applyConfigurationGenerator) generateMemberWithForSlice(sw *generator.SnippetWriter, member types.Member, memberParams memberParams) {
memberIsPointerToSlice := member.Type.Kind == types.Pointer
if memberIsPointerToSlice {
sw.Do(ensureNonEmbedSliceExists, memberParams)
}

sw.Do("// With$.Member.Name$ adds the given value to the $.Member.Name$ field in the declarative configuration\n", memberParams)
sw.Do("// and returns the receiver, so that objects can be build by chaining \"With\" function invocations.\n", memberParams)
sw.Do("// If called multiple times, values provided by each call will be appended to the $.Member.Name$ field.\n", memberParams)
sw.Do("func (b *$.ApplyConfig.ApplyConfiguration|public$) With$.Member.Name$(values ...$.ArgType|raw$) *$.ApplyConfig.ApplyConfiguration|public$ {\n", memberParams)
g.ensureEnbedExistsIfApplicable(sw, memberParams)

if memberIsPointerToSlice {
sw.Do("b.ensure$.MemberType.Elem|public$Exists()\n", memberParams)
}

sw.Do(" for i := range values {\n", memberParams)
if memberParams.ArgType.Kind == types.Pointer {
sw.Do("if values[i] == nil {\n", memberParams)
sw.Do(" panic(\"nil value passed to With$.Member.Name$\")\n", memberParams)
sw.Do("}\n", memberParams)
sw.Do("b.$.Member.Name$ = append(b.$.Member.Name$, *values[i])\n", memberParams)

if memberIsPointerToSlice {
sw.Do("*b.$.Member.Name$ = append(*b.$.Member.Name$, *values[i])\n", memberParams)
} else {
sw.Do("b.$.Member.Name$ = append(b.$.Member.Name$, *values[i])\n", memberParams)
}
} else {
sw.Do("b.$.Member.Name$ = append(b.$.Member.Name$, values[i])\n", memberParams)
if memberIsPointerToSlice {
sw.Do("*b.$.Member.Name$ = append(*b.$.Member.Name$, values[i])\n", memberParams)
} else {
sw.Do("b.$.Member.Name$ = append(b.$.Member.Name$, values[i])\n", memberParams)
}
}
sw.Do(" }\n", memberParams)
sw.Do(" return b\n", memberParams)
Expand Down Expand Up @@ -305,6 +336,14 @@ func (b *$.ApplyConfig.ApplyConfiguration|public$) ensure$.MemberType.Elem|publi
}
`

var ensureNonEmbedSliceExists = `
func (b *$.ApplyConfig.ApplyConfiguration|public$) ensure$.MemberType.Elem|public$Exists() {
if b.$.Member.Name$ == nil {
b.$.Member.Name$ = &[]$.MemberType.Elem|raw${}
}
}
`

var clientgenTypeConstructorNamespaced = `
// $.ApplyConfig.Type|public$ constructs an declarative configuration of the $.ApplyConfig.Type|public$ type for use with
// apply.
Expand All @@ -330,6 +369,17 @@ func $.ApplyConfig.Type|public$(name string) *$.ApplyConfig.ApplyConfiguration|p
}
`

var clientgenTypeConstructorWithoutObjectMeta = `
// $.ApplyConfig.Type|public$ constructs an declarative configuration of the $.ApplyConfig.Type|public$ type for use with
// apply.
func $.ApplyConfig.Type|public$(name string) *$.ApplyConfig.ApplyConfiguration|public$ {
b := &$.ApplyConfig.ApplyConfiguration|public${}
b.WithKind("$.ApplyConfig.Type|singularKind$")
b.WithAPIVersion("$.APIVersion$")
return b
}
`

var constructorWithTypeMeta = `
// $.ApplyConfig.ApplyConfiguration|public$ constructs an declarative configuration of the $.ApplyConfig.Type|public$ type for use with
// apply.
Expand Down Expand Up @@ -375,7 +425,18 @@ func Extract$.ApplyConfig.Type|public$Status($.Struct|private$ *$.Struct|raw$, f
}
`, typeParams)
}
sw.Do(`
if !hasObjectMetaField(typeParams.Struct) {
sw.Do(`
func extract$.ApplyConfig.Type|public$($.Struct|private$ *$.Struct|raw$, fieldManager string, subresource string) (*$.ApplyConfig.ApplyConfiguration|public$, error) {
b := &$.ApplyConfig.ApplyConfiguration|public${}
err := $.ExtractInto|raw$($.Struct|private$, $.ParserFunc|raw$().Type("$.OpenAPIType$"), fieldManager, b, subresource)
if err != nil {
return nil, err
}
`, typeParams)

} else { // it has objectMeta
sw.Do(`
func extract$.ApplyConfig.Type|public$($.Struct|private$ *$.Struct|raw$, fieldManager string, subresource string) (*$.ApplyConfig.ApplyConfiguration|public$, error) {
b := &$.ApplyConfig.ApplyConfiguration|public${}
err := $.ExtractInto|raw$($.Struct|private$, $.ParserFunc|raw$().Type("$.OpenAPIType$"), fieldManager, b, subresource)
Expand All @@ -384,8 +445,9 @@ func extract$.ApplyConfig.Type|public$($.Struct|private$ *$.Struct|raw$, fieldMa
}
b.WithName($.Struct|private$.Name)
`, typeParams)
if !typeParams.Tags.NonNamespaced {
sw.Do("b.WithNamespace($.Struct|private$.Namespace)\n", typeParams)
if !typeParams.Tags.NonNamespaced {
sw.Do("b.WithNamespace($.Struct|private$.Namespace)\n", typeParams)
}
}
sw.Do(`
b.WithKind("$.ApplyConfig.Type|singularKind$")
Expand Down

0 comments on commit 47330cc

Please sign in to comment.