From 817cf4382012e42812d9140d51d6dc328a3ee22e Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Mon, 3 Jun 2024 09:29:18 -0700 Subject: [PATCH] generate: Prevent incorrect attribute association with very deep nesting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reference: https://github.com/hashicorp/terraform-plugin-docs/issues/380 After introducing the new unit test matching the given schema and expected output, prior to the logic change: ``` --- FAIL: TestRender (0.00s) --- FAIL: TestRender/deep_nested_attributes (0.00s) /Users/bflad/src/github.com/hashicorp/terraform-plugin-docs/internal/schemamd/render_test.go:91: Unexpected diff (-wanted, +got):   strings.Join({    ... // 1062 identical bytes    "el_two.level_three.level_four_primary. (see [below for nested sc",    "hema](#nestedatt--level_one--level_two--level_three--level_four_", -  "prim", +  "second",    "ary--level_five))\n- `level_four_primary_string` (String) Parent ",    "should be level_one.level_two.level_three.level_four_primary.\n\n<",    `a id="nestedatt--level_one--level_two--level_three--level_four_`, -  "prim", +  "second",    "ary--level_five\">\n### Nested Schema for `level_one.level_two",    ".level_three.level_four_", -  "prim", +  "second",    "ary.level_five`\n\nOptional:\n\n- `level_five_string` (String) Paren",    "t should be level_one.level_two.level_three.level_four_primary.l",    "evel_five.",   }, "") ``` --- .../unreleased/BUG FIXES-20240603-092911.yaml | 5 ++ internal/schemamd/render.go | 8 +- internal/schemamd/render_test.go | 6 ++ .../testdata/deep_nested_attributes.md | 46 +++++++++++ .../deep_nested_attributes.schema.json | 78 +++++++++++++++++++ 5 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 .changes/unreleased/BUG FIXES-20240603-092911.yaml create mode 100644 internal/schemamd/testdata/deep_nested_attributes.md create mode 100644 internal/schemamd/testdata/deep_nested_attributes.schema.json diff --git a/.changes/unreleased/BUG FIXES-20240603-092911.yaml b/.changes/unreleased/BUG FIXES-20240603-092911.yaml new file mode 100644 index 00000000..4ad685ab --- /dev/null +++ b/.changes/unreleased/BUG FIXES-20240603-092911.yaml @@ -0,0 +1,5 @@ +kind: BUG FIXES +body: 'generate: Prevented incorrect attribute paths with nested attributes that contain multiple attributes' +time: 2024-06-03T09:29:11.314279-07:00 +custom: + Issue: "380" diff --git a/internal/schemamd/render.go b/internal/schemamd/render.go index 210ede34..a459d0ba 100644 --- a/internal/schemamd/render.go +++ b/internal/schemamd/render.go @@ -466,7 +466,9 @@ func writeObjectChildren(w io.Writer, parents []string, ty cty.Type, group group for _, name := range sortedNames { att := atts[name] - path := append(parents, name) + path := make([]string, len(parents), len(parents)+1) + copy(path, parents) + path = append(path, name) nt, err := writeObjectAttribute(w, path, att, group) if err != nil { @@ -522,7 +524,9 @@ func writeNestedAttributeChildren(w io.Writer, parents []string, nestedAttribute for _, name := range names { att := nestedAttributes.Attributes[name] - path := append(parents, name) + path := make([]string, len(parents), len(parents)+1) + copy(path, parents) + path = append(path, name) nt, err := writeAttribute(w, path, att, group) if err != nil { diff --git a/internal/schemamd/render_test.go b/internal/schemamd/render_test.go index 18858292..1770be42 100644 --- a/internal/schemamd/render_test.go +++ b/internal/schemamd/render_test.go @@ -48,6 +48,12 @@ func TestRender(t *testing.T) { "testdata/framework_types.schema.json", "testdata/framework_types.md", }, + { + // Reference: https://github.com/hashicorp/terraform-plugin-docs/issues/380 + "deep_nested_attributes", + "testdata/deep_nested_attributes.schema.json", + "testdata/deep_nested_attributes.md", + }, } { c := c t.Run(c.name, func(t *testing.T) { diff --git a/internal/schemamd/testdata/deep_nested_attributes.md b/internal/schemamd/testdata/deep_nested_attributes.md new file mode 100644 index 00000000..88e52c6b --- /dev/null +++ b/internal/schemamd/testdata/deep_nested_attributes.md @@ -0,0 +1,46 @@ +## Schema + +### Required + +- `level_one` (Attributes) (see [below for nested schema](#nestedatt--level_one)) + +### Read-Only + +- `id` (String) Example identifier + + +### Nested Schema for `level_one` + +Optional: + +- `level_two` (Attributes) (see [below for nested schema](#nestedatt--level_one--level_two)) + + +### Nested Schema for `level_one.level_two` + +Optional: + +- `level_three` (Attributes) (see [below for nested schema](#nestedatt--level_one--level_two--level_three)) + + +### Nested Schema for `level_one.level_two.level_three` + +Optional: + +- `level_four_primary` (Attributes) (see [below for nested schema](#nestedatt--level_one--level_two--level_three--level_four_primary)) +- `level_four_secondary` (String) + + +### Nested Schema for `level_one.level_two.level_three.level_four_primary` + +Optional: + +- `level_five` (Attributes) Parent should be level_one.level_two.level_three.level_four_primary. (see [below for nested schema](#nestedatt--level_one--level_two--level_three--level_four_primary--level_five)) +- `level_four_primary_string` (String) Parent should be level_one.level_two.level_three.level_four_primary. + + +### Nested Schema for `level_one.level_two.level_three.level_four_primary.level_five` + +Optional: + +- `level_five_string` (String) Parent should be level_one.level_two.level_three.level_four_primary.level_five. diff --git a/internal/schemamd/testdata/deep_nested_attributes.schema.json b/internal/schemamd/testdata/deep_nested_attributes.schema.json new file mode 100644 index 00000000..7e212882 --- /dev/null +++ b/internal/schemamd/testdata/deep_nested_attributes.schema.json @@ -0,0 +1,78 @@ +{ + "version": 0, + "block": { + "attributes": { + "id": { + "type": "string", + "description": "Example identifier", + "description_kind": "markdown", + "computed": true + }, + "level_one": { + "nested_type": { + "attributes": { + "level_two": { + "nested_type": { + "attributes": { + "level_three": { + "nested_type": { + "attributes": { + "level_four_primary": { + "nested_type": { + "attributes": { + "level_five": { + "nested_type": { + "attributes": { + "level_five_string": { + "type": "string", + "description": "Parent should be level_one.level_two.level_three.level_four_primary.level_five.", + "description_kind": "plain", + "optional": true + } + }, + "nesting_mode": "single" + }, + "description": "Parent should be level_one.level_two.level_three.level_four_primary.", + "description_kind": "plain", + "optional": true + }, + "level_four_primary_string": { + "type": "string", + "description": "Parent should be level_one.level_two.level_three.level_four_primary.", + "description_kind": "plain", + "optional": true + } + }, + "nesting_mode": "single" + }, + "description_kind": "plain", + "optional": true + }, + "level_four_secondary": { + "type": "string", + "description_kind": "plain", + "optional": true + } + }, + "nesting_mode": "single" + }, + "description_kind": "plain", + "optional": true + } + }, + "nesting_mode": "single" + }, + "description_kind": "plain", + "optional": true + } + }, + "nesting_mode": "single" + }, + "description_kind": "plain", + "required": true + } + }, + "description": "Example resource", + "description_kind": "markdown" + } +} \ No newline at end of file