# README
Kanopy code-generator
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.
Requirements
The code generator depends on golang projects using go.mod
.
kanopy-codegen
Usage
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.
Execute:
go install ./cmd/kanopy-code-gen
kanopy-codegen -o ./<path for output> --input-dirs ./<path to package>
cmd/
The main entry point into the application
internal/cli
Defines the cli interface and flags using cobra
pkg/generators
Defines the generator implementation for constructing code for Kubernetes Runtime types
pkg/generators/builder
Implements the gengo generator.Generator interface.
pkg/generators/snippets
Defines individual template snippets used by the builder.
pkg/generators/tags
Common functions to parse comment tags supported by this generator.
Supported Comment Tags
Type Enabled
// +kanopy:builder=true
type AType struct...
Type Disabled
// +kanopy:builder=false
type AType struct...
Package Global Settings
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
Generate Enums
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.
Definition of Terms
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)
Generator States
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