Skip to content

Commit

Permalink
TypeDefiners must also support RequiredImports (#158)
Browse files Browse the repository at this point in the history
* Change a few config filters to typeFilters

  - It makes more sense to avoid scanning those types,
    rather than scanning them and then not emitting them.

* Clean up how we do RequiredImports a bit
  • Loading branch information
matthchr authored Jun 30, 2020
1 parent 2506229 commit b5fbcbd
Show file tree
Hide file tree
Showing 29 changed files with 66 additions and 58 deletions.
4 changes: 2 additions & 2 deletions hack/generator/azure-arm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ typeFilters:
group: definitions
name: Expression
because: expression is an ARM template construct which doesn't belong in CRDs
exportFilters:
- action: include
version: 2020-*
because: all 2020 API versions are included
- action: exclude
- action: prune
version: '*preview'
because: preview SDK versions are excluded by default
exportFilters:
- action: exclude
group: deploymenttemplate
because: this is the "container" group that holds references to all of the other groups and as such doesn't make sense to generate
Expand Down
12 changes: 12 additions & 0 deletions hack/generator/pkg/astmodel/code_generation_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

package astmodel

import "fmt"

// CodeGenerationContext stores context about the location code-generation is occurring.
// This is required because some things (such as specific field types) are impacted by the context
// in which the field declaration occurs - for example in a file with two conflicting package references
Expand Down Expand Up @@ -34,3 +36,13 @@ func (codeGenContext *CodeGenerationContext) PackageImports() map[PackageReferen
}
return result
}

// GetImportedPackageName gets the imported packages name or an error if the package was not imported
func (codeGenContext *CodeGenerationContext) GetImportedPackageName(reference *PackageReference) (string, error) {
packageImport, ok := codeGenContext.packageImports[*reference]
if !ok {
return "", fmt.Errorf("package %s not imported", reference)
}

return packageImport.PackageName(), nil
}
5 changes: 5 additions & 0 deletions hack/generator/pkg/astmodel/enum_definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,8 @@ func (enum *EnumDefinition) createValueDeclaration(value EnumValue) ast.Spec {

return valueSpec
}

