From 111929cc962a1ead601e8024e41f8ed117925ee4 Mon Sep 17 00:00:00 2001 From: Jefftree Date: Thu, 4 Jul 2024 11:11:50 -0400 Subject: [PATCH] Render code blocks properly in OpenAPI --- pkg/generators/openapi.go | 21 +++++++++++ pkg/generators/openapi_test.go | 66 ++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/pkg/generators/openapi.go b/pkg/generators/openapi.go index b0fa8272a..8d96f1933 100644 --- a/pkg/generators/openapi.go +++ b/pkg/generators/openapi.go @@ -50,6 +50,8 @@ const ( tagValueFalse = "false" ) +const codeBlockDelimiter = "```" + // Used for temporary validation of patch struct tags. // TODO: Remove patch struct tag validation because they we are now consuming OpenAPI on server. var tempPatchTags = [...]string{ @@ -922,6 +924,7 @@ func (g openAPITypeWriter) generateDescription(CommentLines []string) { } } + inCodeBlock := false for _, line := range CommentLines { // Ignore all lines after --- if line == "---" { @@ -929,6 +932,24 @@ func (g openAPITypeWriter) generateDescription(CommentLines []string) { } line = strings.TrimRight(line, " ") leading := strings.TrimLeft(line, " ") + + if leading == codeBlockDelimiter { + if !inCodeBlock { + delPrevChar() + buffer.WriteString("\n" + leading + "\n") + inCodeBlock = true + } else { + buffer.WriteString(leading + "\n") + inCodeBlock = false + } + continue + } else if inCodeBlock { + // code blocks should be outputted as is with no left trimming + line = line + "\n" + buffer.WriteString(line) + continue + } + switch { case len(line) == 0: // Keep paragraphs delPrevChar() diff --git a/pkg/generators/openapi_test.go b/pkg/generators/openapi_test.go index e53292129..a6245f832 100644 --- a/pkg/generators/openapi_test.go +++ b/pkg/generators/openapi_test.go @@ -409,6 +409,72 @@ Extensions: spec.Extensions{ }) } +func TestDescription(t *testing.T) { + inputFile := ` + package foo + + // Blah is a test. + // +k8s:openapi-gen=true + type Blah struct { + // Should + // render + // one + // line. + // ` + "```" + ` + // func foo() { + // indents + // } + // ` + "```" + ` + // normal + // plain + // text. + String string + }` + + packagestest.TestAll(t, func(t *testing.T, x packagestest.Exporter) { + e := packagestest.Export(t, x, []packagestest.Module{{ + Name: "example.com/base/foo", + Files: map[string]interface{}{ + "foo.go": inputFile, + }, + }}) + defer e.Cleanup() + + callErr, funcErr, callBuffer, funcBuffer, _ := testOpenAPITypeWriter(t, e.Config) + if callErr != nil { + t.Fatal(callErr) + } + if funcErr != nil { + t.Fatal(funcErr) + } + assertEqual(t, callBuffer.String(), + `"example.com/base/foo.Blah": schema_examplecom_base_foo_Blah(ref),`) + + assertEqual(t, funcBuffer.String(), + `func schema_examplecom_base_foo_Blah(ref common.ReferenceCallback) common.OpenAPIDefinition { +return common.OpenAPIDefinition{ +Schema: spec.Schema{ +SchemaProps: spec.SchemaProps{ +Description: "Blah is a test.", +Type: []string{"object"}, +Properties: map[string]spec.Schema{ +"String": { +SchemaProps: spec.SchemaProps{ +Description: "Should render one line.\n`+"```"+`\nfunc foo() {\n\tindents\n}\n`+"```"+`\nnormal plain text.", +Default: "", +Type: []string{"string"}, +Format: "", +}, +}, +}, +Required: []string{"String"}, +}, +}, +} +}`) + }) +} + func TestEmptyProperties(t *testing.T) { inputFile := ` package foo