Skip to content

kanopy-platform/code-generator

Repository files navigation

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).