// RequiredImports returns a list of packages required by this type
func (enum *EnumDefinition) RequiredImports() []*PackageReference {
return enum.baseType.RequiredImports()
}
18 changes: 10 additions & 8 deletions hack/generator/pkg/astmodel/file_definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,18 @@ func NewFileDefinition(packageRef *PackageReference, definitions ...TypeDefiner)
// generateImports products the definitive set of imports for use in this file and
// disambiguates any conflicts
func (file *FileDefinition) generateImports() map[PackageImport]struct{} {

metav1Import := NewPackageImport(
*NewPackageReference("k8s.io/apimachinery/pkg/apis/meta/v1")).WithName("metav1")

var requiredImports = make(map[PackageImport]struct{}) // fake set type
requiredImports[*metav1Import] = struct{}{}

for _, s := range file.definitions {
for _, requiredImport := range s.Type().RequiredImports() {
for _, requiredImport := range s.RequiredImports() {
// no need to import the current package
if !requiredImport.Equals(file.packageReference) {
newImport := NewPackageImport(*requiredImport)

if requiredImport.PackagePath() == MetaV1PackageReference.PackagePath() {
newImport = newImport.WithName("metav1")
}

requiredImports[*newImport] = struct{}{}
}
}
Expand Down Expand Up @@ -100,8 +100,10 @@ func (file *FileDefinition) AsAst() ast.Node {
// Create context from imports
codeGenContext := NewCodeGenerationContext(file.packageReference, packageReferences)

// Create import header:
decls = append(decls, &ast.GenDecl{Tok: token.IMPORT, Specs: file.generateImportSpecs(packageReferences)})
// Create import header if needed
if len(packageReferences) > 0 {
decls = append(decls, &ast.GenDecl{Tok: token.IMPORT, Specs: file.generateImportSpecs(packageReferences)})
}

// Emit all definitions:
for _, s := range file.definitions {
Expand Down
2 changes: 2 additions & 0 deletions hack/generator/pkg/astmodel/package_reference.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const (
localPathPrefix = "github.com/Azure/k8s-infra/hack/generator/apis/"
)

var MetaV1PackageReference = NewPackageReference("k8s.io/apimachinery/pkg/apis/meta/v1")

// PackageReference indicates which package
// a struct belongs to.
type PackageReference struct {
Expand Down
19 changes: 16 additions & 3 deletions hack/generator/pkg/astmodel/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package astmodel

import (
"fmt"
"go/ast"
"go/token"
)
Expand Down Expand Up @@ -77,13 +78,25 @@ func (definition *ResourceDefinition) WithDescription(description *string) TypeD
return &result
}

// TODO: metav1 import should be added via RequiredImports?
var typeMetaField = defineField("", "metav1.TypeMeta", "`json:\",inline\"`")
var objectMetaField = defineField("", "metav1.ObjectMeta", "`json:\"metadata,omitempty\"`")
// RequiredImports returns a list of packages required by this
func (definition *ResourceDefinition) RequiredImports() []*PackageReference {
typeImports := definition.spec.RequiredImports()
// TODO BUG: the status is not considered here
typeImports = append(typeImports, MetaV1PackageReference)

return typeImports
}

// AsDeclarations converts the ResourceDefinition to a go declaration
func (definition *ResourceDefinition) AsDeclarations(codeGenerationContext *CodeGenerationContext) []ast.Decl {

packageName, err := codeGenerationContext.GetImportedPackageName(MetaV1PackageReference)
if err != nil {
panic(fmt.Errorf("resource definition for %s failed to import package: %w", definition.typeName, err))
}
typeMetaField := defineField("", fmt.Sprintf("%s.TypeMeta", packageName), "`json:\",inline\"`")
objectMetaField := defineField("", fmt.Sprintf("%s.ObjectMeta", packageName), "`json:\"metadata,omitempty\"`")

/*
start off with:
metav1.TypeMeta `json:",inline"`
Expand Down
5 changes: 5 additions & 0 deletions hack/generator/pkg/astmodel/simple_type_definer.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,8 @@ func (std *SimpleTypeDefiner) AsDeclarations(codeGenerationContext *CodeGenerati
},
}
}

// RequiredImports returns a list of packages required by this type
func (std *SimpleTypeDefiner) RequiredImports() []*PackageReference {
return std.theType.RequiredImports()
}
5 changes: 5 additions & 0 deletions hack/generator/pkg/astmodel/struct_definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ func (definition *StructDefinition) WithDescription(description *string) TypeDef
return &result
}

// RequiredImports returns a list of packages required by this
func (definition *StructDefinition) RequiredImports() []*PackageReference {
return definition.structType.RequiredImports()
}

// AsDeclarations returns the Go AST declarations for this struct
func (definition *StructDefinition) AsDeclarations(codeGenerationContext *CodeGenerationContext) []ast.Decl {
identifier := ast.NewIdent(definition.typeName.name)
Expand Down
2 changes: 1 addition & 1 deletion hack/generator/pkg/astmodel/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type Type interface {
// Equals returns true if the passed type is the same as this one, false otherwise
Equals(t Type) bool

// CreateDefinitions gives a name to the type and might generate some asssociated definitions as well (the second result)
// CreateDefinitions gives a name to the type and might generate some associated definitions as well (the second result)
// that also must be included in the output.
CreateDefinitions(name *TypeName, idFactory IdentifierFactory) (TypeDefiner, []TypeDefiner)

Expand Down
2 changes: 2 additions & 0 deletions hack/generator/pkg/astmodel/type_definer.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (

// TypeDefiner represents a named type in the output files, and knows how to generate the Go AST
type TypeDefiner interface {
// RequiredImports returns a list of packages required by this type
RequiredImports() []*PackageReference

// Name is the name that will be bound to the type
Name() *TypeName
Expand Down
5 changes: 3 additions & 2 deletions hack/generator/pkg/astmodel/type_name.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ var _ Type = (*TypeName)(nil)
// AsType implements Type for TypeName
func (typeName *TypeName) AsType(codeGenerationContext *CodeGenerationContext) ast.Expr {
// If our package is being referenced, we need to ensure we include a selector for that reference
if imp, ok := codeGenerationContext.PackageImports()[typeName.PackageReference]; ok {
packageName, err := codeGenerationContext.GetImportedPackageName(&typeName.PackageReference)
if err == nil {
return &ast.SelectorExpr{
X: ast.NewIdent(imp.PackageName()),
X: ast.NewIdent(packageName),
Sel: ast.NewIdent(typeName.Name()),
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// Code generated by k8s-infra-gen. DO NOT EDIT.
package v20200101

import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

//Generated from: https://test.test/schemas/2020-01-01/test.json
type Test struct {
Tags *TestTags `json:"tags"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// Code generated by k8s-infra-gen. DO NOT EDIT.
package v20200101

import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

//Generated from: https://test.test/schemas/2020-01-01/test.json
type Test struct {
Tags *map[string]interface{} `json:"tags"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// Code generated by k8s-infra-gen. DO NOT EDIT.
package v20200101

import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

//Generated from: https://test.test/schemas/2020-01-01/test.json
type Test struct {
Tags *map[string]float64 `json:"tags"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// Code generated by k8s-infra-gen. DO NOT EDIT.
package v20200101

import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

//Generated from: https://test.test/schemas/2020-01-01/test.json
type Test struct {
Tags *TestTags `json:"tags"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// Code generated by k8s-infra-gen. DO NOT EDIT.
package v20200101

import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

//Generated from: https://test.test/schemas/2020-01-01/test.json
type Test struct {
Tags *TestTags `json:"tags"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// Code generated by k8s-infra-gen. DO NOT EDIT.
package v20200101

import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

//Generated from: https://test.test/schemas/2020-01-01/test.json#/definitions/Foo
type Foo struct {
Name *string `json:"name"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// Code generated by k8s-infra-gen. DO NOT EDIT.
package v20200101

import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

//Generated from: https://test.test/schemas/2020-01-01/test.json
type Test struct {
Name *string `json:"name"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// Code generated by k8s-infra-gen. DO NOT EDIT.
package v20200101

import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

//Generated from: https://test.test/schemas/2020-01-01/test.json#/definitions/Bar
type Bar struct {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// Code generated by k8s-infra-gen. DO NOT EDIT.
package v20200101

import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

//Generated from: https://test.test/schemas/2020-01-01/test.json#/definitions/Foo
type Foo struct {
Name *string `json:"name"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// Code generated by k8s-infra-gen. DO NOT EDIT.
package v20200101

import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

//Generated from: https://test.test/schemas/2020-01-01/test.json
type Test struct {
Name *string `json:"name"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
// Code generated by k8s-infra-gen. DO NOT EDIT.
package v20200101

import (
"encoding/json"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
import "encoding/json"

//Generated from: https://test.test/schemas/2020-01-01/test.json#/definitions/Bar
type Bar struct {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
// Code generated by k8s-infra-gen. DO NOT EDIT.
package v20200101

import (
"encoding/json"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
import "encoding/json"

//Generated from: https://test.test/schemas/2020-01-01/test.json#/definitions/Bar
type Bar struct {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
// Code generated by k8s-infra-gen. DO NOT EDIT.
package v20200101

import (
"encoding/json"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
import "encoding/json"

//Generated from: https://test.test/schemas/2020-01-01/test.json#/definitions/Foo
type Foo int
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// Code generated by k8s-infra-gen. DO NOT EDIT.
package v20200101

import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

//Generated from: https://test.test/schemas/2020-01-01/test.json
type Test struct {
Name *string `json:"name"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// Code generated by k8s-infra-gen. DO NOT EDIT.
package v20200101

import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

//Generated from: https://test.test/schemas/2020-01-01/test.json
type Test struct {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// Code generated by k8s-infra-gen. DO NOT EDIT.
package v20200101

import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

//Generated from: https://test.test/schemas/2020-01-01/test.json
type Test struct {
NotRequired *string `json:"notRequired"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// Code generated by k8s-infra-gen. DO NOT EDIT.
package v20200101

import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

//Generated from: https://test.test/schemas/2020-01-01/test.json
type Test struct {
Foo interface{} `json:"foo"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// Code generated by k8s-infra-gen. DO NOT EDIT.
package v20200101

import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

//Generated from: https://test.test/schemas/2020-01-01/test.json
type Test struct {

Expand Down

0 comments on commit b5fbcbd

Please sign in to comment.