From 7dd2a2a6ac788728ce9c5959c33a90f0bfa11225 Mon Sep 17 00:00:00 2001 From: fanzhangio Date: Mon, 14 May 2018 15:44:17 -0700 Subject: [PATCH] Add annotation support for generating doc config. - parse doc annotations with +kubebuilder:doc:note and +kubebuilder:doc:warning - support description_warning and description_note in config.yaml - add e2e test in test.sh --- cmd/internal/codegen/parse/apis.go | 8 +++++++ cmd/internal/codegen/parse/util.go | 29 ++++++++++++++++++++++++ cmd/internal/codegen/types.go | 5 +++- cmd/kubebuilder/docs/gen.go | 12 ++++++++-- test.sh | 5 ++++ test/docs/expected/config-annotated.yaml | 24 ++++++++++++++++++++ 6 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 test/docs/expected/config-annotated.yaml diff --git a/cmd/internal/codegen/parse/apis.go b/cmd/internal/codegen/parse/apis.go index c95d01847e..862c363f9a 100644 --- a/cmd/internal/codegen/parse/apis.go +++ b/cmd/internal/codegen/parse/apis.go @@ -72,6 +72,7 @@ func (b *APIs) parseAPIs() { NonNamespaced: resource.NonNamespaced, ShortName: resource.ShortName, } + parseDoc(resource, apiResource) apiVersion.Resources[kind] = apiResource // Set the package for the api version apiVersion.Pkg = b.context.Universe[resource.Type.Name.Package] @@ -275,3 +276,10 @@ func (b *APIs) genDeepCopy(c *types.Type) bool { comments := Comments(c.CommentLines) return comments.hasTag("subresource-request") } + +func parseDoc(resource, apiResource *codegen.APIResource) { + if HasDocAnnotation(resource.Type) { + resource.DocAnnotation = getDocAnnotation(resource.Type, "warning", "note") + apiResource.DocAnnotation = resource.DocAnnotation + } +} diff --git a/cmd/internal/codegen/parse/util.go b/cmd/internal/codegen/parse/util.go index bf29a6587d..e283bfba38 100644 --- a/cmd/internal/codegen/parse/util.go +++ b/cmd/internal/codegen/parse/util.go @@ -125,6 +125,20 @@ func HasCategories(t *types.Type) bool { return false } +// HasDocAnnotation returns true if t is an APIResource with doc annotation +// +kubebuilder:doc +func HasDocAnnotation(t *types.Type) bool { + if !IsAPIResource(t) { + return false + } + for _, c := range t.CommentLines { + if strings.Contains(c, "+kubebuilder:doc") { + return true + } + } + return false +} + func IsUnversioned(t *types.Type, group string) bool { return IsApisDir(filepath.Base(filepath.Dir(t.Name.Package))) && GetGroup(t) == group } @@ -202,3 +216,18 @@ func (c Comments) getTags(name, sep string) []string { } return tags } + +// getDocAnnotation parse annotations of "+kubebuilder:doc:" with tags of "warning" or "doc" for control generating doc config. +// E.g. +kubebuilder:doc:warning=foo +kubebuilder:doc:note=bar +func getDocAnnotation(t *types.Type, tags ...string) map[string]string { + annotation := make(map[string]string) + for _, tag := range tags { + for _, c := range t.CommentLines { + prefix := fmt.Sprintf("+kubebuilder:doc:%s=", tag) + if strings.HasPrefix(c, prefix) { + annotation[tag] = strings.Replace(c, prefix, "", 1) + } + } + } + return annotation +} diff --git a/cmd/internal/codegen/types.go b/cmd/internal/codegen/types.go index 485151d8eb..92e2ca5d1c 100644 --- a/cmd/internal/codegen/types.go +++ b/cmd/internal/codegen/types.go @@ -17,13 +17,14 @@ limitations under the License. package codegen import ( + "sort" + rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/gengo/types" - "sort" ) type APIs struct { @@ -161,6 +162,8 @@ type APIResource struct { CRD v1beta1.CustomResourceDefinition Validation string ValidationComments string + // DocAnnotation is a map of annotations by name for doc. e.g. warning, notes message + DocAnnotation map[string]string } type APISubresource struct { diff --git a/cmd/kubebuilder/docs/gen.go b/cmd/kubebuilder/docs/gen.go index 5870f2ab35..937bfb89ee 100644 --- a/cmd/kubebuilder/docs/gen.go +++ b/cmd/kubebuilder/docs/gen.go @@ -61,6 +61,11 @@ func (g CodeGenerator) Execute(dir string) error { } sort.Strings(vs) r.Version = vs[0] + if version[vs[0]] != nil { + annotations := version[vs[0]].DocAnnotation + r.Warning = annotations["warning"] + r.Note = annotations["note"] + } m[r.Kind] = r s = append(s, r.Kind) } @@ -90,7 +95,7 @@ type Category struct { } type Resource struct { - Kind, Version, Group string + Kind, Version, Group, Warning, Note string } var docsConfigTemplate = `example_location: "examples" @@ -103,5 +108,8 @@ resource_categories: {{ range $category := .Categories }} resources: {{ range $resource := $category.Resources }} - name: "{{ $resource.Kind }}" version: "{{ $resource.Version }}" - group: "{{ $resource.Group }}"{{ end }} + group: "{{ $resource.Group }}"{{ if $resource.Warning }} + description_warning: "{{ $resource.Warning }}"{{ end -}}{{ if $resource.Note }} + description_note: "{{ $resource.Note }}"{{ end -}} + {{ end }} {{ end }}` diff --git a/test.sh b/test.sh index 492f7b3299..6dd8897cf1 100755 --- a/test.sh +++ b/test.sh @@ -500,6 +500,11 @@ function test_docs { diff docs/reference/includes $kb_orig/test/docs/expected/includes diff docs/reference/manifest.json $kb_orig/test/docs/expected/manifest.json diff docs/reference/config.yaml $kb_orig/test/docs/expected/config.yaml + + header_text "testing doc annotations" + sed -i -e "s|// +kubebuilder:categories=foo,bar|// +kubebuilder:categories=foo,bar\n// +kubebuilder:doc:note=test notes message annotations\n// +kubebuilder:doc:warning=test warnings message annotations|" pkg/apis/insect/v1beta1/bee_types.go + kubebuilder docs --brodocs=false --cleanup=false + diff docs/reference/config.yaml $kb_orig/test/docs/expected/config-annotated.yaml } function generate_controller { diff --git a/test/docs/expected/config-annotated.yaml b/test/docs/expected/config-annotated.yaml new file mode 100644 index 0000000000..0a769c8e69 --- /dev/null +++ b/test/docs/expected/config-annotated.yaml @@ -0,0 +1,24 @@ +example_location: "examples" +api_groups: + - "Ant" + + - "Insect" +resource_categories: +- name: "Ant" + include: "ant" + resources: + - name: "Ant" + version: "v1beta1" + group: "ant" + +- name: "Insect" + include: "insect" + resources: + - name: "Bee" + version: "v1beta1" + group: "insect" + description_warning: "test warnings message annotations" + description_note: "test notes message annotations" + - name: "Wasp" + version: "v1beta1" + group: "insect"