diff --git a/README.md b/README.md index abde601..53576d5 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,11 @@ cty generate -c delivery.krok.app_krokcommands --comments --format html ![parsed1_cli](./imgs/parsed1_cli.png) ![parsed2_cli](./imgs/parsed2_cli.png) +In case of multiple CRD files being parsed using a `folder` target, the CRDs will be listed +in collapsed drop-down menus where their KIND is the title. + +![parsed3_cli](./imgs/parsed3_cli.png) + ### Minimal required CRD sample It's possible to generate a sample YAML for a CRD that will make the CRD validation pass. Meaning, it will only contain diff --git a/cmd/generate.go b/cmd/generate.go index a200b69..e0d77a4 100644 --- a/cmd/generate.go +++ b/cmd/generate.go @@ -95,6 +95,21 @@ func runGenerate(_ *cobra.Command, _ []string) error { var w io.WriteCloser + if args.format == FormatHTML { + if args.stdOut { + w = os.Stdout + } else { + w, err = os.Create(args.output) + if err != nil { + return fmt.Errorf("failed to create output file: %w", err) + } + + defer w.Close() + } + + return pkg.RenderContent(w, crds, args.comments, args.minimal) + } + var errs []error //nolint:prealloc // nope for _, crd := range crds { if args.stdOut { @@ -112,12 +127,6 @@ func runGenerate(_ *cobra.Command, _ []string) error { w = outputFile } - if args.format == FormatHTML { - errs = append(errs, pkg.RenderContent(w, crd, args.comments, args.minimal)) - - continue - } - errs = append(errs, pkg.Generate(crd, w, args.comments, args.minimal, args.skipRandom)) } diff --git a/gotemplates.gotemplating.fn.crossplane.io_sample.yaml b/gotemplates.gotemplating.fn.crossplane.io_sample.yaml deleted file mode 100644 index a748a9f..0000000 --- a/gotemplates.gotemplating.fn.crossplane.io_sample.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: gotemplating.fn.crossplane.io/v1beta1 -delims: - left: string - right: "}}" -fileSystem: - dirPath: string -inline: - template: string -kind: GoTemplate -metadata: {} -source: string diff --git a/imgs/parsed3_cli.png b/imgs/parsed3_cli.png new file mode 100644 index 0000000..3f2e6fc Binary files /dev/null and b/imgs/parsed3_cli.png differ diff --git a/pkg/create_html_output.go b/pkg/create_html_output.go index 6003fa0..bef9f50 100644 --- a/pkg/create_html_output.go +++ b/pkg/create_html_output.go @@ -14,6 +14,10 @@ import ( v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" ) +type Index struct { + Page []ViewPage +} + // Version wraps a top level version resource which contains the underlying openAPIV3Schema. type Version struct { Version string @@ -26,6 +30,7 @@ type Version struct { // ViewPage is the template for view.html. type ViewPage struct { + Title string Versions []Version } @@ -61,40 +66,58 @@ func LoadTemplates() error { } // RenderContent creates an HTML website from the CRD content. -func RenderContent(w io.WriteCloser, crd *v1.CustomResourceDefinition, comments, minimal bool) (err error) { +func RenderContent(w io.WriteCloser, crds []*v1.CustomResourceDefinition, comments, minimal bool) (err error) { defer func() { if cerr := w.Close(); cerr != nil { err = errors.Join(err, cerr) } }() - versions := make([]Version, 0) - parser := NewParser(crd.Spec.Group, crd.Spec.Names.Kind, comments, minimal, false) + allViews := make([]ViewPage, 0, len(crds)) - for _, version := range crd.Spec.Versions { - out, err := parseCRD(version.Schema.OpenAPIV3Schema.Properties, version.Name, minimal, RootRequiredFields) - if err != nil { - return fmt.Errorf("failed to parse properties: %w", err) + for _, crd := range crds { + versions := make([]Version, 0) + parser := NewParser(crd.Spec.Group, crd.Spec.Names.Kind, comments, minimal, false) + + for _, version := range crd.Spec.Versions { + out, err := parseCRD(version.Schema.OpenAPIV3Schema.Properties, version.Name, minimal, RootRequiredFields) + if err != nil { + return fmt.Errorf("failed to parse properties: %w", err) + } + var buffer []byte + buf := bytes.NewBuffer(buffer) + if err := parser.ParseProperties(version.Name, buf, version.Schema.OpenAPIV3Schema.Properties); err != nil { + return fmt.Errorf("failed to generate yaml sample: %w", err) + } + versions = append(versions, Version{ + Version: version.Name, + Properties: out, + Kind: crd.Spec.Names.Kind, + Group: crd.Spec.Group, + Description: version.Schema.OpenAPIV3Schema.Description, + YAML: buf.String(), + }) } - var buffer []byte - buf := bytes.NewBuffer(buffer) - if err := parser.ParseProperties(version.Name, buf, version.Schema.OpenAPIV3Schema.Properties); err != nil { - return fmt.Errorf("failed to generate yaml sample: %w", err) + + if len(versions) == 0 { + continue } - versions = append(versions, Version{ - Version: version.Name, - Properties: out, - Kind: crd.Spec.Names.Kind, - Group: crd.Spec.Group, - Description: version.Schema.OpenAPIV3Schema.Description, - YAML: buf.String(), - }) - } - view := ViewPage{ - Versions: versions, + + view := ViewPage{ + Title: crd.Spec.Names.Kind, + Versions: versions, + } + + allViews = append(allViews, view) } + t := templates["view.html"] - if err := t.Execute(w, view); err != nil { + + index := Index{ + Page: allViews, + } + + if err := t.Execute(w, index); err != nil { return fmt.Errorf("failed to execute template: %w", err) } diff --git a/pkg/templates/view.html b/pkg/templates/view.html index 3dac724..28cb0be 100644 --- a/pkg/templates/view.html +++ b/pkg/templates/view.html @@ -31,82 +31,78 @@ padding-bottom: 2rem; } -
-
-
- {{range .Versions}} -

- Version: {{.Group}}/{{.Version}}
- Kind: {{.Kind}} -

-

-

-

{{.Description}}

-
- -
-
-
-
{{.YAML}}
-
-
-
-

-
- - -
-
- {{range $i, $v := .Properties}} -
- - {{$v.Name}} {{$v.Type}} - {{if $v.Format}} - {{.Format}} - {{end}} - {{if $v.Patterns}} - {{.Patterns}} - {{end}} - {{if $v.Default}} - {{$v.Default}} - {{end}} - {{if $v.Required}} - required +

The following CRDs have been rendered

+ + {{range .Page}} +
+ + {{.Title}} + +
+
+ {{range .Versions}} +

+ Version: {{.Group}}/{{.Version}}
+ Kind: {{.Kind}} +

+

+

+

{{.Description}}

+
+ +
+
+
+
{{.YAML}}
+
+
+
+

+
+ {{range $i, $v := .Properties}} +
+ + {{$v.Name}} {{$v.Type}} + {{if $v.Format}} + {{.Format}} + {{end}} + {{if $v.Patterns}} + {{.Patterns}} + {{end}} + {{if $v.Default}} + {{$v.Default}} + {{end}} + {{if $v.Required}} + required + {{end}} + +
+
+

{{$v.Description}}

+
+ {{template "properties" .Properties}} +
+
+
{{end}} -
-
-
-

{{$v.Description}}

-
- {{template "properties" .Properties}}
-
-
- {{end}} + {{end}} +
- {{end}} -
-
+ + {{end}} + + + -