diff --git a/.changes/unreleased/FEATURES-20251001-095120.yaml b/.changes/unreleased/FEATURES-20251001-095120.yaml new file mode 100644 index 00000000..085c6680 --- /dev/null +++ b/.changes/unreleased/FEATURES-20251001-095120.yaml @@ -0,0 +1,5 @@ +kind: FEATURES +body: 'generate/migrate/validate: Add support for list resources' +time: 2025-10-01T09:51:20.683445+02:00 +custom: + Issue: "528" diff --git a/README.md b/README.md index cb42511a..821d1da8 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,7 @@ When you run `tfplugindocs`, by default from the root directory of a provider co * Generate function template files, if missing (Requires Terraform v1.8.0+) * Generate ephemeral resource template files, if missing (Requires Terraform v1.10.0+) * Generate action template files, if missing (Requires Terraform v1.14.0+) +* Generate list resource templeate files, if missing (Requires Terraform v1.14.0+) * Copy all non-template files to the output website directory > [!NOTE] @@ -204,20 +205,22 @@ For templates: > **NOTE:** In the following conventional paths for templates, ``, ``, and `` do not include the provider prefix. -| Path | Description | -|--------------------------------------------------------------------|-----------------------------------------------| -| `templates/` | Root of templated docs | -| `templates/index.md[.tmpl]` | Docs index page (or template) | -| `templates/actions.md[.tmpl]` | Generic action page (or template) | -| `templates/actions/.md[.tmpl]` | Action page (or template) | -| `templates/data-sources.md[.tmpl]` | Generic data source page (or template) | -| `templates/data-sources/.md[.tmpl]` | Data source page (or template) | -| `templates/ephemeral-resources.md[.tmpl]` | Generic ephemeral resource page (or template) | -| `templates/ephemeral-resources/.md[.tmpl]`| Ephemeral resource page (or template) | -| `templates/functions.md[.tmpl]` | Generic function page (or template) | -| `templates/functions/.md[.tmpl]` | Function page (or template) | -| `templates/resources.md[.tmpl]` | Generic resource page (or template) | -| `templates/resources/.md[.tmpl]` | Resource page (or template) | +| Path | Description | +|---------------------------------------------------------------------|-----------------------------------------------| +| `templates/` | Root of templated docs | +| `templates/index.md[.tmpl]` | Docs index page (or template) | +| `templates/actions.md[.tmpl]` | Generic action page (or template) | +| `templates/actions/.md[.tmpl]` | Action page (or template) | +| `templates/data-sources.md[.tmpl]` | Generic data source page (or template) | +| `templates/data-sources/.md[.tmpl]` | Data source page (or template) | +| `templates/ephemeral-resources.md[.tmpl]` | Generic ephemeral resource page (or template) | +| `templates/ephemeral-resources/.md[.tmpl]` | Ephemeral resource page (or template) | +| `templates/functions.md[.tmpl]` | Generic function page (or template) | +| `templates/functions/.md[.tmpl]` | Function page (or template) | +| `templates/list-resources.md[.tmpl]` | Generic list resource page (or template) | +| `templates/list-resources/.md[.tmpl]` | List resource page (or template) | +| `templates/resources.md[.tmpl]` | Generic resource page (or template) | +| `templates/resources/.md[.tmpl]` | Resource page (or template) | Note: the `.tmpl` extension is necessary, for the file to be correctly handled as a template. @@ -234,6 +237,7 @@ For examples: | `examples/data-sources//data-source<*>.tf` | Data source example config(s) | | `examples/ephemeral-resources//ephemeral-resource<*>.tf` | Ephemeral resource example config(s) | | `examples/functions//function<*>.tf` | Function example config(s) | +| `examples/list-resources//list-resource<*>.tfquery.hcl` | List resource example config(s) | | `examples/resources//resource<*>.tf` | Resource example config(s) | | `examples/resources//import.sh` | Resource example import command | | `examples/resources//import-by-string-id.tf` | Resource example import by id config | @@ -257,6 +261,7 @@ Legacy website directory structure: | `website/docs/d/.html.markdown` | Data source page | | `website/docs/ephemeral-resources/.html.markdown` | Ephemeral resource page | | `website/docs/functons/.html.markdown` | Functions page | +| `website/docs/list-resources/.html.markdown` | List resource page | | `website/docs/r/.html.markdown` | Resource page | Docs website directory structure: @@ -270,6 +275,7 @@ Docs website directory structure: | `docs/data-sources/.html.markdown` | Data source page | | `docs/ephemeral-resources/.html.markdown` | Ephemeral resource page | | `docs/functions/.html.markdown` | Function page | +| `docs/list-resources/.html.markdown` | List resource page | | `docs/resources/.html.markdown` | Resource page | Files named `index` (before the first `.`) in the website docs root directory and files in the `website/docs/d/`, `website/docs/r/`, `docs/data-sources/`, @@ -357,6 +363,22 @@ using the following data fields and functions: | `.RenderedProviderName` | string | Value provided via argument `--rendered-provider-name`, otherwise same as `.ProviderName` | | `.SchemaMarkdown` | string | a Markdown formatted Action Schema definition | +##### List Resource Fields + +| Field | Type | Description | +|-------------------------|--------|------------------------------------------------------------------------------------------------------------------------------------------------| +| `.Name` | string | Name of the list resource (ex. `examplecloud_thing`) | +| `.Type` | string | `List Resource` | +| `.Description` | string | List resource description | +| `.HasExample` | bool | (Legacy) Is there an example file? | +| `.HasExamples` | bool | Are there example files? Always true if HasExample is true. | +| `.ExampleFile` | string | (Legacy) Path to the file with the terraform configuration example | +| `.ExampleFiles` | string | Paths to the files with terraform configuration examples. Includes ExampleFile. The file extension for ExampleFiles should be `*.tfquery.hcl`. | +| `.ProviderName` | string | Canonical provider name (ex. `terraform-provider-random`) | +| `.ProviderShortName` | string | Short version of the rendered provider name (ex. `random`) | +| `.RenderedProviderName` | string | Value provided via argument `--rendered-provider-name`, otherwise same as `.ProviderName` | +| `.SchemaMarkdown` | string | a Markdown formatted list resource Schema definition | + #### Template Functions | Function | Description | diff --git a/cmd/tfplugindocs/testdata/scripts/provider-build/generate/framework_provider_success_generic_templates.txtar b/cmd/tfplugindocs/testdata/scripts/provider-build/generate/framework_provider_success_generic_templates.txtar index 8dd3e6cc..4142a930 100644 --- a/cmd/tfplugindocs/testdata/scripts/provider-build/generate/framework_provider_success_generic_templates.txtar +++ b/cmd/tfplugindocs/testdata/scripts/provider-build/generate/framework_provider_success_generic_templates.txtar @@ -28,6 +28,7 @@ data-source "scaffolding_example" fallback template exists, creating template generating missing function content generating missing ephemeral resource content generating missing action content +generating missing list resource content generating missing provider content provider "terraform-provider-scaffolding" template exists, skipping rendering static website diff --git a/cmd/tfplugindocs/testdata/scripts/provider-build/generate/framework_provider_success_named_templates.txtar b/cmd/tfplugindocs/testdata/scripts/provider-build/generate/framework_provider_success_named_templates.txtar index 492690c0..68e8f404 100644 --- a/cmd/tfplugindocs/testdata/scripts/provider-build/generate/framework_provider_success_named_templates.txtar +++ b/cmd/tfplugindocs/testdata/scripts/provider-build/generate/framework_provider_success_named_templates.txtar @@ -28,6 +28,7 @@ data-source "scaffolding_example" template exists, skipping generating missing function content generating missing ephemeral resource content generating missing action content +generating missing list resource content generating missing provider content provider "terraform-provider-scaffolding" template exists, skipping rendering static website diff --git a/cmd/tfplugindocs/testdata/scripts/provider-build/generate/framework_provider_success_no_templates.txtar b/cmd/tfplugindocs/testdata/scripts/provider-build/generate/framework_provider_success_no_templates.txtar index f599fc4e..80511f7f 100644 --- a/cmd/tfplugindocs/testdata/scripts/provider-build/generate/framework_provider_success_no_templates.txtar +++ b/cmd/tfplugindocs/testdata/scripts/provider-build/generate/framework_provider_success_no_templates.txtar @@ -26,6 +26,7 @@ generating new template for data-source "scaffolding_example" generating missing function content generating missing ephemeral resource content generating missing action content +generating missing list resource content generating missing provider content generating new template for "terraform-provider-scaffolding" rendering static website diff --git a/cmd/tfplugindocs/testdata/scripts/provider-build/generate/null_provider_success.txtar b/cmd/tfplugindocs/testdata/scripts/provider-build/generate/null_provider_success.txtar index 1ae070d2..95e0d6d2 100644 --- a/cmd/tfplugindocs/testdata/scripts/provider-build/generate/null_provider_success.txtar +++ b/cmd/tfplugindocs/testdata/scripts/provider-build/generate/null_provider_success.txtar @@ -25,6 +25,7 @@ data-source "null_data_source" fallback template exists, creating template generating missing function content generating missing ephemeral resource content generating missing action content +generating missing list resource content generating missing provider content provider "terraform-provider-null" template exists, skipping rendering static website diff --git a/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_all_framework_types.txtar b/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_all_framework_types.txtar index 3a4c9bb2..f7f9148d 100644 --- a/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_all_framework_types.txtar +++ b/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_all_framework_types.txtar @@ -21,6 +21,7 @@ generating missing function content generating new template for function "scaffolding" generating missing ephemeral resource content generating missing action content +generating missing list resource content generating missing provider content generating new template for "terraform-provider-scaffolding" rendering static website diff --git a/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_generic_templates.txtar b/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_generic_templates.txtar index 3db43b54..e64e8b8d 100644 --- a/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_generic_templates.txtar +++ b/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_generic_templates.txtar @@ -12,6 +12,7 @@ cmpenv docs/resources/example.md expected-resource.md cmpenv docs/functions/example.md expected-function.md cmpenv docs/ephemeral-resources/example.md expected-ephemeral-resource.md cmpenv docs/actions/example.md expected-action.md +cmpenv docs/list-resources/example.md expected-list-resource.md -- expected-output.txt -- @@ -30,6 +31,8 @@ generating missing ephemeral resource content ephemeral resource "scaffolding_example" fallback template exists, creating template generating missing action content action "scaffolding_example" fallback template exists, creating template +generating missing list resource content +list resource "scaffolding_example" fallback template exists, creating template generating missing provider content provider "terraform-provider-scaffolding" template exists, skipping rendering static website @@ -40,6 +43,7 @@ rendering "data-sources/example.md.tmpl" rendering "ephemeral-resources/example.md.tmpl" rendering "functions/example.md.tmpl" rendering "index.md.tmpl" +rendering "list-resources/example.md.tmpl" rendering "resources/example.md.tmpl" -- expected-action.md -- # Data Fields @@ -92,6 +96,59 @@ action "scaffolding_example" "example" { } } ``` +-- expected-list-resource.md -- +# Data Fields + +Name: scaffolding_example +Type: List Resource +Description: Example list resource +HasExample: true +ExampleFile: $WORK/examples/list-resources/scaffolding_example/list-resource.tfquery.hcl +ProviderName: terraform-provider-scaffolding +ProviderShortName: scaffolding +RenderedProviderName: terraform-provider-scaffolding +SchemaMarkdown: +## Schema + +### Required + +- `required_attr` (String) Example required attribute + +### Optional + +- `optional_attr` (String) Example optional attribute + + + +# Functions + +lower: list resource +plainmarkdown: List Resource +prefixlines: Prefix: List Resource +split: [scaffolding example] +title: List Resource +trimspace: List Resource +upper: LIST RESOURCE + +# Conditionals and File Functions + +printf tffile: +## Example Usage + +{{tffile "$WORK/examples/list-resources/scaffolding_example/list-resource.tfquery.hcl"}} + +tffile: +## Example Usage + +```terraform +list "scaffolding_example" "example" { + provider = scaffolding + + config { + required_attr = "some-value" + } +} +``` -- expected-datasource.md -- # Data Fields @@ -365,6 +422,44 @@ resource "scaffolding_example" "example" { configurable_attribute = "some-value" } ``` +-- templates/list-resources.md.tmpl -- +# Data Fields + +Name: {{.Name}} +Type: {{.Type}} +Description: {{.Description}} +HasExample: {{.HasExample}} +ExampleFile: {{.ExampleFile}} +ProviderName: {{.ProviderName}} +ProviderShortName: {{.ProviderShortName}} +RenderedProviderName: {{.RenderedProviderName}} +SchemaMarkdown: {{.SchemaMarkdown}} + +# Functions + +lower: {{ .Type | lower }} +plainmarkdown: {{ .Type | plainmarkdown }} +prefixlines: {{ .Type | prefixlines "Prefix: " }} +split: {{ split .Name "_" }} +title: {{ .Type | title }} +trimspace: {{ .Type | trimspace }} +upper: {{ .Type | upper }} + +# Conditionals and File Functions + +printf tffile: +{{ if .HasExample -}} +## Example Usage + +{{ printf "{{tffile %q}}" .ExampleFile }} +{{- end }} + +tffile: +{{ if .HasExample -}} +## Example Usage + +{{tffile .ExampleFile }} +{{- end }} -- templates/actions.md.tmpl -- # Data Fields @@ -671,6 +766,14 @@ action "scaffolding_example" "example" { required_attr = "some-value" } } +-- examples/list-resources/scaffolding_example/list-resource.tfquery.hcl -- +list "scaffolding_example" "example" { + provider = scaffolding + + config { + required_attr = "some-value" + } +} -- examples/data-sources/scaffolding_example/data-source.tf -- data "scaffolding_example" "example" { configurable_attribute = "some-value" @@ -722,6 +825,29 @@ resource "scaffolding_example" "example" { "description_kind": "markdown" } }, + "list_resource_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "required_attr": { + "type": "string", + "description": "Example required attribute", + "description_kind": "plain", + "required": true + }, + "optional_attr": { + "type": "string", + "description": "Example optional attribute", + "description_kind": "plain", + "optional": true + } + }, + "description": "Example list resource", + "description_kind": "plain" + } + } + }, "action_schemas": { "scaffolding_example": { "version": 0, diff --git a/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_legacy_docs.txtar b/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_legacy_docs.txtar index 16b488a7..9271396d 100644 --- a/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_legacy_docs.txtar +++ b/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_legacy_docs.txtar @@ -32,6 +32,11 @@ cmp templates/actions/example.markdown docs/actions/example.markdown cmp templates/actions/example.html.markdown docs/actions/example.html.markdown cmp templates/actions/example.html.md docs/actions/example.html.md +cmp templates/list-resources/example.md docs/list-resources/example.md +cmp templates/list-resources/example.markdown docs/list-resources/example.markdown +cmp templates/list-resources/example.html.markdown docs/list-resources/example.html.markdown +cmp templates/list-resources/example.html.md docs/list-resources/example.html.md + cmp templates/index.md docs/index.md cmp templates/index.markdown docs/index.markdown cmp templates/index.html.markdown docs/index.html.markdown @@ -52,6 +57,8 @@ generating missing ephemeral resource content ephemeral resource "scaffolding_example" static file exists, skipping generating missing action content action "scaffolding_example" static file exists, skipping +generating missing list resource content +list resource "scaffolding_example" static file exists, skipping generating missing provider content provider "terraform-provider-scaffolding" static file exists, skipping rendering static website @@ -77,6 +84,10 @@ copying non-template file: "index.html.markdown" copying non-template file: "index.html.md" copying non-template file: "index.markdown" copying non-template file: "index.md" +copying non-template file: "list-resources/example.html.markdown" +copying non-template file: "list-resources/example.html.md" +copying non-template file: "list-resources/example.markdown" +copying non-template file: "list-resources/example.md" copying non-template file: "r/example.html.markdown" copying non-template file: "r/example.html.md" copying non-template file: "r/example.markdown" @@ -99,6 +110,26 @@ Type: {{.Type}} -- templates/actions/example.html.md -- # Data Fields +Name: {{.Name}} +Type: {{.Type}} +-- templates/list-resources/example.md -- +# Data Fields + +Name: {{.Name}} +Type: {{.Type}} +-- templates/list-resources/example.markdown -- +# Data Fields + +Name: {{.Name}} +Type: {{.Type}} +-- templates/list-resources/example.html.markdown -- +# Data Fields + +Name: {{.Name}} +Type: {{.Type}} +-- templates/list-resources/example.html.md -- +# Data Fields + Name: {{.Name}} Type: {{.Type}} -- templates/r/example.md -- @@ -217,6 +248,14 @@ action "scaffolding_example" "example" { required_attr = "some-value" } } +-- examples/list-resources/scaffolding_example/list-resource.tfquery.hcl -- +list "scaffolding_example" "example" { + provider = scaffolding + + config { + required_attr = "some-value" + } +} -- examples/data-sources/scaffolding_example/data-source.tf -- data "scaffolding_example" "example" { configurable_attribute = "some-value" @@ -264,6 +303,29 @@ terraform import scaffolding_example.example "id-123" "description_kind": "markdown" } }, + "list_resource_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "required_attr": { + "type": "string", + "description": "Example required attribute", + "description_kind": "plain", + "required": true + }, + "optional_attr": { + "type": "string", + "description": "Example optional attribute", + "description_kind": "plain", + "optional": true + } + }, + "description": "Example list resource", + "description_kind": "plain" + } + } + }, "action_schemas": { "scaffolding_example": { "version": 0, diff --git a/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_named_templates.txtar b/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_named_templates.txtar index aeb62e65..6e49a340 100644 --- a/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_named_templates.txtar +++ b/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_named_templates.txtar @@ -12,6 +12,7 @@ cmpenv docs/resources/example.md expected-resource.md cmpenv docs/functions/example.md expected-function.md cmpenv docs/ephemeral-resources/example.md expected-ephemeral-resource.md cmpenv docs/actions/example.md expected-action.md +cmpenv docs/list-resources/example.md expected-list-resource.md -- expected-output.txt -- rendering website for provider "terraform-provider-scaffolding" (as "Scaffolding") @@ -29,6 +30,8 @@ generating missing ephemeral resource content ephemeral resource "scaffolding_example" template exists, skipping generating missing action content action "scaffolding_example" template exists, skipping +generating missing list resource content +list resource "scaffolding_example" template exists, skipping generating missing provider content provider "terraform-provider-scaffolding" template exists, skipping rendering static website @@ -39,6 +42,7 @@ rendering "data-sources/example.md.tmpl" rendering "ephemeral-resources/example.md.tmpl" rendering "functions/example.md.tmpl" rendering "index.md.tmpl" +rendering "list-resources/example.md.tmpl" rendering "resources/example.md.tmpl" -- expected-action.md -- # Data Fields @@ -91,6 +95,59 @@ action "scaffolding_example" "example" { } } ``` +-- expected-list-resource.md -- +# Data Fields + +Name: scaffolding_example +Type: List Resource +Description: Example list resource +HasExample: true +ExampleFile: $WORK/examples/list-resources/scaffolding_example/list-resource.tfquery.hcl +ProviderName: terraform-provider-scaffolding +ProviderShortName: Scaffolding +RenderedProviderName: Scaffolding +SchemaMarkdown: +## Schema + +### Required + +- `required_attr` (String) Example required attribute + +### Optional + +- `optional_attr` (String) Example optional attribute + + + +# Functions + +lower: list resource +plainmarkdown: List Resource +prefixlines: Prefix: List Resource +split: [scaffolding example] +title: List Resource +trimspace: List Resource +upper: LIST RESOURCE + +# Conditionals and File Functions + +printf tffile: +## Example Usage + +{{tffile "$WORK/examples/list-resources/scaffolding_example/list-resource.tfquery.hcl"}} + +tffile: +## Example Usage + +```terraform +list "scaffolding_example" "example" { + provider = scaffolding + + config { + required_attr = "some-value" + } +} +``` -- expected-datasource.md -- # Data Fields @@ -414,6 +471,44 @@ tffile: {{ if .HasExample -}} ## Example Usage +{{tffile .ExampleFile }} +{{- end }} +-- templates/list-resources/example.md.tmpl -- +# Data Fields + +Name: {{.Name}} +Type: {{.Type}} +Description: {{.Description}} +HasExample: {{.HasExample}} +ExampleFile: {{.ExampleFile}} +ProviderName: {{.ProviderName}} +ProviderShortName: {{.ProviderShortName}} +RenderedProviderName: {{.RenderedProviderName}} +SchemaMarkdown: {{.SchemaMarkdown}} + +# Functions + +lower: {{ .Type | lower }} +plainmarkdown: {{ .Type | plainmarkdown }} +prefixlines: {{ .Type | prefixlines "Prefix: " }} +split: {{ split .Name "_" }} +title: {{ .Type | title }} +trimspace: {{ .Type | trimspace }} +upper: {{ .Type | upper }} + +# Conditionals and File Functions + +printf tffile: +{{ if .HasExample -}} +## Example Usage + +{{ printf "{{tffile %q}}" .ExampleFile }} +{{- end }} + +tffile: +{{ if .HasExample -}} +## Example Usage + {{tffile .ExampleFile }} {{- end }} -- templates/data-sources/example.md.tmpl -- @@ -687,6 +782,14 @@ action "scaffolding_example" "example" { required_attr = "some-value" } } +-- examples/list-resources/scaffolding_example/list-resource.tfquery.hcl -- +list "scaffolding_example" "example" { + provider = scaffolding + + config { + required_attr = "some-value" + } +} -- examples/data-sources/scaffolding_example/data-source.tf -- data "scaffolding_example" "example" { configurable_attribute = "some-value" @@ -751,6 +854,29 @@ terraform import scaffolding_example.example "id-123" "description_kind": "markdown" } }, + "list_resource_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "required_attr": { + "type": "string", + "description": "Example required attribute", + "description_kind": "plain", + "required": true + }, + "optional_attr": { + "type": "string", + "description": "Example optional attribute", + "description_kind": "plain", + "optional": true + } + }, + "description": "Example list resource", + "description_kind": "plain" + } + } + }, "action_schemas": { "scaffolding_example": { "version": 0, diff --git a/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_no_templates_multiple_examples.txtar b/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_no_templates_multiple_examples.txtar index 40da7337..6157b614 100644 --- a/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_no_templates_multiple_examples.txtar +++ b/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_no_templates_multiple_examples.txtar @@ -27,6 +27,7 @@ generating new template for function "no-variadic" generating missing ephemeral resource content generating new template for "scaffolding_example" generating missing action content +generating missing list resource content generating missing provider content generating new template for "terraform-provider-scaffolding" rendering static website diff --git a/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_no_templates_single_example.txtar b/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_no_templates_single_example.txtar index 0cd495cb..e8dd6d6e 100644 --- a/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_no_templates_single_example.txtar +++ b/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_no_templates_single_example.txtar @@ -12,6 +12,7 @@ cmp docs/functions/example.md expected-function.md cmp docs/functions/no-variadic.md expected-no-variadic-function.md cmp docs/ephemeral-resources/example.md expected-ephemeral-resource.md cmp docs/actions/example.md expected-action.md +cmp docs/list-resources/example.md expected-list-resource.md -- expected-output.txt -- rendering website for provider "terraform-provider-scaffolding" (as "Scaffolding") @@ -29,6 +30,8 @@ generating missing ephemeral resource content generating new template for "scaffolding_example" generating missing action content generating new template for "scaffolding_example" +generating missing list resource content +generating new template for "scaffolding_example" generating missing provider content generating new template for "terraform-provider-scaffolding" rendering static website @@ -40,6 +43,7 @@ rendering "ephemeral-resources/example.md.tmpl" rendering "functions/example.md.tmpl" rendering "functions/no-variadic.md.tmpl" rendering "index.md.tmpl" +rendering "list-resources/example.md.tmpl" rendering "resources/example.md.tmpl" -- expected-action.md -- --- @@ -73,6 +77,41 @@ action "scaffolding_example" "example" { ### Optional +- `optional_attr` (String) Example optional attribute +-- expected-list-resource.md -- +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "scaffolding_example List Resource - Scaffolding" +subcategory: "" +description: |- + Example list resource +--- + +# scaffolding_example (List Resource) + +Example list resource + +## Example Usage + +```terraform +list "scaffolding_example" "example" { + provider = scaffolding + + config { + required_attr = "some-value" + } +} +``` + + +## Schema + +### Required + +- `required_attr` (String) Example required attribute + +### Optional + - `optional_attr` (String) Example optional attribute -- expected-datasource.md -- --- @@ -323,6 +362,14 @@ action "scaffolding_example" "example" { required_attr = "some-value" } } +-- examples/list-resources/scaffolding_example/list-resource.tfquery.hcl -- +list "scaffolding_example" "example" { + provider = scaffolding + + config { + required_attr = "some-value" + } +} -- examples/data-sources/scaffolding_example/data-source.tf -- data "scaffolding_example" "example" { configurable_attribute = "some-value" @@ -390,6 +437,29 @@ resource "scaffolding_example" "example" { "description_kind": "markdown" } }, + "list_resource_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "required_attr": { + "type": "string", + "description": "Example required attribute", + "description_kind": "plain", + "required": true + }, + "optional_attr": { + "type": "string", + "description": "Example optional attribute", + "description_kind": "plain", + "optional": true + } + }, + "description": "Example list resource", + "description_kind": "plain" + } + } + }, "action_schemas": { "scaffolding_example": { "version": 0, diff --git a/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_static_files.txtar b/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_static_files.txtar index 26795fbd..9c4f0deb 100644 --- a/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_static_files.txtar +++ b/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_static_files.txtar @@ -32,6 +32,11 @@ cmp templates/actions/example.markdown docs/actions/example.markdown cmp templates/actions/example.html.markdown docs/actions/example.html.markdown cmp templates/actions/example.html.md docs/actions/example.html.md +cmp templates/list-resources/example.md docs/list-resources/example.md +cmp templates/list-resources/example.markdown docs/list-resources/example.markdown +cmp templates/list-resources/example.html.markdown docs/list-resources/example.html.markdown +cmp templates/list-resources/example.html.md docs/list-resources/example.html.md + cmp templates/index.md docs/index.md cmp templates/index.markdown docs/index.markdown cmp templates/index.html.markdown docs/index.html.markdown @@ -52,6 +57,8 @@ generating missing ephemeral resource content ephemeral resource "scaffolding_example" static file exists, skipping generating missing action content action "scaffolding_example" static file exists, skipping +generating missing list resource content +list resource "scaffolding_example" static file exists, skipping generating missing provider content provider "terraform-provider-scaffolding" static file exists, skipping rendering static website @@ -77,6 +84,10 @@ copying non-template file: "index.html.markdown" copying non-template file: "index.html.md" copying non-template file: "index.markdown" copying non-template file: "index.md" +copying non-template file: "list-resources/example.html.markdown" +copying non-template file: "list-resources/example.html.md" +copying non-template file: "list-resources/example.markdown" +copying non-template file: "list-resources/example.md" copying non-template file: "resources/example.html.markdown" copying non-template file: "resources/example.html.md" copying non-template file: "resources/example.markdown" @@ -99,6 +110,26 @@ Type: {{.Type}} -- templates/actions/example.html.md -- # Data Fields +Name: {{.Name}} +Type: {{.Type}} +-- templates/list-resources/example.md -- +# Data Fields + +Name: {{.Name}} +Type: {{.Type}} +-- templates/list-resources/example.markdown -- +# Data Fields + +Name: {{.Name}} +Type: {{.Type}} +-- templates/list-resources/example.html.markdown -- +# Data Fields + +Name: {{.Name}} +Type: {{.Type}} +-- templates/list-resources/example.html.md -- +# Data Fields + Name: {{.Name}} Type: {{.Type}} -- templates/resources/example.md -- @@ -217,6 +248,14 @@ action "scaffolding_example" "example" { required_attr = "some-value" } } +-- examples/list-resources/scaffolding_example/list-resource.tfquery.hcl -- +list "scaffolding_example" "example" { + provider = scaffolding + + config { + required_attr = "some-value" + } +} -- examples/data-sources/scaffolding_example/data-source.tf -- data "scaffolding_example" "example" { configurable_attribute = "some-value" @@ -264,6 +303,29 @@ terraform import scaffolding_example.example "id-123" "description_kind": "markdown" } }, + "list_resource_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "required_attr": { + "type": "string", + "description": "Example required attribute", + "description_kind": "plain", + "required": true + }, + "optional_attr": { + "type": "string", + "description": "Example optional attribute", + "description_kind": "plain", + "optional": true + } + }, + "description": "Example list resource", + "description_kind": "plain" + } + } + }, "action_schemas": { "scaffolding_example": { "version": 0, diff --git a/cmd/tfplugindocs/testdata/scripts/schema-json/generate/nested_id_attribute.txtar b/cmd/tfplugindocs/testdata/scripts/schema-json/generate/nested_id_attribute.txtar index f685ac42..d47aa591 100644 --- a/cmd/tfplugindocs/testdata/scripts/schema-json/generate/nested_id_attribute.txtar +++ b/cmd/tfplugindocs/testdata/scripts/schema-json/generate/nested_id_attribute.txtar @@ -19,6 +19,7 @@ generating missing data source content generating missing function content generating missing ephemeral resource content generating missing action content +generating missing list resource content generating missing provider content generating new template for "terraform-provider-scaffolding" rendering static website diff --git a/cmd/tfplugindocs/testdata/scripts/schema-json/generate/null_provider_success.txtar b/cmd/tfplugindocs/testdata/scripts/schema-json/generate/null_provider_success.txtar index 619257a0..d3c8e089 100644 --- a/cmd/tfplugindocs/testdata/scripts/schema-json/generate/null_provider_success.txtar +++ b/cmd/tfplugindocs/testdata/scripts/schema-json/generate/null_provider_success.txtar @@ -20,6 +20,7 @@ data-source "null_data_source" fallback template exists, creating template generating missing function content generating missing ephemeral resource content generating missing action content +generating missing list resource content generating missing provider content provider "terraform-provider-null" template exists, skipping rendering static website diff --git a/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_docs_website.txtar b/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_docs_website.txtar index e2cf2639..2f5e52a7 100644 --- a/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_docs_website.txtar +++ b/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_docs_website.txtar @@ -17,6 +17,7 @@ cmpenv templates/resources/sleep.md.tmpl exp-templates/resources/sleep.md.tmpl cmpenv templates/resources/static.md.tmpl exp-templates/resources/static.md.tmpl cmpenv templates/ephemeral-resources/ephemeral_static.md.tmpl exp-templates/ephemeral-resources/ephemeral_static.md.tmpl cmpenv templates/actions/example.md.tmpl exp-templates/actions/example.md.tmpl +cmpenv templates/list-resources/example.md.tmpl exp-templates/list-resources/example.md.tmpl # Check generated example files cmpenv examples/example_1.tf examples/example_1.tf @@ -48,6 +49,8 @@ cmpenv examples/ephemeral-resources/ephemeral_static/import_1.sh exp-examples/ep cmpenv examples/actions/example/example_1.tf exp-examples/actions/example/example_1.tf cmpenv examples/actions/example/example_2.tf exp-examples/actions/example/example_2.tf +cmpenv examples/list-resources/example/example_1.tfquery.hcl exp-examples/list-resources/example/example_1.tfquery.hcl + -- expected-output.txt -- migrating website from "$WORK/docs" to "$WORK/templates" migrating actions directory: actions @@ -78,6 +81,12 @@ extracting YAML frontmatter to "$WORK/templates/index.md.tmpl" extracting code examples from "index.html.markdown" creating example file "$WORK/examples/example_1.tf" finished creating template "$WORK/templates/index.md.tmpl" +migrating list resources directory: list-resources +migrating file "example.html.markdown" +extracting YAML frontmatter to "$WORK/templates/list-resources/example.md.tmpl" +extracting code examples from "example.html.markdown" +creating example file "$WORK/examples/list-resources/example/example_1.tfquery.hcl" +finished creating template "$WORK/templates/list-resources/example.md.tmpl" migrating resources directory: resources migrating file "offset.html.markdown" extracting YAML frontmatter to "$WORK/templates/resources/offset.md.tmpl" @@ -643,6 +652,25 @@ $ terraform import time_static.example 2020-02-12T06:36:13Z ``` The `triggers` argument cannot be imported. +-- docs/list-resources/example.html.markdown -- +--- +layout: "time" +page_title: "Time: time_example" +description: |- + Just a fake example. +--- + +Just a fake example. + +```hcl +list "scaffolding_example" "example" { + provider = scaffolding + + config { + required_attr = "value-1" + } +} +``` -- exp-examples/example_1.tf -- resource "time_static" "ami_update" { triggers = { @@ -828,6 +856,14 @@ resource "aws_instance" "server" { } -- exp-examples/ephemeral-resources/ephemeral_static/import_1.sh -- $ terraform import time_static.example 2020-02-12T06:36:13Z +-- exp-examples/list-resources/example/example_1.tfquery.hcl -- +list "scaffolding_example" "example" { + provider = scaffolding + + config { + required_attr = "value-1" + } +} -- exp-templates/index.md.tmpl -- --- page_title: "Provider: Time" @@ -1199,4 +1235,18 @@ Just a fake example. {{tffile "examples/actions/example/example_1.tf"}} -{{tffile "examples/actions/example/example_2.tf"}} \ No newline at end of file +{{tffile "examples/actions/example/example_2.tf"}} +-- exp-templates/list-resources/example.md.tmpl -- +--- +page_title: "Time: time_example" +description: |- + Just a fake example. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +Just a fake example. + +{{tffile "examples/list-resources/example/example_1.tfquery.hcl"}} diff --git a/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_docs_website_with_prefix.txtar b/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_docs_website_with_prefix.txtar index c50ac192..f518b030 100644 --- a/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_docs_website_with_prefix.txtar +++ b/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_docs_website_with_prefix.txtar @@ -17,6 +17,7 @@ cmpenv templates/resources/sleep.md.tmpl exp-templates/resources/sleep.md.tmpl cmpenv templates/resources/static.md.tmpl exp-templates/resources/static.md.tmpl cmpenv templates/ephemeral-resources/ephemeral_static.md.tmpl exp-templates/ephemeral-resources/ephemeral_static.md.tmpl cmpenv templates/actions/example.md.tmpl exp-templates/actions/example.md.tmpl +cmpenv templates/list-resources/example.md.tmpl exp-templates/list-resources/example.md.tmpl # Check generated example files cmpenv examples/example_1.tf examples/example_1.tf @@ -48,6 +49,8 @@ cmpenv examples/ephemeral-resources/ephemeral_static/import_1.sh exp-examples/ep cmpenv examples/actions/example/example_1.tf exp-examples/actions/example/example_1.tf cmpenv examples/actions/example/example_2.tf exp-examples/actions/example/example_2.tf +cmpenv examples/list-resources/example/example_1.tfquery.hcl exp-examples/list-resources/example/example_1.tfquery.hcl + -- expected-output.txt -- migrating website from "$WORK/docs" to "$WORK/templates" migrating actions directory: actions @@ -78,6 +81,12 @@ extracting YAML frontmatter to "$WORK/templates/index.md.tmpl" extracting code examples from "index.html.markdown" creating example file "$WORK/examples/example_1.tf" finished creating template "$WORK/templates/index.md.tmpl" +migrating list resources directory: list-resources +migrating file "example.html.markdown" +extracting YAML frontmatter to "$WORK/templates/list-resources/example.md.tmpl" +extracting code examples from "example.html.markdown" +creating example file "$WORK/examples/list-resources/example/example_1.tfquery.hcl" +finished creating template "$WORK/templates/list-resources/example.md.tmpl" migrating resources directory: resources migrating file "time_offset.html.markdown" extracting YAML frontmatter to "$WORK/templates/resources/offset.md.tmpl" @@ -643,6 +652,25 @@ $ terraform import time_static.example 2020-02-12T06:36:13Z ``` The `triggers` argument cannot be imported. +-- docs/list-resources/example.html.markdown -- +--- +layout: "time" +page_title: "Time: time_example" +description: |- + Just a fake example. +--- + +Just a fake example. + +```hcl +list "scaffolding_example" "example" { + provider = scaffolding + + config { + required_attr = "value-1" + } +} +``` -- exp-examples/example_1.tf -- resource "time_static" "ami_update" { triggers = { @@ -801,6 +829,14 @@ action "scaffolding_example" "example2" { required_attr = "value-2" } } +-- exp-examples/list-resources/example/example_1.tfquery.hcl -- +list "scaffolding_example" "example" { + provider = scaffolding + + config { + required_attr = "value-1" + } +} -- exp-examples/ephemeral-resources/ephemeral_static/example_1.tf -- resource "time_static" "example" {} @@ -1199,4 +1235,18 @@ Just a fake example. {{tffile "examples/actions/example/example_1.tf"}} -{{tffile "examples/actions/example/example_2.tf"}} \ No newline at end of file +{{tffile "examples/actions/example/example_2.tf"}} +-- exp-templates/list-resources/example.md.tmpl -- +--- +page_title: "Time: time_example" +description: |- + Just a fake example. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +Just a fake example. + +{{tffile "examples/list-resources/example/example_1.tfquery.hcl"}} diff --git a/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_legacy_website.txtar b/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_legacy_website.txtar index 088501c5..85115325 100644 --- a/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_legacy_website.txtar +++ b/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_legacy_website.txtar @@ -17,6 +17,7 @@ cmpenv templates/resources/sleep.md.tmpl exp-templates/resources/sleep.md.tmpl cmpenv templates/resources/static.md.tmpl exp-templates/resources/static.md.tmpl cmpenv templates/ephemeral-resources/ephemeral_static.md.tmpl exp-templates/ephemeral-resources/ephemeral_static.md.tmpl cmpenv templates/actions/example.md.tmpl exp-templates/actions/example.md.tmpl +cmpenv templates/list-resources/example.md.tmpl exp-templates/list-resources/example.md.tmpl # Check generated example files cmpenv examples/example_1.tf examples/example_1.tf @@ -48,6 +49,8 @@ cmpenv examples/ephemeral-resources/ephemeral_static/import_1.sh exp-examples/ep cmpenv examples/actions/example/example_1.tf exp-examples/actions/example/example_1.tf cmpenv examples/actions/example/example_2.tf exp-examples/actions/example/example_2.tf +cmpenv examples/list-resources/example/example_1.tfquery.hcl exp-examples/list-resources/example/example_1.tfquery.hcl + # Verify legacy website directory is removed ! exists website/ @@ -81,6 +84,12 @@ extracting YAML frontmatter to "$WORK/templates/index.md.tmpl" extracting code examples from "index.html.markdown" creating example file "$WORK/examples/example_1.tf" finished creating template "$WORK/templates/index.md.tmpl" +migrating list resources directory: list-resources +migrating file "example.html.markdown" +extracting YAML frontmatter to "$WORK/templates/list-resources/example.md.tmpl" +extracting code examples from "example.html.markdown" +creating example file "$WORK/examples/list-resources/example/example_1.tfquery.hcl" +finished creating template "$WORK/templates/list-resources/example.md.tmpl" migrating resources directory: r migrating file "offset.html.markdown" extracting YAML frontmatter to "$WORK/templates/resources/offset.md.tmpl" @@ -646,6 +655,25 @@ $ terraform import time_static.example 2020-02-12T06:36:13Z ``` The `triggers` argument cannot be imported. +-- website/docs/list-resources/sleep/example.html.markdown -- +--- +layout: "time" +page_title: "Time: time_example" +description: |- + Just a fake example. +--- + +Just a fake example. + +```hcl +list "scaffolding_example" "example" { + provider = scaffolding + + config { + required_attr = "value-1" + } +} +``` -- exp-examples/example_1.tf -- resource "time_static" "ami_update" { triggers = { @@ -831,6 +859,14 @@ resource "aws_instance" "server" { } -- exp-examples/ephemeral-resources/ephemeral_static/import_1.sh -- $ terraform import time_static.example 2020-02-12T06:36:13Z +-- exp-examples/list-resources/example/example_1.tfquery.hcl -- +list "scaffolding_example" "example" { + provider = scaffolding + + config { + required_attr = "value-1" + } +} -- exp-templates/index.md.tmpl -- --- page_title: "Provider: Time" @@ -1202,4 +1238,18 @@ Just a fake example. {{tffile "examples/actions/example/example_1.tf"}} -{{tffile "examples/actions/example/example_2.tf"}} \ No newline at end of file +{{tffile "examples/actions/example/example_2.tf"}} +-- exp-templates/list-resources/example.md.tmpl -- +--- +page_title: "Time: time_example" +description: |- + Just a fake example. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +Just a fake example. + +{{tffile "examples/list-resources/example/example_1.tfquery.hcl"}} diff --git a/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_legacy_website_with_prefix.txtar b/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_legacy_website_with_prefix.txtar index 0e071534..9193eae2 100644 --- a/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_legacy_website_with_prefix.txtar +++ b/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_success_legacy_website_with_prefix.txtar @@ -17,6 +17,7 @@ cmpenv templates/resources/sleep.md.tmpl exp-templates/resources/sleep.md.tmpl cmpenv templates/resources/static.md.tmpl exp-templates/resources/static.md.tmpl cmpenv templates/ephemeral-resources/ephemeral_static.md.tmpl exp-templates/ephemeral-resources/ephemeral_static.md.tmpl cmpenv templates/actions/example.md.tmpl exp-templates/actions/example.md.tmpl +cmpenv templates/list-resources/example.md.tmpl exp-templates/list-resources/example.md.tmpl # Check generated example files cmpenv examples/example_1.tf examples/example_1.tf @@ -48,6 +49,8 @@ cmpenv examples/ephemeral-resources/ephemeral_static/import_1.sh exp-examples/ep cmpenv examples/actions/example/example_1.tf exp-examples/actions/example/example_1.tf cmpenv examples/actions/example/example_2.tf exp-examples/actions/example/example_2.tf +cmpenv examples/list-resources/example/example_1.tfquery.hcl exp-examples/list-resources/example/example_1.tfquery.hcl + # Verify legacy website directory is removed ! exists website/ @@ -81,6 +84,12 @@ extracting YAML frontmatter to "$WORK/templates/index.md.tmpl" extracting code examples from "index.html.markdown" creating example file "$WORK/examples/example_1.tf" finished creating template "$WORK/templates/index.md.tmpl" +migrating list resources directory: list-resources +migrating file "example.html.markdown" +extracting YAML frontmatter to "$WORK/templates/list-resources/example.md.tmpl" +extracting code examples from "example.html.markdown" +creating example file "$WORK/examples/list-resources/example/example_1.tfquery.hcl" +finished creating template "$WORK/templates/list-resources/example.md.tmpl" migrating resources directory: r migrating file "time_offset.html.markdown" extracting YAML frontmatter to "$WORK/templates/resources/offset.md.tmpl" @@ -646,6 +655,25 @@ $ terraform import time_static.example 2020-02-12T06:36:13Z ``` The `triggers` argument cannot be imported. +-- website/docs/list-resources/example.html.markdown -- +--- +layout: "time" +page_title: "Time: time_example" +description: |- + Just a fake example. +--- + +Just a fake example. + +```hcl +list "scaffolding_example" "example" { + provider = scaffolding + + config { + required_attr = "value-1" + } +} +``` -- exp-examples/example_1.tf -- resource "time_static" "ami_update" { triggers = { @@ -804,6 +832,14 @@ action "scaffolding_example" "example2" { required_attr = "value-2" } } +-- exp-examples/list-resources/example/example_1.tfquery.hcl -- +list "scaffolding_example" "example" { + provider = scaffolding + + config { + required_attr = "value-1" + } +} -- exp-examples/ephemeral-resources/ephemeral_static/example_1.tf -- resource "time_static" "example" {} @@ -1202,4 +1238,18 @@ Just a fake example. {{tffile "examples/actions/example/example_1.tf"}} -{{tffile "examples/actions/example/example_2.tf"}} \ No newline at end of file +{{tffile "examples/actions/example/example_2.tf"}} +-- exp-templates/list-resources/example.md.tmpl -- +--- +page_title: "Time: time_example" +description: |- + Just a fake example. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +Just a fake example. + +{{tffile "examples/list-resources/example/example_1.tfquery.hcl"}} diff --git a/cmd/tfplugindocs/testdata/scripts/schema-json/validate/framework_provider_error_file_mismatch.txtar b/cmd/tfplugindocs/testdata/scripts/schema-json/validate/framework_provider_error_file_mismatch.txtar index 6405567a..8aa750ba 100644 --- a/cmd/tfplugindocs/testdata/scripts/schema-json/validate/framework_provider_error_file_mismatch.txtar +++ b/cmd/tfplugindocs/testdata/scripts/schema-json/validate/framework_provider_error_file_mismatch.txtar @@ -15,7 +15,20 @@ stderr 'matching ephemeral resource for documentation file \(example2.md\) not f stderr 'missing documentation file for ephemeral resource: scaffolding_example' stderr 'matching action for documentation file \(example2.md\) not found, file is extraneous or incorrectly named' stderr 'missing documentation file for action: scaffolding_example' +stderr 'matching list resource for documentation file \(example2.md\) not found, file is extraneous or incorrectly named' +stderr 'missing documentation file for list resource: scaffolding_example_list' +-- docs/list-resources/example2.md -- +--- +subcategory: "Example" +page_title: "Example: example_thing" +description: |- + Example description. +--- +# Data Fields + +Name: {{.Name}} +Type: {{.Type}} -- docs/actions/example2.md -- --- subcategory: "Example" @@ -91,6 +104,29 @@ Type: {{.Type}} "description_kind": "markdown" } }, + "list_resource_schemas": { + "scaffolding_example_list": { + "version": 0, + "block": { + "attributes": { + "required_attr": { + "type": "string", + "description": "Example required attribute", + "description_kind": "plain", + "required": true + }, + "optional_attr": { + "type": "string", + "description": "Example optional attribute", + "description_kind": "plain", + "optional": true + } + }, + "description": "Example list resource", + "description_kind": "plain" + } + } + }, "action_schemas": { "scaffolding_example": { "version": 0, diff --git a/cmd/tfplugindocs/testdata/scripts/schema-json/validate/framework_provider_success_legacy_docs.txtar b/cmd/tfplugindocs/testdata/scripts/schema-json/validate/framework_provider_success_legacy_docs.txtar index ff6a2132..87b77926 100644 --- a/cmd/tfplugindocs/testdata/scripts/schema-json/validate/framework_provider_success_legacy_docs.txtar +++ b/cmd/tfplugindocs/testdata/scripts/schema-json/validate/framework_provider_success_legacy_docs.txtar @@ -22,6 +22,8 @@ running file checks on website/docs/functions/example.html.md running invalid directories check on website/docs/guides running file checks on website/docs/guides/example.html.md running file checks on website/docs/index.html.md +running invalid directories check on website/docs/list-resources +running file checks on website/docs/list-resources/example.html.md running invalid directories check on website/docs/r running file checks on website/docs/r/example.html.md running file mismatch check @@ -48,6 +50,18 @@ description: |- --- # Data Fields +Name: {{.Name}} +Type: {{.Type}} +-- website/docs/list-resources/example.html.md -- +--- +subcategory: "Example" +layout: "example" +page_title: "Example: example_thing" +description: |- + Example description. +--- +# Data Fields + Name: {{.Name}} Type: {{.Type}} -- website/docs/r/example.html.md -- @@ -129,6 +143,29 @@ Type: {{.Type}} "description_kind": "markdown" } }, + "list_resource_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "required_attr": { + "type": "string", + "description": "Example required attribute", + "description_kind": "plain", + "required": true + }, + "optional_attr": { + "type": "string", + "description": "Example optional attribute", + "description_kind": "plain", + "optional": true + } + }, + "description": "Example list resource", + "description_kind": "plain" + } + } + }, "action_schemas": { "scaffolding_example": { "version": 0, diff --git a/cmd/tfplugindocs/testdata/scripts/schema-json/validate/framework_provider_success_registry_docs.txtar b/cmd/tfplugindocs/testdata/scripts/schema-json/validate/framework_provider_success_registry_docs.txtar index a470194d..afc8a579 100644 --- a/cmd/tfplugindocs/testdata/scripts/schema-json/validate/framework_provider_success_registry_docs.txtar +++ b/cmd/tfplugindocs/testdata/scripts/schema-json/validate/framework_provider_success_registry_docs.txtar @@ -22,6 +22,8 @@ running file checks on docs/functions/example.md running invalid directories check on docs/guides running file checks on docs/guides/example.md running file checks on docs/index.md +running invalid directories check on docs/list-resources +running file checks on docs/list-resources/example.md running invalid directories check on docs/resources running file checks on docs/resources/example.md running file mismatch check @@ -46,6 +48,17 @@ description: |- --- # Data Fields +Name: {{.Name}} +Type: {{.Type}} +-- docs/list-resources/example.md -- +--- +subcategory: "Example" +page_title: "Example: example_thing" +description: |- + Example description. +--- +# Data Fields + Name: {{.Name}} Type: {{.Type}} -- docs/resources/example.md -- @@ -122,6 +135,29 @@ Type: {{.Type}} "description_kind": "markdown" } }, + "list_resource_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "required_attr": { + "type": "string", + "description": "Example required attribute", + "description_kind": "plain", + "required": true + }, + "optional_attr": { + "type": "string", + "description": "Example optional attribute", + "description_kind": "plain", + "optional": true + } + }, + "description": "Example list resource", + "description_kind": "plain" + } + } + }, "action_schemas": { "scaffolding_example": { "version": 0, diff --git a/internal/check/directory.go b/internal/check/directory.go index 2f92576d..ec841838 100644 --- a/internal/check/directory.go +++ b/internal/check/directory.go @@ -20,6 +20,7 @@ const ( LegacyResourcesDirectory = `r` LegacyFunctionsDirectory = `functions` LegacyActionsDirectory = `actions` + LegacyListResourcesDirectory = "list-resources" RegistryIndexDirectory = `docs` RegistryDataSourcesDirectory = `data-sources` @@ -28,6 +29,7 @@ const ( RegistryResourcesDirectory = `resources` RegistryFunctionsDirectory = `functions` RegistryActionsDirectory = `actions` + RegistryListResourcesDirectory = "list-resources" // Terraform Registry Storage Limits // https://www.terraform.io/docs/registry/providers/docs.html#storage-limits @@ -44,6 +46,7 @@ var ValidLegacyDirectories = []string{ LegacyIndexDirectory + "/" + LegacyResourcesDirectory, LegacyIndexDirectory + "/" + LegacyFunctionsDirectory, LegacyIndexDirectory + "/" + LegacyActionsDirectory, + LegacyIndexDirectory + "/" + LegacyListResourcesDirectory, } var ValidRegistryDirectories = []string{ @@ -54,6 +57,7 @@ var ValidRegistryDirectories = []string{ RegistryIndexDirectory + "/" + RegistryResourcesDirectory, RegistryIndexDirectory + "/" + RegistryFunctionsDirectory, RegistryIndexDirectory + "/" + RegistryActionsDirectory, + RegistryIndexDirectory + "/" + RegistryListResourcesDirectory, } var ValidCdktfLanguages = []string{ @@ -71,6 +75,7 @@ var ValidLegacySubdirectories = []string{ LegacyGuidesDirectory, LegacyResourcesDirectory, LegacyActionsDirectory, + LegacyListResourcesDirectory, } var ValidRegistrySubdirectories = []string{ @@ -80,6 +85,7 @@ var ValidRegistrySubdirectories = []string{ RegistryGuidesDirectory, RegistryResourcesDirectory, RegistryActionsDirectory, + RegistryListResourcesDirectory, } func InvalidDirectoriesCheck(dirPath string) error { diff --git a/internal/check/directory_test.go b/internal/check/directory_test.go index 991ca7ad..df1dc305 100644 --- a/internal/check/directory_test.go +++ b/internal/check/directory_test.go @@ -11,7 +11,7 @@ import ( "github.com/bmatcuk/doublestar/v4" ) -var DocumentationGlobPattern = `{docs/index.*,docs/{,cdktf/}{actions,data-sources,ephemeral-resources,guides,resources,functions}/**/*,website/docs/**/*}` +var DocumentationGlobPattern = `{docs/index.*,docs/{,cdktf/}{actions,data-sources,ephemeral-resources,guides,list-resources,resources,functions}/**/*,website/docs/**/*}` func TestMixedDirectoriesCheck(t *testing.T) { t.Parallel() @@ -52,6 +52,13 @@ func TestMixedDirectoriesCheck(t *testing.T) { }, ExpectError: true, }, + "invalid mixed directories - registry list resource": { + ProviderFS: fstest.MapFS{ + "docs/list-resources/invalid.md": {}, + "website/docs/index.md": {}, + }, + ExpectError: true, + }, "invalid mixed directories - registry resource": { ProviderFS: fstest.MapFS{ "docs/resources/invalid.md": {}, @@ -94,6 +101,13 @@ func TestMixedDirectoriesCheck(t *testing.T) { }, ExpectError: true, }, + "invalid mixed directories - legacy list resource": { + ProviderFS: fstest.MapFS{ + "website/docs/list-resources/invalid.html.markdown": {}, + "docs/resources/thing.md": {}, + }, + ExpectError: true, + }, "invalid mixed directories - legacy resource": { ProviderFS: fstest.MapFS{ "website/docs/r/invalid.html.markdown": {}, diff --git a/internal/check/file_mismatch.go b/internal/check/file_mismatch.go index 9c77d232..8aa3a406 100644 --- a/internal/check/file_mismatch.go +++ b/internal/check/file_mismatch.go @@ -32,6 +32,8 @@ type FileMismatchOptions struct { ActionEntries []os.DirEntry + ListResourceEntries []os.DirEntry + Schema *tfjson.ProviderSchema } @@ -88,6 +90,11 @@ func (check *FileMismatchCheck) Run() error { result = errors.Join(result, err) } + if check.Options.ListResourceEntries != nil { + err := check.ResourceFileMismatchCheck(check.Options.ListResourceEntries, "list resource", check.Options.Schema.ListResourceSchemas) + result = errors.Join(result, err) + } + return result } diff --git a/internal/provider/generate.go b/internal/provider/generate.go index dffa8016..1984bbf5 100644 --- a/internal/provider/generate.go +++ b/internal/provider/generate.go @@ -75,6 +75,14 @@ var ( "actions/%s.html.markdown", "actions/%s.html.md", } + websiteListResourceFile = "list-resources/%s.md.tmpl" + websiteListResourceFallbackFile = "list-resources.md.tmpl" + websiteListResourceFileStaticCandidates = []string{ + "list-resources/%s.md", + "list-resources/%s.markdown", + "list-resources/%s.html.markdown", + "list-resources/%s.html.md", + } websiteProviderFile = "index.md.tmpl" websiteProviderFileStaticCandidates = []string{ "index.markdown", @@ -90,6 +98,7 @@ var ( "functions", "ephemeral-resources", "actions", + "list-resources", } managedWebsiteFiles = []string{ @@ -463,6 +472,42 @@ func (g *generator) generateMissingActionTemplate(actionName string) error { return nil } +func (g *generator) generateMissingListResourceTemplate(resourceName string) error { + templatePath := fmt.Sprintf(websiteListResourceFile, resourceShortName(resourceName, g.providerName)) + templatePath = filepath.Join(g.TempTemplatesDir(), templatePath) + if fileExists(templatePath) { + g.infof("list resource %q template exists, skipping", resourceName) + return nil + } + + fallbackTemplatePath := filepath.Join(g.TempTemplatesDir(), websiteListResourceFallbackFile) + if fileExists(fallbackTemplatePath) { + g.infof("list resource %q fallback template exists, creating template", resourceName) + err := cp(fallbackTemplatePath, templatePath) + if err != nil { + return fmt.Errorf("unable to copy fallback template for %q: %w", resourceName, err) + } + return nil + } + + for _, candidate := range websiteListResourceFileStaticCandidates { + candidatePath := fmt.Sprintf(candidate, resourceShortName(resourceName, g.providerName)) + candidatePath = filepath.Join(g.TempTemplatesDir(), candidatePath) + if fileExists(candidatePath) { + g.infof("list resource %q static file exists, skipping", resourceName) + return nil + } + } + + g.infof("generating new template for %q", resourceName) + err := writeFile(templatePath, string(defaultResourceTemplate)) + if err != nil { + return fmt.Errorf("unable to write template for %q: %w", resourceName, err) + } + + return nil +} + func (g *generator) generateMissingProviderTemplate() error { templatePath := filepath.Join(g.TempTemplatesDir(), websiteProviderFile) if fileExists(templatePath) { @@ -593,6 +638,27 @@ func (g *generator) generateMissingTemplates(providerSchema *tfjson.ProviderSche } } + g.infof("generating missing list resource content") + + listResourceKeys := make([]string, 0, len(providerSchema.ListResourceSchemas)) + for key := range providerSchema.ListResourceSchemas { + listResourceKeys = append(listResourceKeys, key) + } + sort.Strings(listResourceKeys) + + for _, name := range listResourceKeys { + schema := providerSchema.ListResourceSchemas[name] + + if g.ignoreDeprecated && schema.Block.Deprecated { + continue + } + + err := g.generateMissingListResourceTemplate(name) + if err != nil { + return fmt.Errorf("unable to generate template for list resource %q: %w", name, err) + } + } + g.infof("generating missing provider content") err := g.generateMissingProviderTemplate() if err != nil { @@ -654,12 +720,13 @@ func (g *generator) renderStaticWebsite(providerSchema *tfjson.ProviderSchema) e relDir, relFile := filepath.Split(rel) relDir = filepath.ToSlash(relDir) - // skip special top-level generic resource, data source, function, ephemeral resource, and action templates + // skip special top-level generic resource, data source, function, ephemeral resource, action and list resource templates if relDir == "" && (relFile == "resources.md.tmpl" || relFile == "data-sources.md.tmpl" || relFile == "functions.md.tmpl" || relFile == "ephemeral-resources.md.tmpl" || - relFile == "actions.md.tmpl") { + relFile == "actions.md.tmpl" || + relFile == "list-resources.md.tmpl") { return nil } @@ -816,6 +883,31 @@ func (g *generator) renderStaticWebsite(providerSchema *tfjson.ProviderSchema) e return nil } g.warnf("action entitled %q, or %q does not exist", shortName, resName) + case "list-resources/": + resSchema, resName := resourceSchema(providerSchema.ListResourceSchemas, shortName, relFile) + exampleFilePath := filepath.Join(g.ProviderExamplesDir(), "list-resources", resName, "list-resource.tfquery.hcl") + exampleFilesPattern := filepath.Join(g.ProviderExamplesDir(), "list-resources", resName, "list-resource*.tfquery.hcl") + exampleFiles, err := filepath.Glob(exampleFilesPattern) + + if err != nil { + return fmt.Errorf("unable to glob example files with pattern %q: %w", exampleFilesPattern, err) + } + + slices.Sort(exampleFiles) + + if resSchema != nil { + tmpl := resourceTemplate(tmplData) + render, err := tmpl.Render(g.providerDir, resName, g.providerName, g.renderedProviderName, "List Resource", exampleFilePath, exampleFiles, "", "", "", resSchema, nil) + if err != nil { + return fmt.Errorf("unable to render list resource template %q: %w", rel, err) + } + _, err = out.WriteString(render) + if err != nil { + return fmt.Errorf("unable to write rendered string: %w", err) + } + return nil + } + g.warnf("list resource entitled %q, or %q does not exist", shortName, resName) case "": // provider if relFile == "index.md.tmpl" { exampleFilePath := filepath.Join(g.ProviderExamplesDir(), "provider", "provider.tf") diff --git a/internal/provider/migrate.go b/internal/provider/migrate.go index 0aeadf35..51c9c70d 100644 --- a/internal/provider/migrate.go +++ b/internal/provider/migrate.go @@ -146,6 +146,13 @@ func (m *migrator) Migrate() error { return err } return filepath.SkipDir + case "list-resources": + m.infof("migrating list resources directory: %s", d.Name()) + err := filepath.WalkDir(path, m.MigrateTemplate("list-resources")) + if err != nil { + return err + } + return filepath.SkipDir } } else { switch { @@ -306,8 +313,13 @@ func (m *migrator) ExtractCodeExamples(content []byte, newRelDir string, templat lang := string(fencedNode.Info.Text(content)[:]) switch lang { case "hcl", "terraform": + exampleCount++ ext = ".tf" + if strings.Contains(newRelDir, "list-resources") { + //m.infof("### DEBUG ### this is a list resource: %s", newRelDir) + ext = ".tfquery.hcl" + } exampleName = "example_" + strconv.Itoa(exampleCount) + ext examplePath = filepath.Join(m.examplesDir, newRelDir, exampleName) template = fmt.Sprintf("{{tffile \"%s\"}}", examplePath) diff --git a/internal/provider/testdata/schema.json b/internal/provider/testdata/schema.json index 2f1e26c0..01ed3ca7 100644 --- a/internal/provider/testdata/schema.json +++ b/internal/provider/testdata/schema.json @@ -8,6 +8,29 @@ "description_kind": "plain" } }, + "list_resource_schemas": { + "null_list_resource": { + "version": 0, + "block": { + "attributes": { + "required_attr": { + "type": "string", + "description": "Required attribute", + "description_kind": "plain", + "required": true + }, + "optional_attr": { + "type": "string", + "description": "Optional attribute", + "description_kind": "plain", + "optional": true + } + }, + "description": "Example list resource", + "description_kind": "plain" + } + } + }, "action_schemas": { "null_fake_action": { "version": 0, diff --git a/internal/provider/util_test.go b/internal/provider/util_test.go index c0a6e201..7ad2db1e 100644 --- a/internal/provider/util_test.go +++ b/internal/provider/util_test.go @@ -113,6 +113,9 @@ func Test_extractSchemaFromFile(t *testing.T) { if providerSchema.ActionSchemas["null_fake_action"] == nil { t.Fatalf("null_fake_action not found") } + if providerSchema.ListResourceSchemas["null_list_resource"] == nil { + t.Fatalf("null_list_resource not found") + } if providerSchema.ResourceSchemas["null_resource"].Block.Attributes["id"] == nil { t.Fatalf("null_resoruce id attribute not found") } @@ -125,4 +128,7 @@ func Test_extractSchemaFromFile(t *testing.T) { if providerSchema.ActionSchemas["null_fake_action"].Block.Attributes["required_attr"] == nil { t.Fatalf("null_fake_action required_attr attribute not found") } + if providerSchema.ListResourceSchemas["null_list_resource"].Block.Attributes["required_attr"] == nil { + t.Fatalf("null_list_resource required_attr attribute not found") + } } diff --git a/internal/provider/validate.go b/internal/provider/validate.go index 5b2151db..8a758311 100644 --- a/internal/provider/validate.go +++ b/internal/provider/validate.go @@ -26,8 +26,8 @@ const ( FileExtensionMarkdown = `.markdown` FileExtensionMd = `.md` - DocumentationGlobPattern = `{docs/index.*,docs/{,cdktf/}{actions,data-sources,ephemeral-resources,guides,resources,functions}/**/*,website/docs/**/*}` - DocumentationDirGlobPattern = `{docs/{,cdktf/}{actions,data-sources,ephemeral-resources,guides,resources,functions}{,/*},website/docs/**/*}` + DocumentationGlobPattern = `{docs/index.*,docs/{,cdktf/}{actions,data-sources,ephemeral-resources,guides,list-resources,resources,functions}/**/*,website/docs/**/*}` + DocumentationDirGlobPattern = `{docs/{,cdktf/}{actions,data-sources,ephemeral-resources,guides,list-resources,resources,functions}{,/*},website/docs/**/*}` ) var ValidLegacyFileExtensions = []string{ @@ -318,6 +318,10 @@ func (v *validator) validateStaticDocs() error { actionFiles, _ := fs.ReadDir(v.providerFS, dir+"/actions") mismatchOpt.ActionEntries = actionFiles } + if dirExists(v.providerFS, dir+"/list-resources") { + listResourceFiles, _ := fs.ReadDir(v.providerFS, dir+"/list-resources") + mismatchOpt.ListResourceEntries = listResourceFiles + } v.logger.infof("running file mismatch check") if err := check.NewFileMismatchCheck(mismatchOpt).Run(); err != nil { @@ -409,6 +413,10 @@ func (v *validator) validateLegacyWebsite() error { actionFiles, _ := fs.ReadDir(v.providerFS, dir+"/actions") mismatchOpt.ActionEntries = actionFiles } + if dirExists(v.providerFS, dir+"/list-resources") { + listResourceFiles, _ := fs.ReadDir(v.providerFS, dir+"/list-resources") + mismatchOpt.ListResourceEntries = listResourceFiles + } v.logger.infof("running file mismatch check") if err := check.NewFileMismatchCheck(mismatchOpt).Run(); err != nil { diff --git a/internal/provider/validate_test.go b/internal/provider/validate_test.go index 6b718cf7..14886ee2 100644 --- a/internal/provider/validate_test.go +++ b/internal/provider/validate_test.go @@ -94,6 +94,9 @@ func TestValidateStaticDocs_DirectoryChecks(t *testing.T) { "docs/guides/thing.md": { Data: encodeYAML(t, &ValidRegistryGuideFrontMatter), }, + "docs/list-resources/thing.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, "docs/nonregistrydocs/valid.md": { Data: []byte("non-registry documentation"), }, @@ -122,6 +125,9 @@ func TestValidateStaticDocs_DirectoryChecks(t *testing.T) { "docs/cdktf/typescirpt/guides/thing.md": { Data: encodeYAML(t, &ValidRegistryGuideFrontMatter), }, + "docs/cdktf/typescript/list-resources/thing.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, "docs/cdktf/typescript/nonregistrydocs/valid.md": { Data: []byte("non-registry documentation"), }, @@ -168,6 +174,9 @@ func TestValidateStaticDocs_DirectoryChecks(t *testing.T) { "docs/guides/invalid/thing.md": { Data: encodeYAML(t, &ValidRegistryGuideFrontMatter), }, + "docs/list-resources/invalid/thing.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, "docs/nonregistrydocs/valid.md": { Data: []byte("non-registry documentation"), }, @@ -189,6 +198,7 @@ func TestValidateStaticDocs_DirectoryChecks(t *testing.T) { "\ninvalid Terraform Provider documentation directory found: " + filepath.Join("docs", "ephemeral-resources", "invalid") + "\ninvalid Terraform Provider documentation directory found: " + filepath.Join("docs", "functions", "invalid") + "\ninvalid Terraform Provider documentation directory found: " + filepath.Join("docs", "guides", "invalid") + + "\ninvalid Terraform Provider documentation directory found: " + filepath.Join("docs", "list-resources", "invalid") + "\ninvalid Terraform Provider documentation directory found: " + filepath.Join("docs", "resources", "invalid"), }, } @@ -318,6 +328,38 @@ func TestValidateStaticDocs_FileChecks(t *testing.T) { filepath.Join("docs", "actions", "with_layout.md") + ": error checking file frontmatter: YAML frontmatter should not contain layout\n" + filepath.Join("docs", "actions", "with_sidebar_current.md") + ": error checking file frontmatter: YAML frontmatter should not contain sidebar_current", }, + "invalid list resource files": { + ProviderFS: fstest.MapFS{ + "docs/list-resources/invalid_extension.txt": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/list-resources/invalid_frontmatter.md": &InvalidYAMLFrontMatter, + "docs/list-resources/with_layout.md": { + Data: encodeYAML(t, + &FrontMatterData{ + Layout: &exampleLayout, + Subcategory: &exampleSubcategory, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + "docs/list-resources/with_sidebar_current.md": { + Data: encodeYAML(t, + &FrontMatterData{ + SidebarCurrent: &exampleSidebarCurrent, + Subcategory: &exampleSubcategory, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + }, + ExpectedError: filepath.Join("docs", "list-resources", "invalid_extension.txt") + ": error checking file extension: file does not end with a valid extension, valid extensions: [.md]\n" + + filepath.Join("docs", "list-resources", "invalid_frontmatter.md") + ": error checking file frontmatter: error parsing YAML frontmatter: yaml: line 4: could not find expected ':'\n" + + filepath.Join("docs", "list-resources", "with_layout.md") + ": error checking file frontmatter: YAML frontmatter should not contain layout\n" + + filepath.Join("docs", "list-resources", "with_sidebar_current.md") + ": error checking file frontmatter: YAML frontmatter should not contain sidebar_current", + }, "invalid resource files": { ProviderFS: fstest.MapFS{ "docs/resources/invalid_extension.txt": { @@ -490,6 +532,9 @@ func TestValidateStaticDocs_FileMismatchCheck(t *testing.T) { EphemeralResourceSchemas: map[string]*tfjson.Schema{ "test_ephemeral_id": {}, }, + ListResourceSchemas: map[string]*tfjson.Schema{ + "test_list": {}, + }, ResourceSchemas: map[string]*tfjson.Schema{ "test_id": {}, }, @@ -507,6 +552,9 @@ func TestValidateStaticDocs_FileMismatchCheck(t *testing.T) { "docs/ephemeral-resources/ephemeral_id.md": { Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), }, + "docs/list-resources/list.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, "docs/functions/parse_id.md": { Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), }, @@ -529,6 +577,10 @@ func TestValidateStaticDocs_FileMismatchCheck(t *testing.T) { "test_ephemeral_id": {}, "test_ephemeral_id2": {}, }, + ListResourceSchemas: map[string]*tfjson.Schema{ + "test_list": {}, + "test_list2": {}, + }, ResourceSchemas: map[string]*tfjson.Schema{ "test_id": {}, "test_id2": {}, @@ -548,6 +600,9 @@ func TestValidateStaticDocs_FileMismatchCheck(t *testing.T) { "docs/ephemeral-resources/ephemeral_id.md": { Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), }, + "docs/list-resources/list.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, "docs/functions/parse_id.md": { Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), }, @@ -559,7 +614,8 @@ func TestValidateStaticDocs_FileMismatchCheck(t *testing.T) { "missing documentation file for datasource: test_pet2\n" + "missing documentation file for function: parse_id2\n" + "missing documentation file for ephemeral resource: test_ephemeral_id2\n" + - "missing documentation file for action: test_action2", + "missing documentation file for action: test_action2\n" + + "missing documentation file for list resource: test_list2", }, "invalid - extra files": { ProviderSchema: &tfjson.ProviderSchema{ @@ -572,6 +628,9 @@ func TestValidateStaticDocs_FileMismatchCheck(t *testing.T) { EphemeralResourceSchemas: map[string]*tfjson.Schema{ "test_ephemeral_id": {}, }, + ListResourceSchemas: map[string]*tfjson.Schema{ + "test_list": {}, + }, ResourceSchemas: map[string]*tfjson.Schema{ "test_id": {}, }, @@ -598,6 +657,12 @@ func TestValidateStaticDocs_FileMismatchCheck(t *testing.T) { "docs/ephemeral-resources/ephemeral_id2.md": { Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), }, + "docs/list-resources/list.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/list-resources/list2.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, "docs/functions/parse_id.md": { Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), }, @@ -615,7 +680,8 @@ func TestValidateStaticDocs_FileMismatchCheck(t *testing.T) { "matching datasource for documentation file (pet2.md) not found, file is extraneous or incorrectly named\n" + "matching function for documentation file (parse_id2.md) not found, file is extraneous or incorrectly named\n" + "matching ephemeral resource for documentation file (ephemeral_id2.md) not found, file is extraneous or incorrectly named\n" + - "matching action for documentation file (action2.md) not found, file is extraneous or incorrectly named", + "matching action for documentation file (action2.md) not found, file is extraneous or incorrectly named\n" + + "matching list resource for documentation file (list2.md) not found, file is extraneous or incorrectly named", }, } @@ -660,6 +726,9 @@ func TestValidateLegacyWebsite_DirectoryChecks(t *testing.T) { "website/docs/ephemeral-resources/thing.html.markdown": { Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), }, + "website/docs/list-resources/thing.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, "website/docs/functions/thing.html.markdown": { Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), }, @@ -685,6 +754,9 @@ func TestValidateLegacyWebsite_DirectoryChecks(t *testing.T) { "website/docs/cdktf/typescript/ephemeral-resources/thing.html.markdown": { Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), }, + "website/docs/cdktf/typescript/list-resources/thing.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, "website/docs/cdktf/typescript/guides/thing.html.markdown": { Data: encodeYAML(t, &ValidLegacyGuideFrontMatter), }, @@ -719,6 +791,9 @@ func TestValidateLegacyWebsite_DirectoryChecks(t *testing.T) { "website/docs/ephemeral-resources/invalid/thing.html.markdown": { Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), }, + "website/docs/list-resources/invalid/thing.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, "website/docs/functions/invalid/thing.html.markdown": { Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), }, @@ -737,6 +812,7 @@ func TestValidateLegacyWebsite_DirectoryChecks(t *testing.T) { "\ninvalid Terraform Provider documentation directory found: " + filepath.Join("website", "docs", "ephemeral-resources", "invalid") + "\ninvalid Terraform Provider documentation directory found: " + filepath.Join("website", "docs", "functions", "invalid") + "\ninvalid Terraform Provider documentation directory found: " + filepath.Join("website", "docs", "guides", "invalid") + + "\ninvalid Terraform Provider documentation directory found: " + filepath.Join("website", "docs", "list-resources", "invalid") + "\ninvalid Terraform Provider documentation directory found: " + filepath.Join("website", "docs", "r", "invalid"), }, } @@ -834,6 +910,38 @@ func TestValidateLegacyWebsite_FileChecks(t *testing.T) { filepath.Join("website", "docs", "ephemeral-resources", "with_sidebar_current.html.markdown") + ": error checking file frontmatter: YAML frontmatter should not contain sidebar_current\n" + filepath.Join("website", "docs", "ephemeral-resources", "without_layout.html.markdown") + ": error checking file frontmatter: YAML frontmatter missing required layout", }, + "invalid list resource files": { + ProviderFS: fstest.MapFS{ + "website/docs/list-resources/invalid_extension.txt": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "website/docs/list-resources/invalid_frontmatter.html.markdown": &InvalidYAMLFrontMatter, + "website/docs/list-resources/without_layout.html.markdown": { + Data: encodeYAML(t, + &FrontMatterData{ + Subcategory: &exampleSubcategory, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + "website/docs/list-resources/with_sidebar_current.html.markdown": { + Data: encodeYAML(t, + &FrontMatterData{ + SidebarCurrent: &exampleSidebarCurrent, + Subcategory: &exampleSubcategory, + Layout: &exampleLayout, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + }, + ExpectedError: filepath.Join("website", "docs", "list-resources", "invalid_extension.txt") + ": error checking file extension: file does not end with a valid extension, valid extensions: [.html.markdown .html.md .markdown .md]\n" + + filepath.Join("website", "docs", "list-resources", "invalid_frontmatter.html.markdown") + ": error checking file frontmatter: error parsing YAML frontmatter: yaml: line 4: could not find expected ':'\n" + + filepath.Join("website", "docs", "list-resources", "with_sidebar_current.html.markdown") + ": error checking file frontmatter: YAML frontmatter should not contain sidebar_current\n" + + filepath.Join("website", "docs", "list-resources", "without_layout.html.markdown") + ": error checking file frontmatter: YAML frontmatter missing required layout", + }, "invalid action files": { ProviderFS: fstest.MapFS{ "website/docs/actions/invalid_extension.txt": { @@ -1046,6 +1154,9 @@ func TestValidateLegacyWebsite_FileMismatchCheck(t *testing.T) { EphemeralResourceSchemas: map[string]*tfjson.Schema{ "test_ephemeral_id": {}, }, + ListResourceSchemas: map[string]*tfjson.Schema{ + "test_list": {}, + }, ResourceSchemas: map[string]*tfjson.Schema{ "test_id": {}, }, @@ -1063,6 +1174,9 @@ func TestValidateLegacyWebsite_FileMismatchCheck(t *testing.T) { "website/docs/ephemeral-resources/ephemeral_id.html.markdown": { Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), }, + "website/docs/list-resources/list.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, "website/docs/functions/parse_id.html.markdown": { Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), }, @@ -1085,6 +1199,10 @@ func TestValidateLegacyWebsite_FileMismatchCheck(t *testing.T) { "test_ephemeral_id": {}, "test_ephemeral_id2": {}, }, + ListResourceSchemas: map[string]*tfjson.Schema{ + "test_list": {}, + "test_list2": {}, + }, ResourceSchemas: map[string]*tfjson.Schema{ "test_id": {}, "test_id2": {}, @@ -1104,6 +1222,9 @@ func TestValidateLegacyWebsite_FileMismatchCheck(t *testing.T) { "website/docs/ephemeral-resources/ephemeral_id.html.markdown": { Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), }, + "website/docs/list-resources/list.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, "website/docs/functions/parse_id.html.markdown": { Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), }, @@ -1115,7 +1236,8 @@ func TestValidateLegacyWebsite_FileMismatchCheck(t *testing.T) { "missing documentation file for datasource: test_pet2\n" + "missing documentation file for function: parse_id2\n" + "missing documentation file for ephemeral resource: test_ephemeral_id2\n" + - "missing documentation file for action: test_action2", + "missing documentation file for action: test_action2\n" + + "missing documentation file for list resource: test_list2", }, "invalid - extra files": { ProviderSchema: &tfjson.ProviderSchema{ @@ -1128,6 +1250,9 @@ func TestValidateLegacyWebsite_FileMismatchCheck(t *testing.T) { EphemeralResourceSchemas: map[string]*tfjson.Schema{ "test_ephemeral_id": {}, }, + ListResourceSchemas: map[string]*tfjson.Schema{ + "test_list": {}, + }, ResourceSchemas: map[string]*tfjson.Schema{ "test_id": {}, }, @@ -1160,6 +1285,12 @@ func TestValidateLegacyWebsite_FileMismatchCheck(t *testing.T) { "website/docs/functions/parse_id2.html.markdown": { Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), }, + "website/docs/list-resources/list.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/list-resources/list2.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, "website/docs/r/id.html.markdown": { Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), }, @@ -1171,7 +1302,8 @@ func TestValidateLegacyWebsite_FileMismatchCheck(t *testing.T) { "matching datasource for documentation file (pet2.html.markdown) not found, file is extraneous or incorrectly named\n" + "matching function for documentation file (parse_id2.html.markdown) not found, file is extraneous or incorrectly named\n" + "matching ephemeral resource for documentation file (ephemeral_id2.html.markdown) not found, file is extraneous or incorrectly named\n" + - "matching action for documentation file (action2.html.markdown) not found, file is extraneous or incorrectly named", + "matching action for documentation file (action2.html.markdown) not found, file is extraneous or incorrectly named\n" + + "matching list resource for documentation file (list2.html.markdown) not found, file is extraneous or incorrectly named", }, }