An opinionated Kubernetes Runtime and Golang type generator in the builder pattern. Why the builder pattern? It was chosen to offer a consistent, clean, and readable code that can be extensible by the developer.
The Kanopy code-generator is built using the Kubernetes gengo packages.
The code generator depends on golang projects using go.mod
.
Kanopy Builder code generator
Usage:
kanopy-codegen [flags]
Flags:
--bounding-dirs strings specify directories to bound the generation
--build-tag string A Go build tag to use to identify files generated by this command. Should be unique. (default "ignore_autogenerated")
-e, --go-header-file string File containing boilerplate header text. The string YEAR will be replaced with the current 4-digit year. (default "/Users/david.katz/go/src/k8s.io/gengo/boilerplate/boilerplate.go.txt")
-h, --help help for kanopy-codegen
-i, --input-dirs strings Comma-separated list of import paths to get input types from.
--log-level string Configure log level (default "info")
-o, --output-base string Output base; defaults to $GOPATH/src/ or ./ if $GOPATH is not set. (default "/Users/david.katz/go/src")
-O, --output-file-base string Base name (without .go suffix) for output files. (default "zz_generated_builders")
-p, --output-package string Base package path.
--trim-path-prefix string If set, trim the specified prefix from --output-package when generating files.
--verify-only If true, only verify existing output, do not write anything.
go install ./cmd/kanopy-code-gen
kanopy-codegen -o ./<path for output> --input-dirs ./<path to package>
The main entry point into the application
Defines the cli interface and flags using cobra
Defines the generator implementation for constructing code for Kubernetes Runtime types
Implements the gengo generator.Generator interface.
Defines individual template snippets used by the builder.
Common functions to parse comment tags supported by this generator.
// +kanopy:builder=true
type AType struct...
// +kanopy:builder=false
type AType struct...
As referenced in gengo, global package settings can be provided by adding a doc.go
to the package. For example:
doc.go
:
package mytypes
// +kanopy:builder=package
An enum can be generated with the following argument. Enum constants are used in several upstream k8s packages. e.g.
// +kanopy:builder=true,ref=k8s.io/api/admissionregistration/v1.OperationType,enum=*;CREATE;UPDATE;DELETE;CONNECT
type OperationType admissionv1.OperationType
ref
is required to provide a type hint to the generator since gengo resolves Alias types to the leaf node
Which generates:
const OperationTypeCreate OperationType = "CREATE"
The *
is a special value within k8s that indicates All
. The code generator will translate a *
to all in the suffix of the constant name.
const OperationTypeAll OperationType = "*"
Enum arguments can be used for both upstream packages and internal packages.
terms | definition |
---|---|
embedded | A type that is inheriting the attributes and members of another type |
member | A direct attribute of a type. For example. AType.Name = "hello" Name is a member of AType |
root / wrapper type | The top level type defined in the source code to be generated |
parent type | The immediate parent type of a member |
type AType struct { // root / wrapper type
b.AnotherType // embedded type
}
type AnotherType struct { // parent type
Name string // member type
}
Relationships are always relative to the type as the tree is traversed. In the example above the AType
definition is also the parent
of b.AnotherType
and b.AnotherType
is also a member of AType
.
Code is be generated using the following convention:
With<MemberName>
for direct assignments. e.g.WithName(string)
Append<MemberName>
for slices e.g.AppendStrings(...string)
All kubernetes runtime types have the following in common. They embed ObjectMeta and TypeMeta.
-
Given a type is tagged and enabled Then perform code generation.
-
Given a type with ObjectMeta
- generate a Constructor that accepts the name of the resources
- generate DeepCopy and DeepCopyInto wrappers of the parent type
- generate members of ObjectMeta not tagged as
// Read-only
(case insensitive)
-
Given a type with Builtin / Primitive members
- generate setter functions for each member not tagged as
// Read-only
(case insensitive).
- generate setter functions for each member not tagged as