Compiler's main responsibility is to generate code based on provided datamodel. Currently, generated are:
- CRD yamls with OpenAPI schema,
- CRD Go types definitions,
- CRD Go clients,
- nexus shim layer.
- Compiler operates on datamodel provided by user (example can be found in
example/datamodel
). - Compiler parses datamodel to build graph (this happens in the
parser
package). - Based on built graph base templates are rendered and created (this happens in the
pkg/generator
package), example output of this operation is in theexample/output/_rendered_templates
directory. - kubernetes code generator generates more additional Go code (this happens in the
generated_base_structure/scripts/generate_k8s_api.sh
), it generates kuberentes go-client and deepcopy functions, example output is inexample/crd-generated/client and example/crd-generated/apis/{api_name}/v1/zz_generated_deepcopy.go
. - OpenAPI generator updates CRD yamls with OpenAPI specification (this happens in the
generated_base_structure/scripts
, uses k8s.io/kube-openapi/cmd/openapi-gen and code from some our custom logic in thegenerated_base_structure/openapi_generator
package), example output is in theexample/output/generated/crds
.
Very detailed flow chart
- Create datamodel based on docs
- Download compiler image or build in compiler repo using
make docker.builder && make docker
command - Run compiler from your application nexus directory. Specify GROUP_NAME env variable with your CRD group name: Your datamodel should be mounted to /go/src/github.com/vmware-tanzu/graph-framework-for-microservices/compiler/datamodel directory, and directory to which you would like to generate your files should be mounted to /go/src/github.com/vmware-tanzu/graph-framework-for-microservices/compiler/generated directory. CRD_MODULE_PATH env var will determine import paths for generated files. If you follow structure from example above you just need to specify GROUP_NAME and copy rest of following example command
$ cd nexus
$ GROUP_NAME=helloworld.com && \
docker run \
--volume $(realpath .)/datamodel:/go/src/github.com/vmware-tanzu/graph-framework-for-microservices/compiler/datamodel \
--volume $(realpath .)/generated:/go/src/github.com/vmware-tanzu/graph-framework-for-microservices/compiler/generated \
-e CRD_MODULE_PATH=$(go list -m)/nexus/generated/ \
-e GROUP_NAME=$GROUP_NAME \
--workdir /go/src/github.com/vmware-tanzu/graph-framework-for-microservices/compiler/ \
nexus-compiler:1ce29d44
- Create datamodel based on docs
- Init submodules by running
make init_submodules
(step required only once) - Install necessary tools by running
make tools
(step required only once) - Specify required env variables:
DATAMODEL_PATH
- path to datamodelCONFIG_FILE
- path to config fileGENERATED_OUTPUT_DIRECTORY
- path to which code should be generatedCRD_MODULE_PATH
- name of module to which code should be generated
- Run
make generate_code
For example to generate code for org-chart datamodel example download it your GOPATH/src/gitlab.eng.vmware.com/nsx-allspark_users/nexus-sdk/datamodel-examples/ and run compiler like this:
DATAMODEL_PATH=${GOPATH}/src/gitlab.eng.vmware.com/nsx-allspark_users/nexus-sdk/datamodel-examples/org-chart \
CONFIG_FILE=${DATAMODEL_PATH}/nexus.yaml \
GENERATED_OUTPUT_DIRECTORY=${DATAMODEL_PATH}/build \
CRD_MODULE_PATH=gitlab.eng.vmware.com/nsx-allspark_users/nexus-sdk/datamodel-examples.git/org-chart/build \
make generate_code
Any and every code change MUST follow code style guidelines and pass following checks:
-
Unit Test cases are mandatory for any and every code change.
-
make test-fmt
- makes sure code formatting matches standard golang formatting -
make lint
andmake vet
- static code analysis looking for possible programming errors, bugs, stylistic errors, and suspicious constructs -
make race-unit-test
- executes unit tests with race flag to look for possible race conditions
To run build in a fixed/sandboxed environment:
-
Download the build sandbox:
make docker.builder
-
Build compiler:
make docker
Install required tools using make tools
To render templates for example datamodel use make render_templates
(this step executes steps 1-3 from
[How compiler works](#How compiler works)). This will generate rendered templates to example/output/_rendered_templates
directory.
To generate all code for example use make generate_example
(this step executes all steps from
[How compiler works](#How compiler works)). This will generate code to example/output/generated
directory.
To run tests in a fixed/sandboxed environment:
-
Download the test sandbox:
make docker.builder
-
Test compiler:
make test_in_container
-
Test generation with
make test_generate_code_in_container
To render crd templates you can run:
make render_templates
This will generate rendered templates to example/output/_rendered_templates
directory. This directory can be used for unit tests.
To test code generation for example datamodel run:
make generate_example
This will generate code to example/output/generated
directory.
Compiler is packaged and published a Docker container images.
Packaging is achieved by the following two steps:
Create base image: make docker
To build compiler docker image: make docker
Compiler docker image can be published by invoking: make publish
If generated code can't be built with error message like
apis/root.tsm.tanzu.vmware.com/v1/zz_generated.deepcopy.go:173:6: in.F.DeepCopyInto undefined (type text.Frame has no field or method DeepCopyInto)
It means that text.Frame must implement DeepCopyInto method. This method must be added manually.