diff --git a/.changes/0.20.0.md b/.changes/0.20.0.md new file mode 100644 index 00000000..42e2d498 --- /dev/null +++ b/.changes/0.20.0.md @@ -0,0 +1,18 @@ +## 0.20.0 (November 06, 2024) + +NOTES: + +* all: This Go module has been updated to Go 1.22 per the [Go support policy](https://go.dev/doc/devel/release#policy). It is recommended to review the [Go 1.22 release notes](https://go.dev/doc/go1.22) before upgrading. Any consumers building on earlier Go versions may experience errors. ([#400](https://github.com/hashicorp/terraform-plugin-docs/issues/400)) + +FEATURES: + +* generate: Add support for ephemeral resources ([#415](https://github.com/hashicorp/terraform-plugin-docs/issues/415)) +* migrate: Add support for ephemeral resources ([#415](https://github.com/hashicorp/terraform-plugin-docs/issues/415)) +* validate: Add support for ephemeral resources ([#415](https://github.com/hashicorp/terraform-plugin-docs/issues/415)) + +BUG FIXES: + +* validate: File extension check now runs on `index.*` files instead of just `index.md` files. ([#413](https://github.com/hashicorp/terraform-plugin-docs/issues/413)) +* validate: File extension check now specifies the correct valid extensions in the error message. ([#413](https://github.com/hashicorp/terraform-plugin-docs/issues/413)) +* validate: Front matter check now runs with the correct options on legacy index files. ([#413](https://github.com/hashicorp/terraform-plugin-docs/issues/413)) + diff --git a/.changie.yaml b/.changie.yaml index 1216b591..37089da1 100644 --- a/.changie.yaml +++ b/.changie.yaml @@ -1,3 +1,5 @@ +# DO NOT EDIT - This GitHub Workflow is managed by automation +# https://github.com/hashicorp/terraform-devex-repos changesDir: .changes unreleasedDir: unreleased changelogPath: CHANGELOG.md diff --git a/.github/workflows/add-content-to-project.yml b/.github/workflows/add-content-to-project.yml deleted file mode 100644 index eeb91e1e..00000000 --- a/.github/workflows/add-content-to-project.yml +++ /dev/null @@ -1,40 +0,0 @@ -# Based on https://github.com/leonsteinhaeuser/project-beta-automations - -name: "Add Issues/PRs to TF Provider DevEx team board" - -on: - issues: - types: [opened, reopened] - pull_request_target: - # NOTE: The way content is added to project board is equivalent to an "upsert". - # Calling it multiple times will be idempotent. - # - # See https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ - # to see the reasoning behind using `pull_request_target` instead of `pull_request` - types: [opened, reopened, ready_for_review] - -jobs: - add-content-to-project: - name: "Add Content to project" - runs-on: ubuntu-latest - steps: - - name: "Set Issue to 'Priority = Triage Next'" - uses: leonsteinhaeuser/project-beta-automations@939000fb1900c9fc4f7b5058a09d9f833ebc6859 # v2.2.1 - if: github.event_name == 'issues' - with: - gh_token: ${{ secrets.TF_DEVEX_PROJECT_GITHUB_TOKEN }} - organization: "hashicorp" - project_id: 99 #< https://github.com/orgs/hashicorp/projects/99 - resource_node_id: ${{ github.event.issue.node_id }} - operation_mode: custom_field - custom_field_values: '[{\"name\":\"Priority\",\"type\":\"single_select\",\"value\":\"Triage Next\"}]' - - name: "Set Pull Request to 'Priority = Triage Next'" - uses: leonsteinhaeuser/project-beta-automations@939000fb1900c9fc4f7b5058a09d9f833ebc6859 # v2.2.1 - if: github.event_name == 'pull_request_target' - with: - gh_token: ${{ secrets.TF_DEVEX_PROJECT_GITHUB_TOKEN }} - organization: "hashicorp" - project_id: 99 #< https://github.com/orgs/hashicorp/projects/99 - resource_node_id: ${{ github.event.pull_request.node_id }} - operation_mode: custom_field - custom_field_values: '[{\"name\":\"Priority\",\"type\":\"single_select\",\"value\":\"Triage Next\"}]' diff --git a/.github/workflows/ci-changie.yml b/.github/workflows/ci-changie.yml index e1c0f40a..3031aad8 100644 --- a/.github/workflows/ci-changie.yml +++ b/.github/workflows/ci-changie.yml @@ -1,3 +1,6 @@ +# DO NOT EDIT - This GitHub Workflow is managed by automation +# https://github.com/hashicorp/terraform-devex-repos + # Continuous integration handling for changie name: ci-changie @@ -15,9 +18,10 @@ jobs: check: runs-on: ubuntu-latest steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + # Ensure terraform-devex-repos is updated on version changes. + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + # Ensure terraform-devex-repos is updated on version changes. - uses: miniscruff/changie-action@6dcc2533cac0495148ed4046c438487e4dceaa23 # v2.0.0 with: version: latest args: batch patch --dry-run - diff --git a/.github/workflows/compliance.yml b/.github/workflows/compliance.yml index 8db9cfd1..6a82766b 100644 --- a/.github/workflows/compliance.yml +++ b/.github/workflows/compliance.yml @@ -11,7 +11,7 @@ jobs: copywrite: runs-on: ubuntu-latest steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: hashicorp/setup-copywrite@32638da2d4e81d56a0764aa1547882fc4d209636 # v1.1.3 - run: copywrite headers --plan - run: copywrite license --plan diff --git a/.github/workflows/jira-sync.yml b/.github/workflows/jira-sync.yml deleted file mode 100644 index 737d56a5..00000000 --- a/.github/workflows/jira-sync.yml +++ /dev/null @@ -1,39 +0,0 @@ -on: - issues: - types: [closed, deleted, reopened] - pull_request_target: - types: [closed, reopened] - -name: Jira Sync - -jobs: - sync: - runs-on: ubuntu-latest - name: Jira sync - steps: - - - name: Login - uses: atlassian/gajira-login@45fd029b9f1d6d8926c6f04175aa80c0e42c9026 # v3.0.1 - if: contains(github.event.pull_request.labels.*.name, 'tf-devex-triage') || contains(github.event.issue.labels.*.name, 'tf-devex-triage') - env: - JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} - JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} - JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} - - name: Search for existing issue - id: search - if: contains(github.event.pull_request.labels.*.name, 'tf-devex-triage') || contains(github.event.issue.labels.*.name, 'tf-devex-triage') - uses: tomhjp/gh-action-jira-search@04700b457f317c3e341ce90da5a3ff4ce058f2fa # v0.2.2 - with: - jql: 'project="TFECO" and "Team (R&D)[Labels]"="TF-DevEx" and description ~ "${{ github.event.issue.html_url || github.event.pull_request.html_url }}" and labels in (Github)' - - name: Close task - if: ( github.event.action == 'closed' || github.event.action == 'deleted' ) && steps.search.outputs.issue - uses: atlassian/gajira-transition@38fc9cd61b03d6a53dd35fcccda172fe04b36de3 # v3.0.1 - with: - issue: ${{ steps.search.outputs.issue }} - transition: "Closed" - - name: Reopen task - if: github.event.action == 'reopened' && steps.search.outputs.issue - uses: atlassian/gajira-transition@38fc9cd61b03d6a53dd35fcccda172fe04b36de3 # v3.0.1 - with: - issue: ${{ steps.search.outputs.issue }} - transition: "To Do" diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml index 922282c7..8b519cf9 100644 --- a/.github/workflows/lock.yml +++ b/.github/workflows/lock.yml @@ -15,13 +15,7 @@ jobs: - uses: dessant/lock-threads@1bf7ec25051fe7c00bdd17e6a7cf3d7bfb7dc771 # v5.0.1 with: github-token: ${{ github.token }} - issue-comment: > - I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues. - - If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further. issue-inactive-days: '30' - pr-comment: > - I'm going to lock this pull request because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active contributions. - - If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further. + issue-lock-reason: resolved pr-inactive-days: '30' + pr-lock-reason: resolved diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 444a2523..7520b64c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 # Avoid persisting GITHUB_TOKEN credentials as they take priority over our service account PAT for `git push` operations @@ -54,7 +54,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 # Default input is the SHA that initially triggered the workflow. As we created a new commit in the previous job, @@ -79,12 +79,12 @@ jobs: contents: write # Needed for goreleaser to create GitHub release issues: write # Needed for goreleaser to close associated milestone steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ inputs.versionNumber }} fetch-depth: 0 - - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 + - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version-file: 'go.mod' @@ -93,7 +93,7 @@ jobs: cd .changes sed -e "1{/# /d;}" -e "2{/^$/d;}" ${{ needs.changelog-version.outputs.version }}.md > /tmp/release-notes.txt - - uses: goreleaser/goreleaser-action@5742e2a039330cbb23ebf35f046f814d4c6ff811 # v5.1.0 + - uses: goreleaser/goreleaser-action@286f3b13b1b49da4ac219696163fb8c1c93e1200 # v6.0.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: diff --git a/.github/workflows/send-to-jira.yml b/.github/workflows/send-to-jira.yml deleted file mode 100644 index 6cf5ae5a..00000000 --- a/.github/workflows/send-to-jira.yml +++ /dev/null @@ -1,36 +0,0 @@ -on: - issues: - types: [labeled] - -name: Jira Sync - -jobs: - sync: - runs-on: ubuntu-latest - name: Jira sync - steps: - - - name: Login - uses: atlassian/gajira-login@45fd029b9f1d6d8926c6f04175aa80c0e42c9026 # v3.0.1 - if: github.event.label.name == 'tf-devex-triage' - env: - JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} - JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} - JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} - - name: Search for existing issue - id: search - if: github.event.label.name == 'tf-devex-triage' - uses: tomhjp/gh-action-jira-search@04700b457f317c3e341ce90da5a3ff4ce058f2fa # v0.2.2 - with: - jql: 'project="TFECO" and "Team (R&D)[Labels]"="TF-DevEx" and description ~ "${{ github.event.issue.html_url || github.event.pull_request.html_url }}" and labels in (Github)' - - - name: Create task in DevEx board - if: github.event.label.name == 'tf-devex-triage' && !steps.search.outputs.issue - uses: atlassian/gajira-create@59e177c4f6451399df5b4911c2211104f171e669 # v3.0.1 - with: - project: TFECO - issuetype: "Task" - summary: "[GH] ${{ github.event.issue.title || github.event.pull_request.title }}" - description: "${{ github.event.issue.html_url || github.event.pull_request.html_url }} \n Synced by Github Actions, tagged by ${{ github.actor }}" - # customfield_10091 is Team (R&D) - fields: '{"customfield_10091": ["TF-DevEx"], "labels": ["Github"]}' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a7f277d8..f275ccac 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,13 +21,13 @@ jobs: git config --global core.eol lf - name: Check out code - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Setup Go - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version-file: 'go.mod' - name: Run linters - uses: golangci/golangci-lint-action@a4f60bb28d35aeee14e6880718e0c85ff1882e64 # v6.0.1 + uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1 with: version: latest args: --timeout=3m diff --git a/.golangci.yml b/.golangci.yml index a62a6274..82a43ddd 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -11,6 +11,7 @@ linters: - forcetypeassert - gofmt - gosimple + - govet - ineffassign - makezero - misspell @@ -22,7 +23,6 @@ linters: - unconvert - unparam - unused - - vet run: # Prevent false positive timeouts in CI diff --git a/.goreleaser.yml b/.goreleaser.yml index b6514e75..3ead1e46 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,3 +1,4 @@ +version: 2 project_name: tfplugindocs builds: - main: ./cmd/tfplugindocs diff --git a/CHANGELOG.md b/CHANGELOG.md index 28188581..52f01b97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ +## 0.20.0 (November 06, 2024) + +NOTES: + +* all: This Go module has been updated to Go 1.22 per the [Go support policy](https://go.dev/doc/devel/release#policy). It is recommended to review the [Go 1.22 release notes](https://go.dev/doc/go1.22) before upgrading. Any consumers building on earlier Go versions may experience errors. ([#400](https://github.com/hashicorp/terraform-plugin-docs/issues/400)) + +FEATURES: + +* generate: Add support for ephemeral resources ([#415](https://github.com/hashicorp/terraform-plugin-docs/issues/415)) +* migrate: Add support for ephemeral resources ([#415](https://github.com/hashicorp/terraform-plugin-docs/issues/415)) +* validate: Add support for ephemeral resources ([#415](https://github.com/hashicorp/terraform-plugin-docs/issues/415)) + +BUG FIXES: + +* validate: File extension check now runs on `index.*` files instead of just `index.md` files. ([#413](https://github.com/hashicorp/terraform-plugin-docs/issues/413)) +* validate: File extension check now specifies the correct valid extensions in the error message. ([#413](https://github.com/hashicorp/terraform-plugin-docs/issues/413)) +* validate: Front matter check now runs with the correct options on legacy index files. ([#413](https://github.com/hashicorp/terraform-plugin-docs/issues/413)) + ## 0.19.4 (June 04, 2024) NOTES: diff --git a/README.md b/README.md index 6e30fd9e..dc1edecc 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,7 @@ When you run `tfplugindocs`, by default from the root directory of a provider co * Generate resource template files, if missing * Generate data source template files, if missing * Generate function template files, if missing (Requires Terraform v1.8.0+) +* Generate ephemeral resource template files, if missing (Requires Terraform v1.10.0+) * Copy all non-template files to the output website directory * Process all the remaining templates to generate files for the output website directory @@ -193,16 +194,18 @@ 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/data-sources.md[.tmpl]` | Generic data source page (or template) | -| `templates/data-sources/.md[.tmpl]` | Data source 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/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) | Note: the `.tmpl` extension is necessary, for the file to be correctly handled as a template. @@ -211,14 +214,15 @@ For examples: > **NOTE:** In the following conventional paths for examples, `` and `` include the provider prefix as well, but the provider prefix is **NOT** included in``. > For example, the data source [`caller_identity`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) in the `aws` provider would have an "example" conventional path of: `examples/data-sources/aws_caller_identity/data-source.tf` -| Path | Description | -|-----------------------------------------------------------|---------------------------------| -| `examples/` | Root of examples | -| `examples/provider/provider.tf` | Provider example config | -| `examples/data-sources//data-source.tf` | Data source example config | -| `examples/functions//function.tf` | Function example config | -| `examples/resources//resource.tf` | Resource example config | -| `examples/resources//import.sh` | Resource example import command | +| Path | Description | +|---------------------------------------------------------------------------|-----------------------------------| +| `examples/` | Root of examples | +| `examples/provider/provider.tf` | Provider example config | +| `examples/data-sources//data-source.tf` | Data source example config | +| `examples/ephemeral-resources//ephemeral-resource.tf` | Ephemeral resource example config | +| `examples/functions//function.tf` | Function example config | +| `examples/resources//resource.tf` | Resource example config | +| `examples/resources//import.sh` | Resource example import command | #### Migration @@ -229,25 +233,27 @@ The `migrate` subcommand assumes the following conventional paths for the render Legacy website directory structure: -| Path | Description | -|-------------------------------------------------------|-----------------------------| -| `website/` | Root of website docs | -| `website/docs/guides` | Root of guides subdirectory | -| `website/docs/index.html.markdown` | Docs index page | -| `website/docs/d/.html.markdown` | Data source page | -| `website/docs/functons/.html.markdown` | Functions page | -| `website/docs/r/.html.markdown` | Resource page | +| Path | Description | +|----------------------------------------------------------------------------|-----------------------------| +| `website/` | Root of website docs | +| `website/docs/guides` | Root of guides subdirectory | +| `website/docs/index.html.markdown` | Docs index page | +| `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/r/.html.markdown` | Resource page | Docs website directory structure: -| Path | Description | -|------------------------------------------------------|-----------------------------| -| `docs/` | Root of website docs | -| `docs/guides` | Root of guides subdirectory | -| `docs/index.html.markdown` | Docs index page | -| `docs/data-sources/.html.markdown` | Data source page | -| `docs/functions/.html.markdown` | Function page | -| `docs/resources/.html.markdown` | Resource page | +| Path | Description | +|--------------------------------------------------------------------|-----------------------------| +| `docs/` | Root of website docs | +| `docs/guides` | Root of guides subdirectory | +| `docs/index.html.markdown` | Docs index page | +| `docs/data-sources/.html.markdown` | Data source page | +| `docs/ephemeral-resources/.html.markdown` | Ephemeral resource page | +| `docs/functions/.html.markdown` | Function 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/`, and `docs/resources/` subdirectories will be converted to `tfplugindocs` templates. @@ -275,7 +281,7 @@ 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 Provider Schema definition | -##### Resources / Data Source Fields +##### Managed Resource / Ephemeral Resource / Data Source Fields | Field | Type | 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 3f6010cd..cf5f7b6a 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 @@ -26,6 +26,7 @@ resource "scaffolding_example" fallback template exists, creating template generating missing data source content data-source "scaffolding_example" fallback template exists, creating template generating missing function content +generating missing ephemeral 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 e4b3d497..a7354950 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 @@ -26,6 +26,7 @@ resource "scaffolding_example" template exists, skipping generating missing data source content data-source "scaffolding_example" template exists, skipping generating missing function content +generating missing ephemeral 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 01e3829e..bb6e91cc 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 @@ -24,6 +24,7 @@ generating new template for "scaffolding_example" generating missing data source content generating new template for data-source "scaffolding_example" generating missing function content +generating missing ephemeral 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 0c8fa4eb..263e85c4 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 @@ -23,6 +23,7 @@ resource "null_resource" fallback template exists, creating template generating missing data source content data-source "null_data_source" fallback template exists, creating template generating missing function content +generating missing ephemeral 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 040d727b..b58019ee 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 @@ -19,6 +19,7 @@ generating new template for "scaffolding_example" generating missing data source content generating missing function content generating new template for function "scaffolding" +generating missing ephemeral 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 187ea8b9..3984d4e7 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 @@ -10,6 +10,7 @@ cmpenv docs/index.md expected-index.md cmpenv docs/data-sources/example.md expected-datasource.md 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 -- expected-output.txt -- @@ -24,12 +25,15 @@ generating missing data source content data-source "scaffolding_example" fallback template exists, creating template generating missing function content function "example" fallback template exists, creating template +generating missing ephemeral resource content +ephemeral resource "scaffolding_example" fallback template exists, creating template generating missing provider content provider "terraform-provider-scaffolding" template exists, skipping rendering static website cleaning rendered website dir rendering templated website to static markdown rendering "data-sources/example.md.tmpl" +rendering "ephemeral-resources/example.md.tmpl" rendering "functions/example.md.tmpl" rendering "index.md.tmpl" rendering "resources/example.md.tmpl" @@ -239,6 +243,63 @@ Import is supported using the following syntax: terraform import scaffolding_example.example ``` +tffile: +## Example Usage + +```terraform +resource "scaffolding_example" "example" { + configurable_attribute = "some-value" +} +``` +-- expected-ephemeral-resource.md -- +# Data Fields + +Name: scaffolding_example +Type: Ephemeral Resource +Description: Example ephemeral resource +HasExample: true +ExampleFile: $WORK/examples/ephemeral-resources/scaffolding_example/ephemeral-resource.tf +HasImport: false +ProviderName: terraform-provider-scaffolding +ProviderShortName: scaffolding +RenderedProviderName: terraform-provider-scaffolding +SchemaMarkdown: +## Schema + +### Optional + +- `configurable_attribute` (String) Example configurable attribute +- `defaulted` (String) Example configurable attribute with default value + +### Read-Only + +- `id` (String) Example identifier + + + +# Functions + +lower: ephemeral resource +plainmarkdown: Ephemeral Resource +prefixlines: Prefix: Ephemeral Resource +split: [scaffolding example] +title: Ephemeral Resource +trimspace: Ephemeral Resource +upper: EPHEMERAL RESOURCE + +# Conditionals and File Functions + +printf codefile: + + +printf tffile: +## Example Usage + +{{tffile "$WORK/examples/ephemeral-resources/scaffolding_example/ephemeral-resource.tf"}} + +codefile: + + tffile: ## Example Usage @@ -438,6 +499,63 @@ tffile: {{ if .HasExample -}} ## Example Usage +{{tffile .ExampleFile }} +{{- end }} +-- templates/ephemeral-resources.md.tmpl -- +# Data Fields + +Name: {{.Name}} +Type: {{.Type}} +Description: {{.Description}} +HasExample: {{.HasExample}} +ExampleFile: {{.ExampleFile}} +HasImport: {{.HasImport}} +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 codefile: +{{ if .HasImport -}} +## Import + +Import is supported using the following syntax: + +{{ printf "{{codefile \"shell\" %q}}" .ImportFile }} +{{- end }} + +printf tffile: +{{ if .HasExample -}} +## Example Usage + +{{ printf "{{tffile %q}}" .ExampleFile }} +{{- end }} + +codefile: +{{ if .HasImport -}} +## Import + +Import is supported using the following syntax: + +{{codefile "shell" .ImportFile }} +{{- end }} + +tffile: +{{ if .HasExample -}} +## Example Usage + {{tffile .ExampleFile }} {{- end }} -- examples/README.md -- @@ -468,98 +586,132 @@ resource "scaffolding_example" "example" { } -- examples/resources/scaffolding_example/import.sh -- terraform import scaffolding_example.example +-- examples/ephemeral-resources/scaffolding_example/ephemeral-resource.tf -- +resource "scaffolding_example" "example" { + configurable_attribute = "some-value" +} -- schema.json -- { - "format_version": "1.0", - "provider_schemas": { - "registry.terraform.io/hashicorp/scaffolding": { - "provider": { - "version": 0, - "block": { - "attributes": { - "endpoint": { - "type": "string", - "description": "Example provider attribute", - "description_kind": "markdown", - "optional": true - } - }, - "description": "Example provider", - "description_kind": "markdown" - } - }, - "resource_schemas": { - "scaffolding_example": { - "version": 0, - "block": { - "attributes": { - "configurable_attribute": { - "type": "string", - "description": "Example configurable attribute", - "description_kind": "markdown", - "optional": true - }, - "defaulted": { - "type": "string", - "description": "Example configurable attribute with default value", - "description_kind": "markdown", - "optional": true, - "computed": true - }, - "id": { - "type": "string", - "description": "Example identifier", - "description_kind": "markdown", - "computed": true - } + "format_version": "1.0", + "provider_schemas": { + "registry.terraform.io/hashicorp/scaffolding": { + "provider": { + "version": 0, + "block": { + "attributes": { + "endpoint": { + "type": "string", + "description": "Example provider attribute", + "description_kind": "markdown", + "optional": true + } + }, + "description": "Example provider", + "description_kind": "markdown" + } }, - "description": "Example resource", - "description_kind": "markdown" - } - } - }, - "data_source_schemas": { - "scaffolding_example": { - "version": 0, - "block": { - "attributes": { - "configurable_attribute": { - "type": "string", - "description": "Example configurable attribute", - "description_kind": "markdown", - "optional": true - }, - "id": { - "type": "string", - "description": "Example identifier", - "description_kind": "markdown", - "computed": true - } + "resource_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "configurable_attribute": { + "type": "string", + "description": "Example configurable attribute", + "description_kind": "markdown", + "optional": true + }, + "defaulted": { + "type": "string", + "description": "Example configurable attribute with default value", + "description_kind": "markdown", + "optional": true, + "computed": true + }, + "id": { + "type": "string", + "description": "Example identifier", + "description_kind": "markdown", + "computed": true + } + }, + "description": "Example resource", + "description_kind": "markdown" + } + } }, - "description": "Example data source", - "description_kind": "markdown" - } - } - }, - "functions": { - "example": { - "description": "Given a string value, returns the same value.", - "summary": "Echo a string", - "return_type": "string", - "parameters": [ - { - "name": "input", - "description": "Value to echo.", - "type": "string" + "ephemeral_resource_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "configurable_attribute": { + "type": "string", + "description": "Example configurable attribute", + "description_kind": "markdown", + "optional": true + }, + "defaulted": { + "type": "string", + "description": "Example configurable attribute with default value", + "description_kind": "markdown", + "optional": true, + "computed": true + }, + "id": { + "type": "string", + "description": "Example identifier", + "description_kind": "markdown", + "computed": true + } + }, + "description": "Example ephemeral resource", + "description_kind": "markdown" + } + } + }, + "data_source_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "configurable_attribute": { + "type": "string", + "description": "Example configurable attribute", + "description_kind": "markdown", + "optional": true + }, + "id": { + "type": "string", + "description": "Example identifier", + "description_kind": "markdown", + "computed": true + } + }, + "description": "Example data source", + "description_kind": "markdown" + } + } + }, + "functions": { + "example": { + "description": "Given a string value, returns the same value.", + "summary": "Echo a string", + "return_type": "string", + "parameters": [ + { + "name": "input", + "description": "Value to echo.", + "type": "string" + } + ], + "variadic_parameter": { + "name": "variadicInput", + "description": "Variadic input to echo.", + "type": "string" + } + } } - ], - "variadic_parameter": { - "name": "variadicInput", - "description": "Variadic input to echo.", - "type": "string" - } } - } } - } } \ No newline at end of file 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 03973af1..9d175252 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 @@ -22,6 +22,11 @@ cmp templates/functions/example.markdown docs/functions/example.markdown cmp templates/functions/example.html.markdown docs/functions/example.html.markdown cmp templates/functions/example.html.md docs/functions/example.html.md +cmp templates/ephemeral-resources/example.md docs/ephemeral-resources/example.md +cmp templates/ephemeral-resources/example.markdown docs/ephemeral-resources/example.markdown +cmp templates/ephemeral-resources/example.html.markdown docs/ephemeral-resources/example.html.markdown +cmp templates/ephemeral-resources/example.html.md docs/ephemeral-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 @@ -38,6 +43,8 @@ generating missing data source content data-source "scaffolding_example" static file exists, skipping generating missing function content function "example" static file exists, skipping +generating missing ephemeral resource content +ephemeral resource "scaffolding_example" static file exists, skipping generating missing provider content provider "terraform-provider-scaffolding" static file exists, skipping rendering static website @@ -47,6 +54,10 @@ copying non-template file: "d/example.html.markdown" copying non-template file: "d/example.html.md" copying non-template file: "d/example.markdown" copying non-template file: "d/example.md" +copying non-template file: "ephemeral-resources/example.html.markdown" +copying non-template file: "ephemeral-resources/example.html.md" +copying non-template file: "ephemeral-resources/example.markdown" +copying non-template file: "ephemeral-resources/example.md" copying non-template file: "functions/example.html.markdown" copying non-template file: "functions/example.html.md" copying non-template file: "functions/example.markdown" @@ -117,6 +128,26 @@ Type: {{.Type}} -- templates/functions/example.html.md -- # Data Fields +Name: {{.Name}} +Type: {{.Type}} +-- templates/ephemeral-resources/example.md -- +# Data Fields + +Name: {{.Name}} +Type: {{.Type}} +-- templates/ephemeral-resources/example.markdown -- +# Data Fields + +Name: {{.Name}} +Type: {{.Type}} +-- templates/ephemeral-resources/example.html.markdown -- +# Data Fields + +Name: {{.Name}} +Type: {{.Type}} +-- templates/ephemeral-resources/example.html.md -- +# Data Fields + Name: {{.Name}} Type: {{.Type}} -- templates/index.md -- @@ -161,100 +192,134 @@ provider "scaffolding" { resource "scaffolding_example" "example" { configurable_attribute = "some-value" } +-- examples/ephemeral-resources/scaffolding_example/ephemeral-resource.tf -- +resource "scaffolding_example" "example" { + configurable_attribute = "some-value" +} -- examples/resources/scaffolding_example/import.sh -- terraform import scaffolding_example.example -- schema.json -- { - "format_version": "1.0", - "provider_schemas": { - "registry.terraform.io/hashicorp/scaffolding": { - "provider": { - "version": 0, - "block": { - "attributes": { - "endpoint": { - "type": "string", - "description": "Example provider attribute", - "description_kind": "markdown", - "optional": true - } - }, - "description": "Example provider", - "description_kind": "markdown" - } - }, - "resource_schemas": { - "scaffolding_example": { - "version": 0, - "block": { - "attributes": { - "configurable_attribute": { - "type": "string", - "description": "Example configurable attribute", - "description_kind": "markdown", - "optional": true - }, - "defaulted": { - "type": "string", - "description": "Example configurable attribute with default value", - "description_kind": "markdown", - "optional": true, - "computed": true - }, - "id": { - "type": "string", - "description": "Example identifier", - "description_kind": "markdown", - "computed": true - } + "format_version": "1.0", + "provider_schemas": { + "registry.terraform.io/hashicorp/scaffolding": { + "provider": { + "version": 0, + "block": { + "attributes": { + "endpoint": { + "type": "string", + "description": "Example provider attribute", + "description_kind": "markdown", + "optional": true + } + }, + "description": "Example provider", + "description_kind": "markdown" + } }, - "description": "Example resource", - "description_kind": "markdown" - } - } - }, - "data_source_schemas": { - "scaffolding_example": { - "version": 0, - "block": { - "attributes": { - "configurable_attribute": { - "type": "string", - "description": "Example configurable attribute", - "description_kind": "markdown", - "optional": true - }, - "id": { - "type": "string", - "description": "Example identifier", - "description_kind": "markdown", - "computed": true - } + "resource_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "configurable_attribute": { + "type": "string", + "description": "Example configurable attribute", + "description_kind": "markdown", + "optional": true + }, + "defaulted": { + "type": "string", + "description": "Example configurable attribute with default value", + "description_kind": "markdown", + "optional": true, + "computed": true + }, + "id": { + "type": "string", + "description": "Example identifier", + "description_kind": "markdown", + "computed": true + } + }, + "description": "Example resource", + "description_kind": "markdown" + } + } }, - "description": "Example data source", - "description_kind": "markdown" - } - } - }, - "functions": { - "example": { - "description": "Given a string value, returns the same value.", - "summary": "Echo a string", - "return_type": "string", - "parameters": [ - { - "name": "input", - "description": "Value to echo.", - "type": "string" + "ephemeral_resource_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "configurable_attribute": { + "type": "string", + "description": "Example configurable attribute", + "description_kind": "markdown", + "optional": true + }, + "defaulted": { + "type": "string", + "description": "Example configurable attribute with default value", + "description_kind": "markdown", + "optional": true, + "computed": true + }, + "id": { + "type": "string", + "description": "Example identifier", + "description_kind": "markdown", + "computed": true + } + }, + "description": "Example ephemeral resource", + "description_kind": "markdown" + } + } + }, + "data_source_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "configurable_attribute": { + "type": "string", + "description": "Example configurable attribute", + "description_kind": "markdown", + "optional": true + }, + "id": { + "type": "string", + "description": "Example identifier", + "description_kind": "markdown", + "computed": true + } + }, + "description": "Example data source", + "description_kind": "markdown" + } + } + }, + "functions": { + "example": { + "description": "Given a string value, returns the same value.", + "summary": "Echo a string", + "return_type": "string", + "parameters": [ + { + "name": "input", + "description": "Value to echo.", + "type": "string" + } + ], + "variadic_parameter": { + "name": "variadicInput", + "description": "Variadic input to echo.", + "type": "string" + } + } } - ], - "variadic_parameter": { - "name": "variadicInput", - "description": "Variadic input to echo.", - "type": "string" - } } - } } - } } \ No newline at end of file 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 15680887..50d254eb 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 @@ -10,6 +10,7 @@ cmpenv docs/index.md expected-index.md cmpenv docs/data-sources/example.md expected-datasource.md 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 -- expected-output.txt -- rendering website for provider "terraform-provider-scaffolding" (as "terraform-provider-scaffolding") @@ -23,12 +24,15 @@ generating missing data source content data-source "scaffolding_example" template exists, skipping generating missing function content function "example" template exists, skipping +generating missing ephemeral resource content +ephemeral resource "scaffolding_example" template exists, skipping generating missing provider content provider "terraform-provider-scaffolding" template exists, skipping rendering static website cleaning rendered website dir rendering templated website to static markdown rendering "data-sources/example.md.tmpl" +rendering "ephemeral-resources/example.md.tmpl" rendering "functions/example.md.tmpl" rendering "index.md.tmpl" rendering "resources/example.md.tmpl" @@ -238,6 +242,63 @@ Import is supported using the following syntax: terraform import scaffolding_example.example ``` +tffile: +## Example Usage + +```terraform +resource "scaffolding_example" "example" { + configurable_attribute = "some-value" +} +``` +-- expected-ephemeral-resource.md -- +# Data Fields + +Name: scaffolding_example +Type: Ephemeral Resource +Description: Example ephemeral resource +HasExample: true +ExampleFile: $WORK/examples/ephemeral-resources/scaffolding_example/ephemeral-resource.tf +HasImport: false +ProviderName: terraform-provider-scaffolding +ProviderShortName: scaffolding +RenderedProviderName: terraform-provider-scaffolding +SchemaMarkdown: +## Schema + +### Optional + +- `configurable_attribute` (String) Example configurable attribute +- `defaulted` (String) Example configurable attribute with default value + +### Read-Only + +- `id` (String) Example identifier + + + +# Functions + +lower: ephemeral resource +plainmarkdown: Ephemeral Resource +prefixlines: Prefix: Ephemeral Resource +split: [scaffolding example] +title: Ephemeral Resource +trimspace: Ephemeral Resource +upper: EPHEMERAL RESOURCE + +# Conditionals and File Functions + +printf codefile: + + +printf tffile: +## Example Usage + +{{tffile "$WORK/examples/ephemeral-resources/scaffolding_example/ephemeral-resource.tf"}} + +codefile: + + tffile: ## Example Usage @@ -437,6 +498,63 @@ tffile: {{ if .HasExample -}} ## Example Usage +{{tffile .ExampleFile }} +{{- end }} +-- templates/ephemeral-resources/example.md.tmpl -- +# Data Fields + +Name: {{.Name}} +Type: {{.Type}} +Description: {{.Description}} +HasExample: {{.HasExample}} +ExampleFile: {{.ExampleFile}} +HasImport: {{.HasImport}} +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 codefile: +{{ if .HasImport -}} +## Import + +Import is supported using the following syntax: + +{{ printf "{{codefile \"shell\" %q}}" .ImportFile }} +{{- end }} + +printf tffile: +{{ if .HasExample -}} +## Example Usage + +{{ printf "{{tffile %q}}" .ExampleFile }} +{{- end }} + +codefile: +{{ if .HasImport -}} +## Import + +Import is supported using the following syntax: + +{{codefile "shell" .ImportFile }} +{{- end }} + +tffile: +{{ if .HasExample -}} +## Example Usage + {{tffile .ExampleFile }} {{- end }} -- examples/README.md -- @@ -465,100 +583,134 @@ provider "scaffolding" { resource "scaffolding_example" "example" { configurable_attribute = "some-value" } +-- examples/ephemeral-resources/scaffolding_example/ephemeral-resource.tf -- +resource "scaffolding_example" "example" { + configurable_attribute = "some-value" +} -- examples/resources/scaffolding_example/import.sh -- terraform import scaffolding_example.example -- schema.json -- { - "format_version": "1.0", - "provider_schemas": { - "registry.terraform.io/hashicorp/scaffolding": { - "provider": { - "version": 0, - "block": { - "attributes": { - "endpoint": { - "type": "string", - "description": "Example provider attribute", - "description_kind": "markdown", - "optional": true - } - }, - "description": "Example provider", - "description_kind": "markdown" - } - }, - "resource_schemas": { - "scaffolding_example": { - "version": 0, - "block": { - "attributes": { - "configurable_attribute": { - "type": "string", - "description": "Example configurable attribute", - "description_kind": "markdown", - "optional": true - }, - "defaulted": { - "type": "string", - "description": "Example configurable attribute with default value", - "description_kind": "markdown", - "optional": true, - "computed": true - }, - "id": { - "type": "string", - "description": "Example identifier", - "description_kind": "markdown", - "computed": true - } + "format_version": "1.0", + "provider_schemas": { + "registry.terraform.io/hashicorp/scaffolding": { + "provider": { + "version": 0, + "block": { + "attributes": { + "endpoint": { + "type": "string", + "description": "Example provider attribute", + "description_kind": "markdown", + "optional": true + } + }, + "description": "Example provider", + "description_kind": "markdown" + } }, - "description": "Example resource", - "description_kind": "markdown" - } - } - }, - "data_source_schemas": { - "scaffolding_example": { - "version": 0, - "block": { - "attributes": { - "configurable_attribute": { - "type": "string", - "description": "Example configurable attribute", - "description_kind": "markdown", - "optional": true - }, - "id": { - "type": "string", - "description": "Example identifier", - "description_kind": "markdown", - "computed": true - } + "resource_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "configurable_attribute": { + "type": "string", + "description": "Example configurable attribute", + "description_kind": "markdown", + "optional": true + }, + "defaulted": { + "type": "string", + "description": "Example configurable attribute with default value", + "description_kind": "markdown", + "optional": true, + "computed": true + }, + "id": { + "type": "string", + "description": "Example identifier", + "description_kind": "markdown", + "computed": true + } + }, + "description": "Example resource", + "description_kind": "markdown" + } + } }, - "description": "Example data source", - "description_kind": "markdown" - } - } - }, - "functions": { - "example": { - "description": "Given a string value, returns the same value.", - "summary": "Echo a string", - "return_type": "string", - "parameters": [ - { - "name": "input", - "description": "Value to echo.", - "type": "string" + "ephemeral_resource_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "configurable_attribute": { + "type": "string", + "description": "Example configurable attribute", + "description_kind": "markdown", + "optional": true + }, + "defaulted": { + "type": "string", + "description": "Example configurable attribute with default value", + "description_kind": "markdown", + "optional": true, + "computed": true + }, + "id": { + "type": "string", + "description": "Example identifier", + "description_kind": "markdown", + "computed": true + } + }, + "description": "Example ephemeral resource", + "description_kind": "markdown" + } + } + }, + "data_source_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "configurable_attribute": { + "type": "string", + "description": "Example configurable attribute", + "description_kind": "markdown", + "optional": true + }, + "id": { + "type": "string", + "description": "Example identifier", + "description_kind": "markdown", + "computed": true + } + }, + "description": "Example data source", + "description_kind": "markdown" + } + } + }, + "functions": { + "example": { + "description": "Given a string value, returns the same value.", + "summary": "Echo a string", + "return_type": "string", + "parameters": [ + { + "name": "input", + "description": "Value to echo.", + "type": "string" + } + ], + "variadic_parameter": { + "name": "variadicInput", + "description": "Variadic input to echo.", + "type": "string" + } + } } - ], - "variadic_parameter": { - "name": "variadicInput", - "description": "Variadic input to echo.", - "type": "string" - } } - } } - } } \ No newline at end of file diff --git a/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_no_templates.txtar b/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_no_templates.txtar index 8ac9b9ad..861b396e 100644 --- a/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_no_templates.txtar +++ b/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_no_templates.txtar @@ -9,6 +9,7 @@ cmp docs/index.md expected-index.md cmp docs/data-sources/example.md expected-datasource.md cmp docs/resources/example.md expected-resource.md cmp docs/functions/example.md expected-function.md +cmp docs/ephemeral-resources/example.md expected-ephemeral-resource.md -- expected-output.txt -- rendering website for provider "terraform-provider-scaffolding" (as "terraform-provider-scaffolding") @@ -21,12 +22,15 @@ generating missing data source content generating new template for data-source "scaffolding_example" generating missing function content generating new template for function "example" +generating missing ephemeral resource content +generating new template for "scaffolding_example" generating missing provider content generating new template for "terraform-provider-scaffolding" rendering static website cleaning rendered website dir rendering templated website to static markdown rendering "data-sources/example.md.tmpl" +rendering "ephemeral-resources/example.md.tmpl" rendering "functions/example.md.tmpl" rendering "index.md.tmpl" rendering "resources/example.md.tmpl" @@ -153,6 +157,38 @@ resource "scaffolding_example" "example" { ### Read-Only +- `id` (String) Example identifier +-- expected-ephemeral-resource.md -- +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "scaffolding_example Ephemeral Resource - terraform-provider-scaffolding" +subcategory: "" +description: |- + Example ephemeral resource +--- + +# scaffolding_example (Ephemeral Resource) + +Example ephemeral resource + +## Example Usage + +```terraform +resource "scaffolding_example" "example" { + configurable_attribute = "some-value" +} +``` + + +## Schema + +### Optional + +- `configurable_attribute` (String) Example configurable attribute +- `defaulted` (String) Example configurable attribute with default value + +### Read-Only + - `id` (String) Example identifier -- examples/README.md -- # Examples @@ -180,99 +216,133 @@ provider "scaffolding" { resource "scaffolding_example" "example" { configurable_attribute = "some-value" } +-- examples/ephemeral-resources/scaffolding_example/ephemeral-resource.tf -- +resource "scaffolding_example" "example" { + configurable_attribute = "some-value" +} -- schema.json -- { - "format_version": "1.0", - "provider_schemas": { - "registry.terraform.io/hashicorp/scaffolding": { - "provider": { - "version": 0, - "block": { - "attributes": { - "endpoint": { - "type": "string", - "description": "Example provider attribute", - "description_kind": "markdown", - "optional": true - } - }, - "description": "Example provider", - "description_kind": "markdown" - } - }, - "resource_schemas": { - "scaffolding_example": { - "version": 0, - "block": { - "attributes": { - "configurable_attribute": { - "type": "string", - "description": "Example configurable attribute", - "description_kind": "markdown", - "optional": true - }, - "defaulted": { - "type": "string", - "description": "Example configurable attribute with default value", - "description_kind": "markdown", - "optional": true, - "computed": true - }, - "id": { - "type": "string", - "description": "Example identifier", - "description_kind": "markdown", - "computed": true - } + "format_version": "1.0", + "provider_schemas": { + "registry.terraform.io/hashicorp/scaffolding": { + "provider": { + "version": 0, + "block": { + "attributes": { + "endpoint": { + "type": "string", + "description": "Example provider attribute", + "description_kind": "markdown", + "optional": true + } + }, + "description": "Example provider", + "description_kind": "markdown" + } }, - "description": "Example resource", - "description_kind": "markdown" - } - } - }, - "data_source_schemas": { - "scaffolding_example": { - "version": 0, - "block": { - "attributes": { - "configurable_attribute": { - "type": "string", - "description": "Example configurable attribute", - "description_kind": "markdown", - "optional": true - }, - "id": { - "type": "string", - "description": "Example identifier", - "description_kind": "markdown", - "computed": true - } + "resource_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "configurable_attribute": { + "type": "string", + "description": "Example configurable attribute", + "description_kind": "markdown", + "optional": true + }, + "defaulted": { + "type": "string", + "description": "Example configurable attribute with default value", + "description_kind": "markdown", + "optional": true, + "computed": true + }, + "id": { + "type": "string", + "description": "Example identifier", + "description_kind": "markdown", + "computed": true + } + }, + "description": "Example resource", + "description_kind": "markdown" + } + } }, - "description": "Example data source", - "description_kind": "markdown" - } - } - }, - "functions": { - "example": { - "description": "Given a string value, returns the same value.", - "summary": "Echo a string", - "return_type": "string", - "parameters": [ - { - "name": "input", - "description": "Value to echo.", - "type": "string" + "ephemeral_resource_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "configurable_attribute": { + "type": "string", + "description": "Example configurable attribute", + "description_kind": "markdown", + "optional": true + }, + "defaulted": { + "type": "string", + "description": "Example configurable attribute with default value", + "description_kind": "markdown", + "optional": true, + "computed": true + }, + "id": { + "type": "string", + "description": "Example identifier", + "description_kind": "markdown", + "computed": true + } + }, + "description": "Example ephemeral resource", + "description_kind": "markdown" + } + } + }, + "data_source_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "configurable_attribute": { + "type": "string", + "description": "Example configurable attribute", + "description_kind": "markdown", + "optional": true + }, + "id": { + "type": "string", + "description": "Example identifier", + "description_kind": "markdown", + "computed": true + } + }, + "description": "Example data source", + "description_kind": "markdown" + } + } + }, + "functions": { + "example": { + "description": "Given a string value, returns the same value.", + "summary": "Echo a string", + "return_type": "string", + "parameters": [ + { + "name": "input", + "description": "Value to echo.", + "type": "string" + } + ], + "variadic_parameter": { + "name": "variadicInput", + "description": "Variadic input to echo.", + "type": "string" + } + } } - ], - "variadic_parameter": { - "name": "variadicInput", - "description": "Variadic input to echo.", - "type": "string" - } } - } } - } } \ No newline at end of file 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 bc0309b3..f37cdfc4 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 @@ -22,6 +22,11 @@ cmp templates/functions/example.markdown docs/functions/example.markdown cmp templates/functions/example.html.markdown docs/functions/example.html.markdown cmp templates/functions/example.html.md docs/functions/example.html.md +cmp templates/ephemeral-resources/example.md docs/ephemeral-resources/example.md +cmp templates/ephemeral-resources/example.markdown docs/ephemeral-resources/example.markdown +cmp templates/ephemeral-resources/example.html.markdown docs/ephemeral-resources/example.html.markdown +cmp templates/ephemeral-resources/example.html.md docs/ephemeral-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 @@ -38,6 +43,8 @@ generating missing data source content data-source "scaffolding_example" static file exists, skipping generating missing function content function "example" static file exists, skipping +generating missing ephemeral resource content +ephemeral resource "scaffolding_example" static file exists, skipping generating missing provider content provider "terraform-provider-scaffolding" static file exists, skipping rendering static website @@ -47,6 +54,10 @@ copying non-template file: "data-sources/example.html.markdown" copying non-template file: "data-sources/example.html.md" copying non-template file: "data-sources/example.markdown" copying non-template file: "data-sources/example.md" +copying non-template file: "ephemeral-resources/example.html.markdown" +copying non-template file: "ephemeral-resources/example.html.md" +copying non-template file: "ephemeral-resources/example.markdown" +copying non-template file: "ephemeral-resources/example.md" copying non-template file: "functions/example.html.markdown" copying non-template file: "functions/example.html.md" copying non-template file: "functions/example.markdown" @@ -117,6 +128,26 @@ Type: {{.Type}} -- templates/functions/example.html.md -- # Data Fields +Name: {{.Name}} +Type: {{.Type}} +-- templates/ephemeral-resources/example.md -- +# Data Fields + +Name: {{.Name}} +Type: {{.Type}} +-- templates/ephemeral-resources/example.markdown -- +# Data Fields + +Name: {{.Name}} +Type: {{.Type}} +-- templates/ephemeral-resources/example.html.markdown -- +# Data Fields + +Name: {{.Name}} +Type: {{.Type}} +-- templates/ephemeral-resources/example.html.md -- +# Data Fields + Name: {{.Name}} Type: {{.Type}} -- templates/index.md -- @@ -161,100 +192,134 @@ provider "scaffolding" { resource "scaffolding_example" "example" { configurable_attribute = "some-value" } +-- examples/ephemeral-resources/scaffolding_example/ephemeral-resource.tf -- +resource "scaffolding_example" "example" { + configurable_attribute = "some-value" +} -- examples/resources/scaffolding_example/import.sh -- terraform import scaffolding_example.example -- schema.json -- { - "format_version": "1.0", - "provider_schemas": { - "registry.terraform.io/hashicorp/scaffolding": { - "provider": { - "version": 0, - "block": { - "attributes": { - "endpoint": { - "type": "string", - "description": "Example provider attribute", - "description_kind": "markdown", - "optional": true - } - }, - "description": "Example provider", - "description_kind": "markdown" - } - }, - "resource_schemas": { - "scaffolding_example": { - "version": 0, - "block": { - "attributes": { - "configurable_attribute": { - "type": "string", - "description": "Example configurable attribute", - "description_kind": "markdown", - "optional": true - }, - "defaulted": { - "type": "string", - "description": "Example configurable attribute with default value", - "description_kind": "markdown", - "optional": true, - "computed": true - }, - "id": { - "type": "string", - "description": "Example identifier", - "description_kind": "markdown", - "computed": true - } + "format_version": "1.0", + "provider_schemas": { + "registry.terraform.io/hashicorp/scaffolding": { + "provider": { + "version": 0, + "block": { + "attributes": { + "endpoint": { + "type": "string", + "description": "Example provider attribute", + "description_kind": "markdown", + "optional": true + } + }, + "description": "Example provider", + "description_kind": "markdown" + } }, - "description": "Example resource", - "description_kind": "markdown" - } - } - }, - "data_source_schemas": { - "scaffolding_example": { - "version": 0, - "block": { - "attributes": { - "configurable_attribute": { - "type": "string", - "description": "Example configurable attribute", - "description_kind": "markdown", - "optional": true - }, - "id": { - "type": "string", - "description": "Example identifier", - "description_kind": "markdown", - "computed": true - } + "resource_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "configurable_attribute": { + "type": "string", + "description": "Example configurable attribute", + "description_kind": "markdown", + "optional": true + }, + "defaulted": { + "type": "string", + "description": "Example configurable attribute with default value", + "description_kind": "markdown", + "optional": true, + "computed": true + }, + "id": { + "type": "string", + "description": "Example identifier", + "description_kind": "markdown", + "computed": true + } + }, + "description": "Example resource", + "description_kind": "markdown" + } + } }, - "description": "Example data source", - "description_kind": "markdown" - } - } - }, - "functions": { - "example": { - "description": "Given a string value, returns the same value.", - "summary": "Echo a string", - "return_type": "string", - "parameters": [ - { - "name": "input", - "description": "Value to echo.", - "type": "string" + "ephemeral_resource_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "configurable_attribute": { + "type": "string", + "description": "Example configurable attribute", + "description_kind": "markdown", + "optional": true + }, + "defaulted": { + "type": "string", + "description": "Example configurable attribute with default value", + "description_kind": "markdown", + "optional": true, + "computed": true + }, + "id": { + "type": "string", + "description": "Example identifier", + "description_kind": "markdown", + "computed": true + } + }, + "description": "Example ephemeral resource", + "description_kind": "markdown" + } + } + }, + "data_source_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "configurable_attribute": { + "type": "string", + "description": "Example configurable attribute", + "description_kind": "markdown", + "optional": true + }, + "id": { + "type": "string", + "description": "Example identifier", + "description_kind": "markdown", + "computed": true + } + }, + "description": "Example data source", + "description_kind": "markdown" + } + } + }, + "functions": { + "example": { + "description": "Given a string value, returns the same value.", + "summary": "Echo a string", + "return_type": "string", + "parameters": [ + { + "name": "input", + "description": "Value to echo.", + "type": "string" + } + ], + "variadic_parameter": { + "name": "variadicInput", + "description": "Variadic input to echo.", + "type": "string" + } + } } - ], - "variadic_parameter": { - "name": "variadicInput", - "description": "Variadic input to echo.", - "type": "string" - } } - } } - } } \ No newline at end of file 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 943c54c8..21628fae 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 @@ -17,6 +17,7 @@ generating missing resource content generating new template for "scaffolding_example" generating missing data source content generating missing function content +generating missing ephemeral 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 91597c24..e05ef443 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 @@ -18,6 +18,7 @@ resource "null_resource" fallback template exists, creating template generating missing data source content data-source "null_data_source" fallback template exists, creating template generating missing function content +generating missing ephemeral 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_idempotency.txtar b/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_idempotency.txtar index f2d0dcb6..7427ef84 100644 --- a/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_idempotency.txtar +++ b/cmd/tfplugindocs/testdata/scripts/schema-json/migrate/time_provider_idempotency.txtar @@ -17,6 +17,7 @@ cmpenv templates/resources/offset.md.tmpl exp-templates/resources/offset.md.tmpl cmpenv templates/resources/rotating.md.tmpl exp-templates/resources/rotating.md.tmpl 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 # Check generated example files cmpenv examples/example_1.tf examples/example_1.tf @@ -37,13 +38,25 @@ cmpenv examples/resources/sleep/example_3.tf exp-examples/resources/sleep/exampl cmpenv examples/resources/sleep/import_1.sh exp-examples/resources/sleep/import_1.sh cmpenv examples/resources/sleep/import_2.sh exp-examples/resources/sleep/import_2.sh -cmpenv examples/resources/static/example_1.tf examples/resources/static/example_1.tf -cmpenv examples/resources/static/example_2.tf examples/resources/static/example_2.tf -cmpenv examples/resources/static/import_1.sh examples/resources/static/import_1.sh +cmpenv examples/resources/static/example_1.tf exp-examples/resources/static/example_1.tf +cmpenv examples/resources/static/example_2.tf exp-examples/resources/static/example_2.tf +cmpenv examples/resources/static/import_1.sh exp-examples/resources/static/import_1.sh + +cmpenv examples/ephemeral-resources/ephemeral_static/example_1.tf exp-examples/ephemeral-resources/ephemeral_static/example_1.tf +cmpenv examples/ephemeral-resources/ephemeral_static/example_2.tf exp-examples/ephemeral-resources/ephemeral_static/example_2.tf +cmpenv examples/ephemeral-resources/ephemeral_static/import_1.sh exp-examples/ephemeral-resources/ephemeral_static/import_1.sh -- expected-output.txt -- migrating website from "$WORK/docs" to "$WORK/templates" -migrating functons directory: functions +migrating ephemeral resources directory: ephemeral-resources +migrating file "ephemeral_static.html.markdown" +extracting YAML frontmatter to "$WORK/templates/ephemeral-resources/ephemeral_static.md.tmpl" +extracting code examples from "ephemeral_static.html.markdown" +creating example file "$WORK/examples/ephemeral-resources/ephemeral_static/example_1.tf" +creating example file "$WORK/examples/ephemeral-resources/ephemeral_static/example_2.tf" +creating import file "$WORK/examples/ephemeral-resources/ephemeral_static/import_1.sh" +finished creating template "$WORK/templates/ephemeral-resources/ephemeral_static.md.tmpl" +migrating functions directory: functions migrating file "rfc3339_parse.html.markdown" extracting YAML frontmatter to "$WORK/templates/functions/rfc3339_parse.md.tmpl" extracting code examples from "rfc3339_parse.html.markdown" @@ -516,6 +529,85 @@ This resource can be imported using the UTC RFC3339 value, e.g. $ terraform import time_static.example 2020-02-12T06:36:13Z ``` +The `triggers` argument cannot be imported. +-- docs/ephemeral-resources/ephemeral_static.html.markdown -- +--- +layout: "time" +page_title: "Time: time_ephemeral_static" +description: |- + Manages a static time resource. +--- + +# Resource: time_static + +Manages a static time resource, which keeps a locally sourced UTC timestamp stored in the Terraform state. This prevents perpetual differences caused by using the [`timestamp()` function](https://www.terraform.io/docs/configuration/functions/timestamp.html). + +-> Further manipulation of incoming or outgoing values can be accomplished with the [`formatdate()` function](https://www.terraform.io/docs/configuration/functions/formatdate.html) and the [`timeadd()` function](https://www.terraform.io/docs/configuration/functions/timeadd.html). + +## Example Usage + +### Basic Usage + +```hcl +resource "time_static" "example" {} + +output "current_time" { + value = time_static.example.rfc3339 +} +``` + +### Triggers Usage + +```hcl +resource "time_static" "ami_update" { + triggers = { + # Save the time each switch of an AMI id + ami_id = data.aws_ami.example.id + } +} + +resource "aws_instance" "server" { + # Read the AMI id "through" the time_static resource to ensure that + # both will change together. + ami = time_static.ami_update.triggers.ami_id + + tags = { + AmiUpdateTime = time_static.ami_update.rfc3339 + } + + # ... (other aws_instance arguments) ... +} +``` + +## Argument Reference + +The following arguments are optional: + +* `triggers` - (Optional) Arbitrary map of values that, when changed, will trigger a new base timestamp value to be saved. See [the main provider documentation](../index.html) for more information. +* `rfc3339` - (Optional) Configure the base timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). Defaults to the current time. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `day` - Number day of timestamp. +* `hour` - Number hour of timestamp. +* `id` - UTC RFC3339 timestamp format, e.g. `2020-02-12T06:36:13Z`. +* `minute` - Number minute of timestamp. +* `month` - Number month of timestamp. +* `rfc3339` - UTC RFC3339 format of timestamp, e.g. `2020-02-12T06:36:13Z`. +* `second` - Number second of timestamp. +* `unix` - Number of seconds since epoch time, e.g. `1581489373`. +* `year` - Number year of timestamp. + +## Import + +This resource can be imported using the UTC RFC3339 value, e.g. + +```console +$ terraform import time_static.example 2020-02-12T06:36:13Z +``` + The `triggers` argument cannot be imported. -- exp-examples/example_1.tf -- resource "time_static" "ami_update" { @@ -663,6 +755,33 @@ resource "aws_instance" "server" { } -- exp-examples/resources/static/import_1.sh -- $ terraform import time_static.example 2020-02-12T06:36:13Z +-- exp-examples/ephemeral-resources/ephemeral_static/example_1.tf -- +resource "time_static" "example" {} + +output "current_time" { + value = time_static.example.rfc3339 +} +-- exp-examples/ephemeral-resources/ephemeral_static/example_2.tf -- +resource "time_static" "ami_update" { + triggers = { + # Save the time each switch of an AMI id + ami_id = data.aws_ami.example.id + } +} + +resource "aws_instance" "server" { + # Read the AMI id "through" the time_static resource to ensure that + # both will change together. + ami = time_static.ami_update.triggers.ami_id + + tags = { + AmiUpdateTime = time_static.ami_update.rfc3339 + } + + # ... (other aws_instance arguments) ... +} +-- exp-examples/ephemeral-resources/ephemeral_static/import_1.sh -- +$ terraform import time_static.example 2020-02-12T06:36:13Z -- exp-templates/index.md.tmpl -- --- page_title: "Provider: Time" @@ -963,4 +1082,59 @@ This resource can be imported using the UTC RFC3339 value, e.g. {{codefile "shell" "examples/resources/static/import_1.sh"}} +The `triggers` argument cannot be imported. +-- exp-templates/ephemeral-resources/ephemeral_static.md.tmpl -- +--- +page_title: "Time: time_ephemeral_static" +description: |- + Manages a static time resource. +--- + +{{/* 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. */ -}} + +# Resource: time_static + +Manages a static time resource, which keeps a locally sourced UTC timestamp stored in the Terraform state. This prevents perpetual differences caused by using the [`timestamp()` function](https://www.terraform.io/docs/configuration/functions/timestamp.html). + +-> Further manipulation of incoming or outgoing values can be accomplished with the [`formatdate()` function](https://www.terraform.io/docs/configuration/functions/formatdate.html) and the [`timeadd()` function](https://www.terraform.io/docs/configuration/functions/timeadd.html). + +## Example Usage + +### Basic Usage + +{{tffile "examples/ephemeral-resources/ephemeral_static/example_1.tf"}} + +### Triggers Usage + +{{tffile "examples/ephemeral-resources/ephemeral_static/example_2.tf"}} + +## Argument Reference + +The following arguments are optional: + +* `triggers` - (Optional) Arbitrary map of values that, when changed, will trigger a new base timestamp value to be saved. See [the main provider documentation](../index.html) for more information. +* `rfc3339` - (Optional) Configure the base timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). Defaults to the current time. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `day` - Number day of timestamp. +* `hour` - Number hour of timestamp. +* `id` - UTC RFC3339 timestamp format, e.g. `2020-02-12T06:36:13Z`. +* `minute` - Number minute of timestamp. +* `month` - Number month of timestamp. +* `rfc3339` - UTC RFC3339 format of timestamp, e.g. `2020-02-12T06:36:13Z`. +* `second` - Number second of timestamp. +* `unix` - Number of seconds since epoch time, e.g. `1581489373`. +* `year` - Number year of timestamp. + +## Import + +This resource can be imported using the UTC RFC3339 value, e.g. + +{{codefile "shell" "examples/ephemeral-resources/ephemeral_static/import_1.sh"}} + The `triggers` argument cannot be imported. \ No newline at end of file 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 ea93de7c..6928f37a 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 @@ -15,6 +15,7 @@ cmpenv templates/resources/offset.md.tmpl exp-templates/resources/offset.md.tmpl cmpenv templates/resources/rotating.md.tmpl exp-templates/resources/rotating.md.tmpl 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 # Check generated example files cmpenv examples/example_1.tf examples/example_1.tf @@ -35,13 +36,25 @@ cmpenv examples/resources/sleep/example_3.tf exp-examples/resources/sleep/exampl cmpenv examples/resources/sleep/import_1.sh exp-examples/resources/sleep/import_1.sh cmpenv examples/resources/sleep/import_2.sh exp-examples/resources/sleep/import_2.sh -cmpenv examples/resources/static/example_1.tf examples/resources/static/example_1.tf -cmpenv examples/resources/static/example_2.tf examples/resources/static/example_2.tf -cmpenv examples/resources/static/import_1.sh examples/resources/static/import_1.sh +cmpenv examples/resources/static/example_1.tf exp-examples/resources/static/example_1.tf +cmpenv examples/resources/static/example_2.tf exp-examples/resources/static/example_2.tf +cmpenv examples/resources/static/import_1.sh exp-examples/resources/static/import_1.sh + +cmpenv examples/ephemeral-resources/ephemeral_static/example_1.tf exp-examples/ephemeral-resources/ephemeral_static/example_1.tf +cmpenv examples/ephemeral-resources/ephemeral_static/example_2.tf exp-examples/ephemeral-resources/ephemeral_static/example_2.tf +cmpenv examples/ephemeral-resources/ephemeral_static/import_1.sh exp-examples/ephemeral-resources/ephemeral_static/import_1.sh -- expected-output.txt -- migrating website from "$WORK/docs" to "$WORK/templates" -migrating functons directory: functions +migrating ephemeral resources directory: ephemeral-resources +migrating file "ephemeral_static.html.markdown" +extracting YAML frontmatter to "$WORK/templates/ephemeral-resources/ephemeral_static.md.tmpl" +extracting code examples from "ephemeral_static.html.markdown" +creating example file "$WORK/examples/ephemeral-resources/ephemeral_static/example_1.tf" +creating example file "$WORK/examples/ephemeral-resources/ephemeral_static/example_2.tf" +creating import file "$WORK/examples/ephemeral-resources/ephemeral_static/import_1.sh" +finished creating template "$WORK/templates/ephemeral-resources/ephemeral_static.md.tmpl" +migrating functions directory: functions migrating file "rfc3339_parse.html.markdown" extracting YAML frontmatter to "$WORK/templates/functions/rfc3339_parse.md.tmpl" extracting code examples from "rfc3339_parse.html.markdown" @@ -514,6 +527,85 @@ This resource can be imported using the UTC RFC3339 value, e.g. $ terraform import time_static.example 2020-02-12T06:36:13Z ``` +The `triggers` argument cannot be imported. +-- docs/ephemeral-resources/ephemeral_static.html.markdown -- +--- +layout: "time" +page_title: "Time: time_ephemeral_static" +description: |- + Manages a static time resource. +--- + +# Resource: time_static + +Manages a static time resource, which keeps a locally sourced UTC timestamp stored in the Terraform state. This prevents perpetual differences caused by using the [`timestamp()` function](https://www.terraform.io/docs/configuration/functions/timestamp.html). + +-> Further manipulation of incoming or outgoing values can be accomplished with the [`formatdate()` function](https://www.terraform.io/docs/configuration/functions/formatdate.html) and the [`timeadd()` function](https://www.terraform.io/docs/configuration/functions/timeadd.html). + +## Example Usage + +### Basic Usage + +```hcl +resource "time_static" "example" {} + +output "current_time" { + value = time_static.example.rfc3339 +} +``` + +### Triggers Usage + +```hcl +resource "time_static" "ami_update" { + triggers = { + # Save the time each switch of an AMI id + ami_id = data.aws_ami.example.id + } +} + +resource "aws_instance" "server" { + # Read the AMI id "through" the time_static resource to ensure that + # both will change together. + ami = time_static.ami_update.triggers.ami_id + + tags = { + AmiUpdateTime = time_static.ami_update.rfc3339 + } + + # ... (other aws_instance arguments) ... +} +``` + +## Argument Reference + +The following arguments are optional: + +* `triggers` - (Optional) Arbitrary map of values that, when changed, will trigger a new base timestamp value to be saved. See [the main provider documentation](../index.html) for more information. +* `rfc3339` - (Optional) Configure the base timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). Defaults to the current time. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `day` - Number day of timestamp. +* `hour` - Number hour of timestamp. +* `id` - UTC RFC3339 timestamp format, e.g. `2020-02-12T06:36:13Z`. +* `minute` - Number minute of timestamp. +* `month` - Number month of timestamp. +* `rfc3339` - UTC RFC3339 format of timestamp, e.g. `2020-02-12T06:36:13Z`. +* `second` - Number second of timestamp. +* `unix` - Number of seconds since epoch time, e.g. `1581489373`. +* `year` - Number year of timestamp. + +## Import + +This resource can be imported using the UTC RFC3339 value, e.g. + +```console +$ terraform import time_static.example 2020-02-12T06:36:13Z +``` + The `triggers` argument cannot be imported. -- exp-examples/example_1.tf -- resource "time_static" "ami_update" { @@ -661,6 +753,33 @@ resource "aws_instance" "server" { } -- exp-examples/resources/static/import_1.sh -- $ terraform import time_static.example 2020-02-12T06:36:13Z +-- exp-examples/ephemeral-resources/ephemeral_static/example_1.tf -- +resource "time_static" "example" {} + +output "current_time" { + value = time_static.example.rfc3339 +} +-- exp-examples/ephemeral-resources/ephemeral_static/example_2.tf -- +resource "time_static" "ami_update" { + triggers = { + # Save the time each switch of an AMI id + ami_id = data.aws_ami.example.id + } +} + +resource "aws_instance" "server" { + # Read the AMI id "through" the time_static resource to ensure that + # both will change together. + ami = time_static.ami_update.triggers.ami_id + + tags = { + AmiUpdateTime = time_static.ami_update.rfc3339 + } + + # ... (other aws_instance arguments) ... +} +-- exp-examples/ephemeral-resources/ephemeral_static/import_1.sh -- +$ terraform import time_static.example 2020-02-12T06:36:13Z -- exp-templates/index.md.tmpl -- --- page_title: "Provider: Time" @@ -961,4 +1080,59 @@ This resource can be imported using the UTC RFC3339 value, e.g. {{codefile "shell" "examples/resources/static/import_1.sh"}} +The `triggers` argument cannot be imported. +-- exp-templates/ephemeral-resources/ephemeral_static.md.tmpl -- +--- +page_title: "Time: time_ephemeral_static" +description: |- + Manages a static time resource. +--- + +{{/* 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. */ -}} + +# Resource: time_static + +Manages a static time resource, which keeps a locally sourced UTC timestamp stored in the Terraform state. This prevents perpetual differences caused by using the [`timestamp()` function](https://www.terraform.io/docs/configuration/functions/timestamp.html). + +-> Further manipulation of incoming or outgoing values can be accomplished with the [`formatdate()` function](https://www.terraform.io/docs/configuration/functions/formatdate.html) and the [`timeadd()` function](https://www.terraform.io/docs/configuration/functions/timeadd.html). + +## Example Usage + +### Basic Usage + +{{tffile "examples/ephemeral-resources/ephemeral_static/example_1.tf"}} + +### Triggers Usage + +{{tffile "examples/ephemeral-resources/ephemeral_static/example_2.tf"}} + +## Argument Reference + +The following arguments are optional: + +* `triggers` - (Optional) Arbitrary map of values that, when changed, will trigger a new base timestamp value to be saved. See [the main provider documentation](../index.html) for more information. +* `rfc3339` - (Optional) Configure the base timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). Defaults to the current time. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `day` - Number day of timestamp. +* `hour` - Number hour of timestamp. +* `id` - UTC RFC3339 timestamp format, e.g. `2020-02-12T06:36:13Z`. +* `minute` - Number minute of timestamp. +* `month` - Number month of timestamp. +* `rfc3339` - UTC RFC3339 format of timestamp, e.g. `2020-02-12T06:36:13Z`. +* `second` - Number second of timestamp. +* `unix` - Number of seconds since epoch time, e.g. `1581489373`. +* `year` - Number year of timestamp. + +## Import + +This resource can be imported using the UTC RFC3339 value, e.g. + +{{codefile "shell" "examples/ephemeral-resources/ephemeral_static/import_1.sh"}} + The `triggers` argument cannot be imported. \ No newline at end of file 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 0192624b..11704c44 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 @@ -15,6 +15,7 @@ cmpenv templates/resources/offset.md.tmpl exp-templates/resources/offset.md.tmpl cmpenv templates/resources/rotating.md.tmpl exp-templates/resources/rotating.md.tmpl 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 # Check generated example files cmpenv examples/example_1.tf examples/example_1.tf @@ -35,13 +36,25 @@ cmpenv examples/resources/sleep/example_3.tf exp-examples/resources/sleep/exampl cmpenv examples/resources/sleep/import_1.sh exp-examples/resources/sleep/import_1.sh cmpenv examples/resources/sleep/import_2.sh exp-examples/resources/sleep/import_2.sh -cmpenv examples/resources/static/example_1.tf examples/resources/static/example_1.tf -cmpenv examples/resources/static/example_2.tf examples/resources/static/example_2.tf -cmpenv examples/resources/static/import_1.sh examples/resources/static/import_1.sh +cmpenv examples/resources/static/example_1.tf exp-examples/resources/static/example_1.tf +cmpenv examples/resources/static/example_2.tf exp-examples/resources/static/example_2.tf +cmpenv examples/resources/static/import_1.sh exp-examples/resources/static/import_1.sh + +cmpenv examples/ephemeral-resources/ephemeral_static/example_1.tf exp-examples/ephemeral-resources/ephemeral_static/example_1.tf +cmpenv examples/ephemeral-resources/ephemeral_static/example_2.tf exp-examples/ephemeral-resources/ephemeral_static/example_2.tf +cmpenv examples/ephemeral-resources/ephemeral_static/import_1.sh exp-examples/ephemeral-resources/ephemeral_static/import_1.sh -- expected-output.txt -- migrating website from "$WORK/docs" to "$WORK/templates" -migrating functons directory: functions +migrating ephemeral resources directory: ephemeral-resources +migrating file "time_ephemeral_static.html.markdown" +extracting YAML frontmatter to "$WORK/templates/ephemeral-resources/ephemeral_static.md.tmpl" +extracting code examples from "time_ephemeral_static.html.markdown" +creating example file "$WORK/examples/ephemeral-resources/ephemeral_static/example_1.tf" +creating example file "$WORK/examples/ephemeral-resources/ephemeral_static/example_2.tf" +creating import file "$WORK/examples/ephemeral-resources/ephemeral_static/import_1.sh" +finished creating template "$WORK/templates/ephemeral-resources/ephemeral_static.md.tmpl" +migrating functions directory: functions migrating file "time_rfc3339_parse.html.markdown" extracting YAML frontmatter to "$WORK/templates/functions/rfc3339_parse.md.tmpl" extracting code examples from "time_rfc3339_parse.html.markdown" @@ -514,6 +527,85 @@ This resource can be imported using the UTC RFC3339 value, e.g. $ terraform import time_static.example 2020-02-12T06:36:13Z ``` +The `triggers` argument cannot be imported. +-- docs/ephemeral-resources/time_ephemeral_static.html.markdown -- +--- +layout: "time" +page_title: "Time: time_ephemeral_static" +description: |- + Manages a static time resource. +--- + +# Resource: time_static + +Manages a static time resource, which keeps a locally sourced UTC timestamp stored in the Terraform state. This prevents perpetual differences caused by using the [`timestamp()` function](https://www.terraform.io/docs/configuration/functions/timestamp.html). + +-> Further manipulation of incoming or outgoing values can be accomplished with the [`formatdate()` function](https://www.terraform.io/docs/configuration/functions/formatdate.html) and the [`timeadd()` function](https://www.terraform.io/docs/configuration/functions/timeadd.html). + +## Example Usage + +### Basic Usage + +```hcl +resource "time_static" "example" {} + +output "current_time" { + value = time_static.example.rfc3339 +} +``` + +### Triggers Usage + +```hcl +resource "time_static" "ami_update" { + triggers = { + # Save the time each switch of an AMI id + ami_id = data.aws_ami.example.id + } +} + +resource "aws_instance" "server" { + # Read the AMI id "through" the time_static resource to ensure that + # both will change together. + ami = time_static.ami_update.triggers.ami_id + + tags = { + AmiUpdateTime = time_static.ami_update.rfc3339 + } + + # ... (other aws_instance arguments) ... +} +``` + +## Argument Reference + +The following arguments are optional: + +* `triggers` - (Optional) Arbitrary map of values that, when changed, will trigger a new base timestamp value to be saved. See [the main provider documentation](../index.html) for more information. +* `rfc3339` - (Optional) Configure the base timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). Defaults to the current time. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `day` - Number day of timestamp. +* `hour` - Number hour of timestamp. +* `id` - UTC RFC3339 timestamp format, e.g. `2020-02-12T06:36:13Z`. +* `minute` - Number minute of timestamp. +* `month` - Number month of timestamp. +* `rfc3339` - UTC RFC3339 format of timestamp, e.g. `2020-02-12T06:36:13Z`. +* `second` - Number second of timestamp. +* `unix` - Number of seconds since epoch time, e.g. `1581489373`. +* `year` - Number year of timestamp. + +## Import + +This resource can be imported using the UTC RFC3339 value, e.g. + +```console +$ terraform import time_static.example 2020-02-12T06:36:13Z +``` + The `triggers` argument cannot be imported. -- exp-examples/example_1.tf -- resource "time_static" "ami_update" { @@ -661,6 +753,33 @@ resource "aws_instance" "server" { } -- exp-examples/resources/static/import_1.sh -- $ terraform import time_static.example 2020-02-12T06:36:13Z +-- exp-examples/ephemeral-resources/ephemeral_static/example_1.tf -- +resource "time_static" "example" {} + +output "current_time" { + value = time_static.example.rfc3339 +} +-- exp-examples/ephemeral-resources/ephemeral_static/example_2.tf -- +resource "time_static" "ami_update" { + triggers = { + # Save the time each switch of an AMI id + ami_id = data.aws_ami.example.id + } +} + +resource "aws_instance" "server" { + # Read the AMI id "through" the time_static resource to ensure that + # both will change together. + ami = time_static.ami_update.triggers.ami_id + + tags = { + AmiUpdateTime = time_static.ami_update.rfc3339 + } + + # ... (other aws_instance arguments) ... +} +-- exp-examples/ephemeral-resources/ephemeral_static/import_1.sh -- +$ terraform import time_static.example 2020-02-12T06:36:13Z -- exp-templates/index.md.tmpl -- --- page_title: "Provider: Time" @@ -961,4 +1080,59 @@ This resource can be imported using the UTC RFC3339 value, e.g. {{codefile "shell" "examples/resources/static/import_1.sh"}} +The `triggers` argument cannot be imported. +-- exp-templates/ephemeral-resources/ephemeral_static.md.tmpl -- +--- +page_title: "Time: time_ephemeral_static" +description: |- + Manages a static time resource. +--- + +{{/* 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. */ -}} + +# Resource: time_static + +Manages a static time resource, which keeps a locally sourced UTC timestamp stored in the Terraform state. This prevents perpetual differences caused by using the [`timestamp()` function](https://www.terraform.io/docs/configuration/functions/timestamp.html). + +-> Further manipulation of incoming or outgoing values can be accomplished with the [`formatdate()` function](https://www.terraform.io/docs/configuration/functions/formatdate.html) and the [`timeadd()` function](https://www.terraform.io/docs/configuration/functions/timeadd.html). + +## Example Usage + +### Basic Usage + +{{tffile "examples/ephemeral-resources/ephemeral_static/example_1.tf"}} + +### Triggers Usage + +{{tffile "examples/ephemeral-resources/ephemeral_static/example_2.tf"}} + +## Argument Reference + +The following arguments are optional: + +* `triggers` - (Optional) Arbitrary map of values that, when changed, will trigger a new base timestamp value to be saved. See [the main provider documentation](../index.html) for more information. +* `rfc3339` - (Optional) Configure the base timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). Defaults to the current time. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `day` - Number day of timestamp. +* `hour` - Number hour of timestamp. +* `id` - UTC RFC3339 timestamp format, e.g. `2020-02-12T06:36:13Z`. +* `minute` - Number minute of timestamp. +* `month` - Number month of timestamp. +* `rfc3339` - UTC RFC3339 format of timestamp, e.g. `2020-02-12T06:36:13Z`. +* `second` - Number second of timestamp. +* `unix` - Number of seconds since epoch time, e.g. `1581489373`. +* `year` - Number year of timestamp. + +## Import + +This resource can be imported using the UTC RFC3339 value, e.g. + +{{codefile "shell" "examples/ephemeral-resources/ephemeral_static/import_1.sh"}} + The `triggers` argument cannot be imported. \ No newline at end of file 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 736e2d3b..1b067803 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 @@ -15,6 +15,7 @@ cmpenv templates/resources/offset.md.tmpl exp-templates/resources/offset.md.tmpl cmpenv templates/resources/rotating.md.tmpl exp-templates/resources/rotating.md.tmpl 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 # Check generated example files cmpenv examples/example_1.tf examples/example_1.tf @@ -35,16 +36,28 @@ cmpenv examples/resources/sleep/example_3.tf exp-examples/resources/sleep/exampl cmpenv examples/resources/sleep/import_1.sh exp-examples/resources/sleep/import_1.sh cmpenv examples/resources/sleep/import_2.sh exp-examples/resources/sleep/import_2.sh -cmpenv examples/resources/static/example_1.tf examples/resources/static/example_1.tf -cmpenv examples/resources/static/example_2.tf examples/resources/static/example_2.tf -cmpenv examples/resources/static/import_1.sh examples/resources/static/import_1.sh +cmpenv examples/resources/static/example_1.tf exp-examples/resources/static/example_1.tf +cmpenv examples/resources/static/example_2.tf exp-examples/resources/static/example_2.tf +cmpenv examples/resources/static/import_1.sh exp-examples/resources/static/import_1.sh + +cmpenv examples/ephemeral-resources/ephemeral_static/example_1.tf exp-examples/ephemeral-resources/ephemeral_static/example_1.tf +cmpenv examples/ephemeral-resources/ephemeral_static/example_2.tf exp-examples/ephemeral-resources/ephemeral_static/example_2.tf +cmpenv examples/ephemeral-resources/ephemeral_static/import_1.sh exp-examples/ephemeral-resources/ephemeral_static/import_1.sh # Verify legacy website directory is removed ! exists website/ -- expected-output.txt -- migrating website from "$WORK/website/docs" to "$WORK/templates" -migrating functons directory: functions +migrating ephemeral resources directory: ephemeral-resources +migrating file "ephemeral_static.html.markdown" +extracting YAML frontmatter to "$WORK/templates/ephemeral-resources/ephemeral_static.md.tmpl" +extracting code examples from "ephemeral_static.html.markdown" +creating example file "$WORK/examples/ephemeral-resources/ephemeral_static/example_1.tf" +creating example file "$WORK/examples/ephemeral-resources/ephemeral_static/example_2.tf" +creating import file "$WORK/examples/ephemeral-resources/ephemeral_static/import_1.sh" +finished creating template "$WORK/templates/ephemeral-resources/ephemeral_static.md.tmpl" +migrating functions directory: functions migrating file "rfc3339_parse.html.markdown" extracting YAML frontmatter to "$WORK/templates/functions/rfc3339_parse.md.tmpl" extracting code examples from "rfc3339_parse.html.markdown" @@ -518,7 +531,85 @@ $ terraform import time_static.example 2020-02-12T06:36:13Z ``` The `triggers` argument cannot be imported. +-- website/docs/ephemeral-resources/ephemeral_static.html.markdown -- +--- +layout: "time" +page_title: "Time: time_ephemeral_static" +description: |- + Manages a static time resource. +--- + +# Resource: time_static + +Manages a static time resource, which keeps a locally sourced UTC timestamp stored in the Terraform state. This prevents perpetual differences caused by using the [`timestamp()` function](https://www.terraform.io/docs/configuration/functions/timestamp.html). + +-> Further manipulation of incoming or outgoing values can be accomplished with the [`formatdate()` function](https://www.terraform.io/docs/configuration/functions/formatdate.html) and the [`timeadd()` function](https://www.terraform.io/docs/configuration/functions/timeadd.html). + +## Example Usage + +### Basic Usage + +```hcl +resource "time_static" "example" {} + +output "current_time" { + value = time_static.example.rfc3339 +} +``` + +### Triggers Usage + +```hcl +resource "time_static" "ami_update" { + triggers = { + # Save the time each switch of an AMI id + ami_id = data.aws_ami.example.id + } +} + +resource "aws_instance" "server" { + # Read the AMI id "through" the time_static resource to ensure that + # both will change together. + ami = time_static.ami_update.triggers.ami_id + + tags = { + AmiUpdateTime = time_static.ami_update.rfc3339 + } + + # ... (other aws_instance arguments) ... +} +``` + +## Argument Reference + +The following arguments are optional: + +* `triggers` - (Optional) Arbitrary map of values that, when changed, will trigger a new base timestamp value to be saved. See [the main provider documentation](../index.html) for more information. +* `rfc3339` - (Optional) Configure the base timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). Defaults to the current time. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `day` - Number day of timestamp. +* `hour` - Number hour of timestamp. +* `id` - UTC RFC3339 timestamp format, e.g. `2020-02-12T06:36:13Z`. +* `minute` - Number minute of timestamp. +* `month` - Number month of timestamp. +* `rfc3339` - UTC RFC3339 format of timestamp, e.g. `2020-02-12T06:36:13Z`. +* `second` - Number second of timestamp. +* `unix` - Number of seconds since epoch time, e.g. `1581489373`. +* `year` - Number year of timestamp. + +## Import + +This resource can be imported using the UTC RFC3339 value, e.g. + +```console +$ terraform import time_static.example 2020-02-12T06:36:13Z +``` +The `triggers` argument cannot be imported. -- exp-examples/example_1.tf -- resource "time_static" "ami_update" { triggers = { @@ -665,6 +756,33 @@ resource "aws_instance" "server" { } -- exp-examples/resources/static/import_1.sh -- $ terraform import time_static.example 2020-02-12T06:36:13Z +-- exp-examples/ephemeral-resources/ephemeral_static/example_1.tf -- +resource "time_static" "example" {} + +output "current_time" { + value = time_static.example.rfc3339 +} +-- exp-examples/ephemeral-resources/ephemeral_static/example_2.tf -- +resource "time_static" "ami_update" { + triggers = { + # Save the time each switch of an AMI id + ami_id = data.aws_ami.example.id + } +} + +resource "aws_instance" "server" { + # Read the AMI id "through" the time_static resource to ensure that + # both will change together. + ami = time_static.ami_update.triggers.ami_id + + tags = { + AmiUpdateTime = time_static.ami_update.rfc3339 + } + + # ... (other aws_instance arguments) ... +} +-- exp-examples/ephemeral-resources/ephemeral_static/import_1.sh -- +$ terraform import time_static.example 2020-02-12T06:36:13Z -- exp-templates/index.md.tmpl -- --- page_title: "Provider: Time" @@ -965,4 +1083,59 @@ This resource can be imported using the UTC RFC3339 value, e.g. {{codefile "shell" "examples/resources/static/import_1.sh"}} +The `triggers` argument cannot be imported. +-- exp-templates/ephemeral-resources/ephemeral_static.md.tmpl -- +--- +page_title: "Time: time_ephemeral_static" +description: |- + Manages a static time resource. +--- + +{{/* 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. */ -}} + +# Resource: time_static + +Manages a static time resource, which keeps a locally sourced UTC timestamp stored in the Terraform state. This prevents perpetual differences caused by using the [`timestamp()` function](https://www.terraform.io/docs/configuration/functions/timestamp.html). + +-> Further manipulation of incoming or outgoing values can be accomplished with the [`formatdate()` function](https://www.terraform.io/docs/configuration/functions/formatdate.html) and the [`timeadd()` function](https://www.terraform.io/docs/configuration/functions/timeadd.html). + +## Example Usage + +### Basic Usage + +{{tffile "examples/ephemeral-resources/ephemeral_static/example_1.tf"}} + +### Triggers Usage + +{{tffile "examples/ephemeral-resources/ephemeral_static/example_2.tf"}} + +## Argument Reference + +The following arguments are optional: + +* `triggers` - (Optional) Arbitrary map of values that, when changed, will trigger a new base timestamp value to be saved. See [the main provider documentation](../index.html) for more information. +* `rfc3339` - (Optional) Configure the base timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). Defaults to the current time. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `day` - Number day of timestamp. +* `hour` - Number hour of timestamp. +* `id` - UTC RFC3339 timestamp format, e.g. `2020-02-12T06:36:13Z`. +* `minute` - Number minute of timestamp. +* `month` - Number month of timestamp. +* `rfc3339` - UTC RFC3339 format of timestamp, e.g. `2020-02-12T06:36:13Z`. +* `second` - Number second of timestamp. +* `unix` - Number of seconds since epoch time, e.g. `1581489373`. +* `year` - Number year of timestamp. + +## Import + +This resource can be imported using the UTC RFC3339 value, e.g. + +{{codefile "shell" "examples/ephemeral-resources/ephemeral_static/import_1.sh"}} + The `triggers` argument cannot be imported. \ No newline at end of file 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 75f93373..e1ce2305 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 @@ -15,6 +15,7 @@ cmpenv templates/resources/offset.md.tmpl exp-templates/resources/offset.md.tmpl cmpenv templates/resources/rotating.md.tmpl exp-templates/resources/rotating.md.tmpl 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 # Check generated example files cmpenv examples/example_1.tf examples/example_1.tf @@ -35,16 +36,28 @@ cmpenv examples/resources/sleep/example_3.tf exp-examples/resources/sleep/exampl cmpenv examples/resources/sleep/import_1.sh exp-examples/resources/sleep/import_1.sh cmpenv examples/resources/sleep/import_2.sh exp-examples/resources/sleep/import_2.sh -cmpenv examples/resources/static/example_1.tf examples/resources/static/example_1.tf -cmpenv examples/resources/static/example_2.tf examples/resources/static/example_2.tf -cmpenv examples/resources/static/import_1.sh examples/resources/static/import_1.sh +cmpenv examples/resources/static/example_1.tf exp-examples/resources/static/example_1.tf +cmpenv examples/resources/static/example_2.tf exp-examples/resources/static/example_2.tf +cmpenv examples/resources/static/import_1.sh exp-examples/resources/static/import_1.sh + +cmpenv examples/ephemeral-resources/ephemeral_static/example_1.tf exp-examples/ephemeral-resources/ephemeral_static/example_1.tf +cmpenv examples/ephemeral-resources/ephemeral_static/example_2.tf exp-examples/ephemeral-resources/ephemeral_static/example_2.tf +cmpenv examples/ephemeral-resources/ephemeral_static/import_1.sh exp-examples/ephemeral-resources/ephemeral_static/import_1.sh # Verify legacy website directory is removed ! exists website/ -- expected-output.txt -- migrating website from "$WORK/website/docs" to "$WORK/templates" -migrating functons directory: functions +migrating ephemeral resources directory: ephemeral-resources +migrating file "time_ephemeral_static.html.markdown" +extracting YAML frontmatter to "$WORK/templates/ephemeral-resources/ephemeral_static.md.tmpl" +extracting code examples from "time_ephemeral_static.html.markdown" +creating example file "$WORK/examples/ephemeral-resources/ephemeral_static/example_1.tf" +creating example file "$WORK/examples/ephemeral-resources/ephemeral_static/example_2.tf" +creating import file "$WORK/examples/ephemeral-resources/ephemeral_static/import_1.sh" +finished creating template "$WORK/templates/ephemeral-resources/ephemeral_static.md.tmpl" +migrating functions directory: functions migrating file "time_rfc3339_parse.html.markdown" extracting YAML frontmatter to "$WORK/templates/functions/rfc3339_parse.md.tmpl" extracting code examples from "time_rfc3339_parse.html.markdown" @@ -518,7 +531,85 @@ $ terraform import time_static.example 2020-02-12T06:36:13Z ``` The `triggers` argument cannot be imported. +-- website/docs/ephemeral-resources/time_ephemeral_static.html.markdown -- +--- +layout: "time" +page_title: "Time: time_ephemeral_static" +description: |- + Manages a static time resource. +--- + +# Resource: time_static + +Manages a static time resource, which keeps a locally sourced UTC timestamp stored in the Terraform state. This prevents perpetual differences caused by using the [`timestamp()` function](https://www.terraform.io/docs/configuration/functions/timestamp.html). + +-> Further manipulation of incoming or outgoing values can be accomplished with the [`formatdate()` function](https://www.terraform.io/docs/configuration/functions/formatdate.html) and the [`timeadd()` function](https://www.terraform.io/docs/configuration/functions/timeadd.html). + +## Example Usage + +### Basic Usage + +```hcl +resource "time_static" "example" {} + +output "current_time" { + value = time_static.example.rfc3339 +} +``` + +### Triggers Usage + +```hcl +resource "time_static" "ami_update" { + triggers = { + # Save the time each switch of an AMI id + ami_id = data.aws_ami.example.id + } +} + +resource "aws_instance" "server" { + # Read the AMI id "through" the time_static resource to ensure that + # both will change together. + ami = time_static.ami_update.triggers.ami_id + + tags = { + AmiUpdateTime = time_static.ami_update.rfc3339 + } + + # ... (other aws_instance arguments) ... +} +``` + +## Argument Reference + +The following arguments are optional: + +* `triggers` - (Optional) Arbitrary map of values that, when changed, will trigger a new base timestamp value to be saved. See [the main provider documentation](../index.html) for more information. +* `rfc3339` - (Optional) Configure the base timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). Defaults to the current time. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `day` - Number day of timestamp. +* `hour` - Number hour of timestamp. +* `id` - UTC RFC3339 timestamp format, e.g. `2020-02-12T06:36:13Z`. +* `minute` - Number minute of timestamp. +* `month` - Number month of timestamp. +* `rfc3339` - UTC RFC3339 format of timestamp, e.g. `2020-02-12T06:36:13Z`. +* `second` - Number second of timestamp. +* `unix` - Number of seconds since epoch time, e.g. `1581489373`. +* `year` - Number year of timestamp. + +## Import + +This resource can be imported using the UTC RFC3339 value, e.g. + +```console +$ terraform import time_static.example 2020-02-12T06:36:13Z +``` +The `triggers` argument cannot be imported. -- exp-examples/example_1.tf -- resource "time_static" "ami_update" { triggers = { @@ -665,6 +756,33 @@ resource "aws_instance" "server" { } -- exp-examples/resources/static/import_1.sh -- $ terraform import time_static.example 2020-02-12T06:36:13Z +-- exp-examples/ephemeral-resources/ephemeral_static/example_1.tf -- +resource "time_static" "example" {} + +output "current_time" { + value = time_static.example.rfc3339 +} +-- exp-examples/ephemeral-resources/ephemeral_static/example_2.tf -- +resource "time_static" "ami_update" { + triggers = { + # Save the time each switch of an AMI id + ami_id = data.aws_ami.example.id + } +} + +resource "aws_instance" "server" { + # Read the AMI id "through" the time_static resource to ensure that + # both will change together. + ami = time_static.ami_update.triggers.ami_id + + tags = { + AmiUpdateTime = time_static.ami_update.rfc3339 + } + + # ... (other aws_instance arguments) ... +} +-- exp-examples/ephemeral-resources/ephemeral_static/import_1.sh -- +$ terraform import time_static.example 2020-02-12T06:36:13Z -- exp-templates/index.md.tmpl -- --- page_title: "Provider: Time" @@ -965,4 +1083,59 @@ This resource can be imported using the UTC RFC3339 value, e.g. {{codefile "shell" "examples/resources/static/import_1.sh"}} +The `triggers` argument cannot be imported. +-- exp-templates/ephemeral-resources/ephemeral_static.md.tmpl -- +--- +page_title: "Time: time_ephemeral_static" +description: |- + Manages a static time resource. +--- + +{{/* 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. */ -}} + +# Resource: time_static + +Manages a static time resource, which keeps a locally sourced UTC timestamp stored in the Terraform state. This prevents perpetual differences caused by using the [`timestamp()` function](https://www.terraform.io/docs/configuration/functions/timestamp.html). + +-> Further manipulation of incoming or outgoing values can be accomplished with the [`formatdate()` function](https://www.terraform.io/docs/configuration/functions/formatdate.html) and the [`timeadd()` function](https://www.terraform.io/docs/configuration/functions/timeadd.html). + +## Example Usage + +### Basic Usage + +{{tffile "examples/ephemeral-resources/ephemeral_static/example_1.tf"}} + +### Triggers Usage + +{{tffile "examples/ephemeral-resources/ephemeral_static/example_2.tf"}} + +## Argument Reference + +The following arguments are optional: + +* `triggers` - (Optional) Arbitrary map of values that, when changed, will trigger a new base timestamp value to be saved. See [the main provider documentation](../index.html) for more information. +* `rfc3339` - (Optional) Configure the base timestamp with an UTC [RFC3339 time string](https://tools.ietf.org/html/rfc3339#section-5.8) (`YYYY-MM-DDTHH:MM:SSZ`). Defaults to the current time. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `day` - Number day of timestamp. +* `hour` - Number hour of timestamp. +* `id` - UTC RFC3339 timestamp format, e.g. `2020-02-12T06:36:13Z`. +* `minute` - Number minute of timestamp. +* `month` - Number month of timestamp. +* `rfc3339` - UTC RFC3339 format of timestamp, e.g. `2020-02-12T06:36:13Z`. +* `second` - Number second of timestamp. +* `unix` - Number of seconds since epoch time, e.g. `1581489373`. +* `year` - Number year of timestamp. + +## Import + +This resource can be imported using the UTC RFC3339 value, e.g. + +{{codefile "shell" "examples/ephemeral-resources/ephemeral_static/import_1.sh"}} + The `triggers` argument cannot be imported. \ No newline at end of file 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 8a0d2e19..e19a80b4 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 @@ -5,10 +5,16 @@ [!unix] skip ! exec tfplugindocs validate --provider-name=terraform-provider-scaffolding --providers-schema=schema.json stderr 'Error executing command: validation errors found:' -stderr 'matching resource for documentation file \(resource2.md\) not found, file is extraneous or incorrectly named' +stderr 'matching resource for documentation file \(example2.md\) not found, file is extraneous or incorrectly named' stderr 'missing documentation file for resource: scaffolding_example' +stderr 'matching datasource for documentation file \(example2.md\) not found, file is extraneous or incorrectly named' +stderr 'missing documentation file for datasource: scaffolding_example' +stderr 'matching function for documentation file \(example2.md\) not found, file is extraneous or incorrectly named' +stderr 'missing documentation file for function: example' +stderr 'matching ephemeral resource for documentation file \(example2.md\) not found, file is extraneous or incorrectly named' +stderr 'missing documentation file for ephemeral resource: scaffolding_example' --- docs/data-sources/example.md -- +-- docs/data-sources/example2.md -- --- subcategory: "Example" page_title: "Example: example_thing" @@ -19,7 +25,29 @@ description: |- Name: {{.Name}} Type: {{.Type}} --- docs/resources/resource2.md -- +-- docs/resources/example2.md -- +--- +subcategory: "Example" +page_title: "Example: example_thing" +description: |- + Example description. +--- +# Data Fields + +Name: {{.Name}} +Type: {{.Type}} +-- docs/ephemeral-resources/example2.md -- +--- +subcategory: "Example" +page_title: "Example: example_thing" +description: |- + Example description. +--- +# Data Fields + +Name: {{.Name}} +Type: {{.Type}} +-- docs/functions/example2.md -- --- subcategory: "Example" page_title: "Example: example_thing" @@ -80,6 +108,36 @@ Type: {{.Type}} } } }, + "ephemeral_resource_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "configurable_attribute": { + "type": "string", + "description": "Example configurable attribute", + "description_kind": "markdown", + "optional": true + }, + "defaulted": { + "type": "string", + "description": "Example configurable attribute with default value", + "description_kind": "markdown", + "optional": true, + "computed": true + }, + "id": { + "type": "string", + "description": "Example identifier", + "description_kind": "markdown", + "computed": true + } + }, + "description": "Example resource", + "description_kind": "markdown" + } + } + }, "data_source_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 c87edab2..fa9df60f 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 @@ -13,6 +13,8 @@ running mixed directories check detected legacy website directory, running checks running invalid directories check on website/docs/d running file checks on website/docs/d/example.html.md +running invalid directories check on website/docs/ephemeral-resources +running file checks on website/docs/ephemeral-resources/example.html.md running invalid directories check on website/docs/functions running file checks on website/docs/functions/example.html.md running invalid directories check on website/docs/guides @@ -68,6 +70,18 @@ description: |- --- # Data Fields +Name: {{.Name}} +Type: {{.Type}} +-- website/docs/ephemeral-resources/example.html.md -- +--- +subcategory: "Example" +layout: "example" +page_title: "Example: example_thing" +description: |- + Example description. +--- +# Data Fields + Name: {{.Name}} Type: {{.Type}} -- website/docs/index.html.md -- @@ -131,6 +145,36 @@ Type: {{.Type}} } } }, + "ephemeral_resource_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "configurable_attribute": { + "type": "string", + "description": "Example configurable attribute", + "description_kind": "markdown", + "optional": true + }, + "defaulted": { + "type": "string", + "description": "Example configurable attribute with default value", + "description_kind": "markdown", + "optional": true, + "computed": true + }, + "id": { + "type": "string", + "description": "Example identifier", + "description_kind": "markdown", + "computed": true + } + }, + "description": "Example resource", + "description_kind": "markdown" + } + } + }, "data_source_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 220a8c3b..5fc21654 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 @@ -13,6 +13,8 @@ running mixed directories check detected static docs directory, running checks running invalid directories check on docs/data-sources running file checks on docs/data-sources/example.md +running invalid directories check on docs/ephemeral-resources +running file checks on docs/ephemeral-resources/example.md running invalid directories check on docs/functions running file checks on docs/functions/example.md running invalid directories check on docs/guides @@ -74,6 +76,17 @@ description: |- --- # Data Fields +Name: {{.Name}} +Type: {{.Type}} +-- docs/ephemeral-resources/example.md -- +--- +subcategory: "Example" +page_title: "Example: example_thing" +description: |- + Example description. +--- +# Data Fields + Name: {{.Name}} Type: {{.Type}} -- schema.json -- @@ -126,6 +139,36 @@ Type: {{.Type}} } } }, + "ephemeral_resource_schemas": { + "scaffolding_example": { + "version": 0, + "block": { + "attributes": { + "configurable_attribute": { + "type": "string", + "description": "Example configurable attribute", + "description_kind": "markdown", + "optional": true + }, + "defaulted": { + "type": "string", + "description": "Example configurable attribute with default value", + "description_kind": "markdown", + "optional": true, + "computed": true + }, + "id": { + "type": "string", + "description": "Example identifier", + "description_kind": "markdown", + "computed": true + } + }, + "description": "Example resource", + "description_kind": "markdown" + } + } + }, "data_source_schemas": { "scaffolding_example": { "version": 0, diff --git a/go.mod b/go.mod index 0f36e326..57fd2989 100644 --- a/go.mod +++ b/go.mod @@ -1,24 +1,25 @@ module github.com/hashicorp/terraform-plugin-docs -go 1.21 +go 1.22.7 require ( github.com/Kunde21/markdownfmt/v3 v3.1.0 - github.com/bmatcuk/doublestar/v4 v4.6.1 + github.com/bmatcuk/doublestar/v4 v4.7.1 github.com/google/go-cmp v0.6.0 github.com/hashicorp/cli v1.1.6 github.com/hashicorp/go-version v1.7.0 - github.com/hashicorp/hc-install v0.7.0 + github.com/hashicorp/hc-install v0.9.0 github.com/hashicorp/terraform-exec v0.21.0 - github.com/hashicorp/terraform-json v0.22.1 + github.com/hashicorp/terraform-json v0.23.0 github.com/mattn/go-colorable v0.1.13 - github.com/rogpeppe/go-internal v1.12.0 - github.com/yuin/goldmark v1.7.1 + github.com/rogpeppe/go-internal v1.13.1 + github.com/yuin/goldmark v1.7.7 github.com/yuin/goldmark-meta v1.1.0 - github.com/zclconf/go-cty v1.14.4 + github.com/zclconf/go-cty v1.15.0 go.abhg.dev/goldmark/frontmatter v0.2.0 golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df - golang.org/x/text v0.15.0 + golang.org/x/text v0.19.0 + gopkg.in/yaml.v3 v3.0.1 ) require ( @@ -37,6 +38,7 @@ require ( github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/huandu/xstrings v1.3.3 // indirect github.com/imdario/mergo v0.3.15 // indirect @@ -48,9 +50,8 @@ require ( github.com/shopspring/decimal v1.3.1 // indirect github.com/spf13/cast v1.5.0 // indirect golang.org/x/crypto v0.21.0 // indirect - golang.org/x/mod v0.17.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/tools v0.13.0 // indirect + golang.org/x/mod v0.21.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/tools v0.22.0 // indirect gopkg.in/yaml.v2 v2.3.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 6fb9296c..2b362738 100644 --- a/go.sum +++ b/go.sum @@ -20,8 +20,8 @@ github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= -github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0CXv75Q= +github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= @@ -58,20 +58,24 @@ github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuD github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= +github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/hc-install v0.7.0 h1:Uu9edVqjKQxxuD28mR5TikkKDd/p55S8vzPC1659aBk= -github.com/hashicorp/hc-install v0.7.0/go.mod h1:ELmmzZlGnEcqoUMKUuykHaPCIR1sYLYX+KSggWSKZuA= +github.com/hashicorp/hc-install v0.9.0 h1:2dIk8LcvANwtv3QZLckxcjyF5w8KVtiMxu6G6eLhghE= +github.com/hashicorp/hc-install v0.9.0/go.mod h1:+6vOP+mf3tuGgMApVYtmsnDoKWMDcFXeTxCACYZ8SFg= github.com/hashicorp/terraform-exec v0.21.0 h1:uNkLAe95ey5Uux6KJdua6+cv8asgILFVWkd/RG0D2XQ= github.com/hashicorp/terraform-exec v0.21.0/go.mod h1:1PPeMYou+KDUSSeRE9szMZ/oHf4fYUmB923Wzbq1ICg= -github.com/hashicorp/terraform-json v0.22.1 h1:xft84GZR0QzjPVWs4lRUwvTcPnegqlyS7orfb5Ltvec= -github.com/hashicorp/terraform-json v0.22.1/go.mod h1:JbWSQCLFSXFFhg42T7l9iJwdGXBYV8fmmD6o/ML4p3A= +github.com/hashicorp/terraform-json v0.23.0 h1:sniCkExU4iKtTADReHzACkk8fnpQXrdD2xoR+lppBkI= +github.com/hashicorp/terraform-json v0.23.0/go.mod h1:MHdXbBAbSg0GvzuWazEGKAn/cyNfIB7mN6y7KJN6y2c= github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4= github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= @@ -104,8 +108,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= @@ -125,12 +129,12 @@ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yuin/goldmark v1.7.1 h1:3bajkSilaCbjdKVsKdZjZCLBNPL9pYzrCakKaf4U49U= -github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= +github.com/yuin/goldmark v1.7.7 h1:5m9rrB1sW3JUMToKFQfb+FGt1U7r57IHu5GrYrG2nqU= +github.com/yuin/goldmark v1.7.7/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc= github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0= -github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= -github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ= +github.com/zclconf/go-cty v1.15.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= go.abhg.dev/goldmark/frontmatter v0.2.0 h1:P8kPG0YkL12+aYk2yU3xHv4tcXzeVnN+gU0tJ5JnxRw= go.abhg.dev/goldmark/frontmatter v0.2.0/go.mod h1:XqrEkZuM57djk7zrlRUB02x8I5J0px76YjkOzhB4YlU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -141,16 +145,18 @@ golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOM golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -159,8 +165,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= @@ -168,13 +174,13 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= +golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/check/directory.go b/internal/check/directory.go index 3c3183b7..15be21ca 100644 --- a/internal/check/directory.go +++ b/internal/check/directory.go @@ -6,23 +6,26 @@ package check import ( "fmt" "log" + "path" "path/filepath" ) const ( CdktfIndexDirectory = `cdktf` - LegacyIndexDirectory = `website/docs` - LegacyDataSourcesDirectory = `d` - LegacyGuidesDirectory = `guides` - LegacyResourcesDirectory = `r` - LegacyFunctionsDirectory = `functions` + LegacyIndexDirectory = `website/docs` + LegacyDataSourcesDirectory = `d` + LegacyEphemeralResourcesDirectory = `ephemeral-resources` + LegacyGuidesDirectory = `guides` + LegacyResourcesDirectory = `r` + LegacyFunctionsDirectory = `functions` - RegistryIndexDirectory = `docs` - RegistryDataSourcesDirectory = `data-sources` - RegistryGuidesDirectory = `guides` - RegistryResourcesDirectory = `resources` - RegistryFunctionsDirectory = `functions` + RegistryIndexDirectory = `docs` + RegistryDataSourcesDirectory = `data-sources` + RegistryEphemeralResourcesDirectory = `ephemeral-resources` + RegistryGuidesDirectory = `guides` + RegistryResourcesDirectory = `resources` + RegistryFunctionsDirectory = `functions` // Terraform Registry Storage Limits // https://www.terraform.io/docs/registry/providers/docs.html#storage-limits @@ -34,6 +37,7 @@ const ( var ValidLegacyDirectories = []string{ LegacyIndexDirectory, LegacyIndexDirectory + "/" + LegacyDataSourcesDirectory, + LegacyIndexDirectory + "/" + LegacyEphemeralResourcesDirectory, LegacyIndexDirectory + "/" + LegacyGuidesDirectory, LegacyIndexDirectory + "/" + LegacyResourcesDirectory, LegacyIndexDirectory + "/" + LegacyFunctionsDirectory, @@ -42,6 +46,7 @@ var ValidLegacyDirectories = []string{ var ValidRegistryDirectories = []string{ RegistryIndexDirectory, RegistryIndexDirectory + "/" + RegistryDataSourcesDirectory, + RegistryIndexDirectory + "/" + RegistryEphemeralResourcesDirectory, RegistryIndexDirectory + "/" + RegistryGuidesDirectory, RegistryIndexDirectory + "/" + RegistryResourcesDirectory, RegistryIndexDirectory + "/" + RegistryFunctionsDirectory, @@ -58,6 +63,7 @@ var ValidCdktfLanguages = []string{ var ValidLegacySubdirectories = []string{ LegacyIndexDirectory, LegacyDataSourcesDirectory, + LegacyEphemeralResourcesDirectory, LegacyGuidesDirectory, LegacyResourcesDirectory, } @@ -65,6 +71,7 @@ var ValidLegacySubdirectories = []string{ var ValidRegistrySubdirectories = []string{ RegistryIndexDirectory, RegistryDataSourcesDirectory, + RegistryEphemeralResourcesDirectory, RegistryGuidesDirectory, RegistryResourcesDirectory, } @@ -82,7 +89,7 @@ func InvalidDirectoriesCheck(dirPath string) error { return nil } - return fmt.Errorf("invalid Terraform Provider documentation directory found: %s", dirPath) + return fmt.Errorf("invalid Terraform Provider documentation directory found: %s", filepath.FromSlash(dirPath)) } @@ -92,7 +99,7 @@ func MixedDirectoriesCheck(docFiles []string) error { err := fmt.Errorf("mixed Terraform Provider documentation directory layouts found, must use only legacy or registry layout") for _, file := range docFiles { - directory := filepath.Dir(file) + directory := path.Dir(file) log.Printf("[DEBUG] Found directory: %s", directory) // Allow docs/ with other files @@ -120,7 +127,7 @@ func MixedDirectoriesCheck(docFiles []string) error { func IsValidLegacyDirectory(directory string) bool { for _, validLegacyDirectory := range ValidLegacyDirectories { - if directory == filepath.FromSlash(validLegacyDirectory) { + if directory == validLegacyDirectory { return true } } @@ -130,7 +137,7 @@ func IsValidLegacyDirectory(directory string) bool { func IsValidRegistryDirectory(directory string) bool { for _, validRegistryDirectory := range ValidRegistryDirectories { - if directory == filepath.FromSlash(validRegistryDirectory) { + if directory == validRegistryDirectory { return true } } @@ -139,32 +146,32 @@ func IsValidRegistryDirectory(directory string) bool { } func IsValidCdktfDirectory(directory string) bool { - if directory == filepath.FromSlash(fmt.Sprintf("%s/%s", LegacyIndexDirectory, CdktfIndexDirectory)) { + if directory == fmt.Sprintf("%s/%s", LegacyIndexDirectory, CdktfIndexDirectory) { return true } - if directory == filepath.FromSlash(fmt.Sprintf("%s/%s", RegistryIndexDirectory, CdktfIndexDirectory)) { + if directory == fmt.Sprintf("%s/%s", RegistryIndexDirectory, CdktfIndexDirectory) { return true } for _, validCdktfLanguage := range ValidCdktfLanguages { - if directory == filepath.FromSlash(fmt.Sprintf("%s/%s/%s", LegacyIndexDirectory, CdktfIndexDirectory, validCdktfLanguage)) { + if directory == fmt.Sprintf("%s/%s/%s", LegacyIndexDirectory, CdktfIndexDirectory, validCdktfLanguage) { return true } - if directory == filepath.FromSlash(fmt.Sprintf("%s/%s/%s", RegistryIndexDirectory, CdktfIndexDirectory, validCdktfLanguage)) { + if directory == fmt.Sprintf("%s/%s/%s", RegistryIndexDirectory, CdktfIndexDirectory, validCdktfLanguage) { return true } for _, validLegacySubdirectory := range ValidLegacySubdirectories { - if directory == filepath.FromSlash(fmt.Sprintf("%s/%s/%s/%s", LegacyIndexDirectory, CdktfIndexDirectory, validCdktfLanguage, validLegacySubdirectory)) { + if directory == fmt.Sprintf("%s/%s/%s/%s", LegacyIndexDirectory, CdktfIndexDirectory, validCdktfLanguage, validLegacySubdirectory) { return true } } for _, validRegistrySubdirectory := range ValidRegistrySubdirectories { - if directory == filepath.FromSlash(fmt.Sprintf("%s/%s/%s/%s", RegistryIndexDirectory, CdktfIndexDirectory, validCdktfLanguage, validRegistrySubdirectory)) { + if directory == fmt.Sprintf("%s/%s/%s/%s", RegistryIndexDirectory, CdktfIndexDirectory, validCdktfLanguage, validRegistrySubdirectory) { return true } } diff --git a/internal/check/directory_test.go b/internal/check/directory_test.go index 29660713..b2432de5 100644 --- a/internal/check/directory_test.go +++ b/internal/check/directory_test.go @@ -4,26 +4,108 @@ package check import ( - "os" - "path/filepath" + "io/fs" "testing" + "testing/fstest" "github.com/bmatcuk/doublestar/v4" ) -var DocumentationGlobPattern = `{docs/index.md,docs/{,cdktf/}{data-sources,guides,resources,functions}/**/*,website/docs/**/*}` +var DocumentationGlobPattern = `{docs/index.*,docs/{,cdktf/}{data-sources,ephemeral-resources,guides,resources,functions}/**/*,website/docs/**/*}` func TestMixedDirectoriesCheck(t *testing.T) { t.Parallel() testCases := map[string]struct { - BasePath string + ProviderFS fs.FS ExpectError bool }{ "valid mixed directories": { - BasePath: filepath.Join("testdata", "valid-mixed-directories"), + ProviderFS: fstest.MapFS{ + "docs/nonregistrydocs/thing.md": {}, + "website/docs/index.md": {}, + }, }, - "invalid mixed directories": { - BasePath: filepath.Join("testdata", "invalid-mixed-directories"), + "valid mixed directories - cdktf": { + ProviderFS: fstest.MapFS{ + "docs/cdktf/typescript/index.md": {}, + "website/docs/index.md": {}, + }, + }, + "invalid mixed directories - registry data source": { + ProviderFS: fstest.MapFS{ + "docs/data-sources/invalid.md": {}, + "website/docs/index.md": {}, + }, + ExpectError: true, + }, + "invalid mixed directories - registry ephemeral resource": { + ProviderFS: fstest.MapFS{ + "docs/ephemeral-resources/invalid.md": {}, + "website/docs/index.md": {}, + }, + ExpectError: true, + }, + "invalid mixed directories - registry resource": { + ProviderFS: fstest.MapFS{ + "docs/resources/invalid.md": {}, + "website/docs/index.md": {}, + }, + ExpectError: true, + }, + "invalid mixed directories - registry guide": { + ProviderFS: fstest.MapFS{ + "docs/guides/invalid.md": {}, + "website/docs/index.md": {}, + }, + ExpectError: true, + }, + "invalid mixed directories - registry function": { + ProviderFS: fstest.MapFS{ + "docs/functions/invalid.md": {}, + "website/docs/index.md": {}, + }, + ExpectError: true, + }, + "invalid mixed directories - legacy data source": { + ProviderFS: fstest.MapFS{ + "website/docs/d/invalid.html.markdown": {}, + "docs/resources/thing.md": {}, + }, + ExpectError: true, + }, + "invalid mixed directories - legacy ephemeral resource": { + ProviderFS: fstest.MapFS{ + "website/docs/ephemeral-resources/invalid.html.markdown": {}, + "docs/resources/thing.md": {}, + }, + ExpectError: true, + }, + "invalid mixed directories - legacy resource": { + ProviderFS: fstest.MapFS{ + "website/docs/r/invalid.html.markdown": {}, + "docs/resources/thing.md": {}, + }, + ExpectError: true, + }, + "invalid mixed directories - legacy guide": { + ProviderFS: fstest.MapFS{ + "website/docs/guides/invalid.html.markdown": {}, + "docs/resources/thing.md": {}, + }, + ExpectError: true, + }, + "invalid mixed directories - legacy function": { + ProviderFS: fstest.MapFS{ + "website/docs/functions/invalid.html.markdown": {}, + "docs/resources/thing.md": {}, + }, + ExpectError: true, + }, + "invalid mixed directories - legacy index": { + ProviderFS: fstest.MapFS{ + "website/docs/index.html.markdown": {}, + "docs/resources/thing.md": {}, + }, ExpectError: true, }, } @@ -34,9 +116,7 @@ func TestMixedDirectoriesCheck(t *testing.T) { t.Run(name, func(t *testing.T) { t.Parallel() - providerFs := os.DirFS(testCase.BasePath) - - files, err := doublestar.Glob(providerFs, DocumentationGlobPattern) + files, err := doublestar.Glob(testCase.ProviderFS, DocumentationGlobPattern) if err != nil { t.Fatalf("error finding documentation files: %s", err) } diff --git a/internal/check/file.go b/internal/check/file.go index cb079b3a..5cf94b11 100644 --- a/internal/check/file.go +++ b/internal/check/file.go @@ -5,8 +5,8 @@ package check import ( "fmt" + "io/fs" "log" - "os" "path/filepath" ) @@ -23,14 +23,14 @@ func (opts *FileOptions) FullPath(path string) string { } // FileSizeCheck verifies that documentation file is below the Terraform Registry storage limit. -func FileSizeCheck(fullpath string) error { - fi, err := os.Stat(fullpath) +func FileSizeCheck(providerFs fs.FS, path string) error { + fi, err := fs.Stat(providerFs, path) if err != nil { return err } - log.Printf("[DEBUG] File %s size: %d (limit: %d)", fullpath, fi.Size(), RegistryMaximumSizeOfFile) + log.Printf("[DEBUG] File %s size: %d (limit: %d)", path, fi.Size(), RegistryMaximumSizeOfFile) if fi.Size() >= int64(RegistryMaximumSizeOfFile) { return fmt.Errorf("exceeded maximum (%d) size of documentation file for Terraform Registry: %d", RegistryMaximumSizeOfFile, fi.Size()) } diff --git a/internal/check/file_extension.go b/internal/check/file_extension.go index dd5f37b6..7ca7b20f 100644 --- a/internal/check/file_extension.go +++ b/internal/check/file_extension.go @@ -30,7 +30,7 @@ var ValidRegistryFileExtensions = []string{ // FileExtensionCheck checks if the file extension of the given path is valid. func FileExtensionCheck(path string, validExtensions []string) error { if !FilePathEndsWithExtensionFrom(path, validExtensions) { - return fmt.Errorf("file does not end with a valid extension, valid extensions: %v", ValidLegacyFileExtensions) + return fmt.Errorf("file does not end with a valid extension, valid extensions: %v", validExtensions) } return nil diff --git a/internal/check/file_mismatch.go b/internal/check/file_mismatch.go index d65989fd..c53827d7 100644 --- a/internal/check/file_mismatch.go +++ b/internal/check/file_mismatch.go @@ -28,6 +28,8 @@ type FileMismatchOptions struct { FunctionEntries []os.DirEntry + EphemeralResourceEntries []os.DirEntry + Schema *tfjson.ProviderSchema } @@ -74,6 +76,11 @@ func (check *FileMismatchCheck) Run() error { result = errors.Join(result, err) } + if check.Options.EphemeralResourceEntries != nil { + err := check.ResourceFileMismatchCheck(check.Options.EphemeralResourceEntries, "ephemeral resource", check.Options.Schema.EphemeralResourceSchemas) + result = errors.Join(result, err) + } + return result } diff --git a/internal/check/file_test.go b/internal/check/file_test.go index c8ec7b8b..d29a7e7f 100644 --- a/internal/check/file_test.go +++ b/internal/check/file_test.go @@ -4,26 +4,40 @@ package check import ( - "os" + "io/fs" "path/filepath" "testing" + "testing/fstest" ) func TestFileSizeCheck(t *testing.T) { t.Parallel() testCases := map[string]struct { + FileSystem fs.FS Size int64 ExpectError bool }{ "under limit": { - Size: RegistryMaximumSizeOfFile - 1, + FileSystem: fstest.MapFS{ + "file.md": { + Data: make([]byte, RegistryMaximumSizeOfFile-1), + }, + }, }, "on limit": { - Size: RegistryMaximumSizeOfFile, + FileSystem: fstest.MapFS{ + "file.md": { + Data: make([]byte, RegistryMaximumSizeOfFile), + }, + }, ExpectError: true, }, "over limit": { - Size: RegistryMaximumSizeOfFile + 1, + FileSystem: fstest.MapFS{ + "file.md": { + Data: make([]byte, RegistryMaximumSizeOfFile+1), + }, + }, ExpectError: true, }, } @@ -34,15 +48,7 @@ func TestFileSizeCheck(t *testing.T) { t.Run(name, func(t *testing.T) { t.Parallel() - file, _ := os.CreateTemp(t.TempDir(), "TestFileSizeCheck") - - defer file.Close() - - if err := file.Truncate(testCase.Size); err != nil { - t.Fatalf("error writing temporary file: %s", err) - } - - got := FileSizeCheck(file.Name()) + got := FileSizeCheck(testCase.FileSystem, "file.md") if got == nil && testCase.ExpectError { t.Errorf("expected error, got no error") diff --git a/internal/check/provider_file.go b/internal/check/provider_file.go index 5358b669..cae52a9b 100644 --- a/internal/check/provider_file.go +++ b/internal/check/provider_file.go @@ -5,8 +5,9 @@ package check import ( "fmt" + "io/fs" "log" - "os" + "path/filepath" ) type ProviderFileOptions struct { @@ -17,12 +18,14 @@ type ProviderFileOptions struct { } type ProviderFileCheck struct { - Options *ProviderFileOptions + Options *ProviderFileOptions + ProviderFs fs.FS } -func NewProviderFileCheck(opts *ProviderFileOptions) *ProviderFileCheck { +func NewProviderFileCheck(providerFs fs.FS, opts *ProviderFileOptions) *ProviderFileCheck { check := &ProviderFileCheck{ - Options: opts, + Options: opts, + ProviderFs: providerFs, } if check.Options == nil { @@ -46,21 +49,21 @@ func (check *ProviderFileCheck) Run(path string) error { log.Printf("[DEBUG] Checking file: %s", fullpath) if err := FileExtensionCheck(path, check.Options.ValidExtensions); err != nil { - return fmt.Errorf("%s: error checking file extension: %w", path, err) + return fmt.Errorf("%s: error checking file extension: %w", filepath.FromSlash(path), err) } - if err := FileSizeCheck(fullpath); err != nil { - return fmt.Errorf("%s: error checking file size: %w", path, err) + if err := FileSizeCheck(check.ProviderFs, path); err != nil { + return fmt.Errorf("%s: error checking file size: %w", filepath.FromSlash(path), err) } - content, err := os.ReadFile(fullpath) + content, err := fs.ReadFile(check.ProviderFs, path) if err != nil { - return fmt.Errorf("%s: error reading file: %w", path, err) + return fmt.Errorf("%s: error reading file: %w", filepath.FromSlash(path), err) } if err := NewFrontMatterCheck(check.Options.FrontMatter).Run(content); err != nil { - return fmt.Errorf("%s: error checking file frontmatter: %w", path, err) + return fmt.Errorf("%s: error checking file frontmatter: %w", filepath.FromSlash(path), err) } return nil diff --git a/internal/check/testdata/invalid-mixed-directories/docs/resources/thing.md b/internal/check/testdata/invalid-mixed-directories/docs/resources/thing.md deleted file mode 100644 index 59bb04cc..00000000 --- a/internal/check/testdata/invalid-mixed-directories/docs/resources/thing.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -subcategory: "Example" -layout: "example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Resource: example_thing - -Byline. - -## Example Usage - -```terraform -resource "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/check/testdata/invalid-mixed-directories/website/docs/r/thing.html.markdown b/internal/check/testdata/invalid-mixed-directories/website/docs/r/thing.html.markdown deleted file mode 100644 index e69de29b..00000000 diff --git a/internal/check/testdata/valid-mixed-directories/docs/CONTRIBUTING.md b/internal/check/testdata/valid-mixed-directories/docs/CONTRIBUTING.md deleted file mode 100644 index 423305c4..00000000 --- a/internal/check/testdata/valid-mixed-directories/docs/CONTRIBUTING.md +++ /dev/null @@ -1,3 +0,0 @@ -# Contributing Guide - -This file has contents and no YAML frontmatter, because it is not a Terraform Provider documentation file and that is okay. diff --git a/internal/check/testdata/valid-mixed-directories/docs/nonregistrydocs/valid.md b/internal/check/testdata/valid-mixed-directories/docs/nonregistrydocs/valid.md deleted file mode 100644 index a7f1fce5..00000000 --- a/internal/check/testdata/valid-mixed-directories/docs/nonregistrydocs/valid.md +++ /dev/null @@ -1,3 +0,0 @@ -# Valid - -Files in `/docs`, but outside Registry documentation directories, should be ignored. diff --git a/internal/check/testdata/valid-mixed-directories/website/docs/r/thing.html.markdown b/internal/check/testdata/valid-mixed-directories/website/docs/r/thing.html.markdown deleted file mode 100644 index 59bb04cc..00000000 --- a/internal/check/testdata/valid-mixed-directories/website/docs/r/thing.html.markdown +++ /dev/null @@ -1,27 +0,0 @@ ---- -subcategory: "Example" -layout: "example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Resource: example_thing - -Byline. - -## Example Usage - -```terraform -resource "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/mdplain/mdplain_test.go b/internal/mdplain/mdplain_test.go index 9bf6dcfd..e4c77211 100644 --- a/internal/mdplain/mdplain_test.go +++ b/internal/mdplain/mdplain_test.go @@ -32,7 +32,7 @@ func TestPlainMarkdown(t *testing.T) { return } if !cmp.Equal(expected, actual) { - t.Errorf(cmp.Diff(expected, actual)) + t.Error(cmp.Diff(expected, actual)) } } diff --git a/internal/provider/generate.go b/internal/provider/generate.go index d0c3c965..7df7b63d 100644 --- a/internal/provider/generate.go +++ b/internal/provider/generate.go @@ -58,6 +58,14 @@ var ( "functions/%s.html.markdown", "functions/%s.html.md", } + websiteEphemeralResourceFile = "ephemeral-resources/%s.md.tmpl" + websiteEphemeralResourceFallbackFile = "ephemeral-resources.md.tmpl" + websiteEphemeralResourceFileStaticCandidates = []string{ + "ephemeral-resources/%s.md", + "ephemeral-resources/%s.markdown", + "ephemeral-resources/%s.html.markdown", + "ephemeral-resources/%s.html.md", + } websiteProviderFile = "index.md.tmpl" websiteProviderFileStaticCandidates = []string{ "index.markdown", @@ -71,6 +79,7 @@ var ( "guides", "resources", "functions", + "ephemeral-resources", } managedWebsiteFiles = []string{ @@ -372,6 +381,42 @@ func (g *generator) generateMissingFunctionTemplate(functionName string) error { return nil } +func (g *generator) generateMissingEphemeralResourceTemplate(resourceName string) error { + templatePath := fmt.Sprintf(websiteEphemeralResourceFile, resourceShortName(resourceName, g.providerName)) + templatePath = filepath.Join(g.TempTemplatesDir(), templatePath) + if fileExists(templatePath) { + g.infof("ephemeral resource %q template exists, skipping", resourceName) + return nil + } + + fallbackTemplatePath := filepath.Join(g.TempTemplatesDir(), websiteEphemeralResourceFallbackFile) + if fileExists(fallbackTemplatePath) { + g.infof("ephemeral 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 websiteEphemeralResourceFileStaticCandidates { + candidatePath := fmt.Sprintf(candidate, resourceShortName(resourceName, g.providerName)) + candidatePath = filepath.Join(g.TempTemplatesDir(), candidatePath) + if fileExists(candidatePath) { + g.infof("ephemeral 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) { @@ -433,6 +478,18 @@ func (g *generator) generateMissingTemplates(providerSchema *tfjson.ProviderSche } } + g.infof("generating missing ephemeral resource content") + for name, schema := range providerSchema.EphemeralResourceSchemas { + if g.ignoreDeprecated && schema.Block.Deprecated { + continue + } + + err := g.generateMissingEphemeralResourceTemplate(name) + if err != nil { + return fmt.Errorf("unable to generate template for ephemeral resource %q: %w", name, err) + } + } + g.infof("generating missing provider content") err := g.generateMissingProviderTemplate() if err != nil { @@ -494,8 +551,11 @@ 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, and function templates - if relDir == "" && (relFile == "resources.md.tmpl" || relFile == "data-sources.md.tmpl" || relFile == "functions.md.tmpl") { + // skip special top-level generic resource, data source, function, and ephemeral resource templates + if relDir == "" && (relFile == "resources.md.tmpl" || + relFile == "data-sources.md.tmpl" || + relFile == "functions.md.tmpl" || + relFile == "ephemeral-resources.md.tmpl") { return nil } @@ -579,6 +639,23 @@ func (g *generator) renderStaticWebsite(providerSchema *tfjson.ProviderSchema) e } g.warnf("function entitled %q does not exist", funcName) + case "ephemeral-resources/": + resSchema, resName := resourceSchema(providerSchema.EphemeralResourceSchemas, shortName, relFile) + exampleFilePath := filepath.Join(g.ProviderExamplesDir(), "ephemeral-resources", resName, "ephemeral-resource.tf") + + if resSchema != nil { + tmpl := resourceTemplate(tmplData) + render, err := tmpl.Render(g.providerDir, resName, g.providerName, g.renderedProviderName, "Ephemeral Resource", exampleFilePath, "", resSchema) + if err != nil { + return fmt.Errorf("unable to render ephemeral 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("ephemeral resource entitled %q, or %q does not exist", shortName, resName) case "": // provider if relFile == "index.md.tmpl" { tmpl := providerTemplate(tmplData) diff --git a/internal/provider/migrate.go b/internal/provider/migrate.go index babe2127..9abd7734 100644 --- a/internal/provider/migrate.go +++ b/internal/provider/migrate.go @@ -105,7 +105,7 @@ func (m *migrator) Migrate() error { if d.IsDir() { switch d.Name() { case "d", "data-sources": //data-sources - m.infof("migrating data-sources directory: %s", d.Name()) + m.infof("migrating datasources directory: %s", d.Name()) err := filepath.WalkDir(path, m.MigrateTemplate("data-sources")) if err != nil { return err @@ -119,12 +119,19 @@ func (m *migrator) Migrate() error { } return filepath.SkipDir case "functions": - m.infof("migrating functons directory: %s", d.Name()) + m.infof("migrating functions directory: %s", d.Name()) err := filepath.WalkDir(path, m.MigrateTemplate("functions")) if err != nil { return err } return filepath.SkipDir + case "ephemeral-resources": + m.infof("migrating ephemeral resources directory: %s", d.Name()) + err := filepath.WalkDir(path, m.MigrateTemplate("ephemeral-resources")) + if err != nil { + return err + } + return filepath.SkipDir case "guides": m.infof("copying guides directory: %s", d.Name()) err := cp(path, filepath.Join(m.ProviderTemplatesDir(), "guides")) diff --git a/internal/provider/testdata/invalid-legacy-directories/website/docs/r/invalid/thing.html.markdown b/internal/provider/testdata/invalid-legacy-directories/website/docs/r/invalid/thing.html.markdown deleted file mode 100644 index 59bb04cc..00000000 --- a/internal/provider/testdata/invalid-legacy-directories/website/docs/r/invalid/thing.html.markdown +++ /dev/null @@ -1,27 +0,0 @@ ---- -subcategory: "Example" -layout: "example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Resource: example_thing - -Byline. - -## Example Usage - -```terraform -resource "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/invalid-legacy-files/data_source_invalid_extension.txt b/internal/provider/testdata/invalid-legacy-files/data_source_invalid_extension.txt deleted file mode 100644 index caee79a4..00000000 --- a/internal/provider/testdata/invalid-legacy-files/data_source_invalid_extension.txt +++ /dev/null @@ -1,27 +0,0 @@ ---- -subcategory: "Example" -layout: "example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Data Source: example_thing - -Byline. - -## Example Usage - -```terraform -data "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/invalid-legacy-files/data_source_invalid_frontmatter.html.markdown b/internal/provider/testdata/invalid-legacy-files/data_source_invalid_frontmatter.html.markdown deleted file mode 100644 index 1cb8750a..00000000 --- a/internal/provider/testdata/invalid-legacy-files/data_source_invalid_frontmatter.html.markdown +++ /dev/null @@ -1,27 +0,0 @@ ---- -subcategory: "Example" -layout: "example" -page_title: "Example: example_thing" -description: |- -Missing indentation. ---- - -# Data Source: example_thing - -Byline. - -## Example Usage - -```terraform -data "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/invalid-legacy-files/data_source_with_sidebar_current.html.markdown b/internal/provider/testdata/invalid-legacy-files/data_source_with_sidebar_current.html.markdown deleted file mode 100644 index 510d48ae..00000000 --- a/internal/provider/testdata/invalid-legacy-files/data_source_with_sidebar_current.html.markdown +++ /dev/null @@ -1,28 +0,0 @@ ---- -subcategory: "Example" -sidebar_current: "example_thing" -layout: "example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Data Source: example_thing - -Byline. - -## Example Usage - -```terraform -data "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/invalid-legacy-files/data_source_without_layout.html.markdown b/internal/provider/testdata/invalid-legacy-files/data_source_without_layout.html.markdown deleted file mode 100644 index 688fa598..00000000 --- a/internal/provider/testdata/invalid-legacy-files/data_source_without_layout.html.markdown +++ /dev/null @@ -1,26 +0,0 @@ ---- -subcategory: "Example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Data Source: example_thing - -Byline. - -## Example Usage - -```terraform -data "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/invalid-legacy-files/guide_invalid_extension.txt b/internal/provider/testdata/invalid-legacy-files/guide_invalid_extension.txt deleted file mode 100644 index b02bcc8e..00000000 --- a/internal/provider/testdata/invalid-legacy-files/guide_invalid_extension.txt +++ /dev/null @@ -1,11 +0,0 @@ ---- -subcategory: "Example" -layout: "example" -page_title: "Example Guide" -description: |- - Example description. ---- - -# Example Guide - -Example contents. diff --git a/internal/provider/testdata/invalid-legacy-files/guide_invalid_frontmatter.html.markdown b/internal/provider/testdata/invalid-legacy-files/guide_invalid_frontmatter.html.markdown deleted file mode 100644 index 33997fc6..00000000 --- a/internal/provider/testdata/invalid-legacy-files/guide_invalid_frontmatter.html.markdown +++ /dev/null @@ -1,11 +0,0 @@ ---- -subcategory: "Example" -layout: "example" -page_title: "Example Guide" -description: |- -Missing indentation. ---- - -# Example Guide - -Example contents. diff --git a/internal/provider/testdata/invalid-legacy-files/guide_with_sidebar_current.html.markdown b/internal/provider/testdata/invalid-legacy-files/guide_with_sidebar_current.html.markdown deleted file mode 100644 index 5a101a3c..00000000 --- a/internal/provider/testdata/invalid-legacy-files/guide_with_sidebar_current.html.markdown +++ /dev/null @@ -1,12 +0,0 @@ ---- -subcategory: "Example" -sidebar_current: "example" -layout: "example" -page_title: "Example Guide" -description: |- - Example description. ---- - -# Example Guide - -Example contents. diff --git a/internal/provider/testdata/invalid-legacy-files/guide_without_layout.html.markdown b/internal/provider/testdata/invalid-legacy-files/guide_without_layout.html.markdown deleted file mode 100644 index 61331ef0..00000000 --- a/internal/provider/testdata/invalid-legacy-files/guide_without_layout.html.markdown +++ /dev/null @@ -1,10 +0,0 @@ ---- -subcategory: "Example" -page_title: "Example Guide" -description: |- - Example description. ---- - -# Example Guide - -Example contents. diff --git a/internal/provider/testdata/invalid-legacy-files/index_invalid_extension.txt b/internal/provider/testdata/invalid-legacy-files/index_invalid_extension.txt deleted file mode 100644 index c4ab1478..00000000 --- a/internal/provider/testdata/invalid-legacy-files/index_invalid_extension.txt +++ /dev/null @@ -1,10 +0,0 @@ ---- -layout: "example" -page_title: "Example Provider" -description: |- - Example description. ---- - -# Example Provider - -Example contents. diff --git a/internal/provider/testdata/invalid-legacy-files/index_invalid_frontmatter.html.markdown b/internal/provider/testdata/invalid-legacy-files/index_invalid_frontmatter.html.markdown deleted file mode 100644 index c4903d5a..00000000 --- a/internal/provider/testdata/invalid-legacy-files/index_invalid_frontmatter.html.markdown +++ /dev/null @@ -1,10 +0,0 @@ ---- -layout: "example" -page_title: "Example Provider" -description: |- -Missing indentation. ---- - -# Example Provider - -Example contents. diff --git a/internal/provider/testdata/invalid-legacy-files/index_with_sidebar_current.html.markdown b/internal/provider/testdata/invalid-legacy-files/index_with_sidebar_current.html.markdown deleted file mode 100644 index fe33d3f2..00000000 --- a/internal/provider/testdata/invalid-legacy-files/index_with_sidebar_current.html.markdown +++ /dev/null @@ -1,11 +0,0 @@ ---- -sidebar_current: "example" -layout: "example" -page_title: "Example Provider" -description: |- - Example description. ---- - -# Example Provider - -Example contents. diff --git a/internal/provider/testdata/invalid-legacy-files/index_with_subcategory.html.markdown b/internal/provider/testdata/invalid-legacy-files/index_with_subcategory.html.markdown deleted file mode 100644 index 9766b6df..00000000 --- a/internal/provider/testdata/invalid-legacy-files/index_with_subcategory.html.markdown +++ /dev/null @@ -1,10 +0,0 @@ ---- -subcategory: "Example" -page_title: "Example Provider" -description: |- - Example description. ---- - -# Example Provider - -Example contents. diff --git a/internal/provider/testdata/invalid-legacy-files/index_without_layout.html.markdown b/internal/provider/testdata/invalid-legacy-files/index_without_layout.html.markdown deleted file mode 100644 index 9daab155..00000000 --- a/internal/provider/testdata/invalid-legacy-files/index_without_layout.html.markdown +++ /dev/null @@ -1,9 +0,0 @@ ---- -page_title: "Example Provider" -description: |- - Example description. ---- - -# Example Provider - -Example contents. diff --git a/internal/provider/testdata/invalid-legacy-files/resource_invalid_extension.txt b/internal/provider/testdata/invalid-legacy-files/resource_invalid_extension.txt deleted file mode 100644 index 59bb04cc..00000000 --- a/internal/provider/testdata/invalid-legacy-files/resource_invalid_extension.txt +++ /dev/null @@ -1,27 +0,0 @@ ---- -subcategory: "Example" -layout: "example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Resource: example_thing - -Byline. - -## Example Usage - -```terraform -resource "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/invalid-legacy-files/resource_invalid_frontmatter.html.markdown b/internal/provider/testdata/invalid-legacy-files/resource_invalid_frontmatter.html.markdown deleted file mode 100644 index 0cd796a3..00000000 --- a/internal/provider/testdata/invalid-legacy-files/resource_invalid_frontmatter.html.markdown +++ /dev/null @@ -1,27 +0,0 @@ ---- -subcategory: "Example" -layout: "example" -page_title: "Example: example_thing" -description: |- -Missing indentation. ---- - -# Resource: example_thing - -Byline. - -## Example Usage - -```terraform -resource "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/invalid-legacy-files/resource_with_sidebar_current.html.markdown b/internal/provider/testdata/invalid-legacy-files/resource_with_sidebar_current.html.markdown deleted file mode 100644 index 32ec4684..00000000 --- a/internal/provider/testdata/invalid-legacy-files/resource_with_sidebar_current.html.markdown +++ /dev/null @@ -1,28 +0,0 @@ ---- -subcategory: "Example" -sidebar_current: "example_thing" -layout: "example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Resource: example_thing - -Byline. - -## Example Usage - -```terraform -resource "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/invalid-legacy-files/resource_without_layout.html.markdown b/internal/provider/testdata/invalid-legacy-files/resource_without_layout.html.markdown deleted file mode 100644 index aa156f35..00000000 --- a/internal/provider/testdata/invalid-legacy-files/resource_without_layout.html.markdown +++ /dev/null @@ -1,26 +0,0 @@ ---- -subcategory: "Example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Resource: example_thing - -Byline. - -## Example Usage - -```terraform -resource "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/invalid-registry-directories/docs/resources/invalid/thing.md b/internal/provider/testdata/invalid-registry-directories/docs/resources/invalid/thing.md deleted file mode 100644 index aa156f35..00000000 --- a/internal/provider/testdata/invalid-registry-directories/docs/resources/invalid/thing.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -subcategory: "Example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Resource: example_thing - -Byline. - -## Example Usage - -```terraform -resource "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/invalid-registry-files/data_source_invalid_extension.markdown b/internal/provider/testdata/invalid-registry-files/data_source_invalid_extension.markdown deleted file mode 100644 index 688fa598..00000000 --- a/internal/provider/testdata/invalid-registry-files/data_source_invalid_extension.markdown +++ /dev/null @@ -1,26 +0,0 @@ ---- -subcategory: "Example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Data Source: example_thing - -Byline. - -## Example Usage - -```terraform -data "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/invalid-registry-files/data_source_invalid_frontmatter.md b/internal/provider/testdata/invalid-registry-files/data_source_invalid_frontmatter.md deleted file mode 100644 index 224dcf7e..00000000 --- a/internal/provider/testdata/invalid-registry-files/data_source_invalid_frontmatter.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -subcategory: "Example" -page_title: "Example: example_thing" -description: |- -Missing indentation. ---- - -# Data Source: example_thing - -Byline. - -## Example Usage - -```terraform -data "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/invalid-registry-files/data_source_with_layout.md b/internal/provider/testdata/invalid-registry-files/data_source_with_layout.md deleted file mode 100644 index caee79a4..00000000 --- a/internal/provider/testdata/invalid-registry-files/data_source_with_layout.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -subcategory: "Example" -layout: "example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Data Source: example_thing - -Byline. - -## Example Usage - -```terraform -data "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/invalid-registry-files/data_source_with_sidebar_current.md b/internal/provider/testdata/invalid-registry-files/data_source_with_sidebar_current.md deleted file mode 100644 index afc1af9e..00000000 --- a/internal/provider/testdata/invalid-registry-files/data_source_with_sidebar_current.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -subcategory: "Example" -sidebar_current: "example_thing" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Data Source: example_thing - -Byline. - -## Example Usage - -```terraform -data "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/invalid-registry-files/guide_invalid_extension.markdown b/internal/provider/testdata/invalid-registry-files/guide_invalid_extension.markdown deleted file mode 100644 index 9acc401d..00000000 --- a/internal/provider/testdata/invalid-registry-files/guide_invalid_extension.markdown +++ /dev/null @@ -1,10 +0,0 @@ ---- -subcategory: "Example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Example Guide - -Example contents. diff --git a/internal/provider/testdata/invalid-registry-files/guide_invalid_frontmatter.md b/internal/provider/testdata/invalid-registry-files/guide_invalid_frontmatter.md deleted file mode 100644 index 1dbe9583..00000000 --- a/internal/provider/testdata/invalid-registry-files/guide_invalid_frontmatter.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -subcategory: "Example" -page_title: "Example: example_thing" -description: |- -Missing indentation. ---- - -# Example Guide - -Example contents. diff --git a/internal/provider/testdata/invalid-registry-files/guide_with_layout.md b/internal/provider/testdata/invalid-registry-files/guide_with_layout.md deleted file mode 100644 index ff7efb92..00000000 --- a/internal/provider/testdata/invalid-registry-files/guide_with_layout.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -subcategory: "Example" -layout: "example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Example Guide - -Example contents. diff --git a/internal/provider/testdata/invalid-registry-files/guide_with_sidebar_current.md b/internal/provider/testdata/invalid-registry-files/guide_with_sidebar_current.md deleted file mode 100644 index 1954289d..00000000 --- a/internal/provider/testdata/invalid-registry-files/guide_with_sidebar_current.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -subcategory: "Example" -sidebar_current: "example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Example Guide - -Example contents. diff --git a/internal/provider/testdata/invalid-registry-files/index_invalid_extension.markdown b/internal/provider/testdata/invalid-registry-files/index_invalid_extension.markdown deleted file mode 100644 index 9daab155..00000000 --- a/internal/provider/testdata/invalid-registry-files/index_invalid_extension.markdown +++ /dev/null @@ -1,9 +0,0 @@ ---- -page_title: "Example Provider" -description: |- - Example description. ---- - -# Example Provider - -Example contents. diff --git a/internal/provider/testdata/invalid-registry-files/index_invalid_frontmatter.md b/internal/provider/testdata/invalid-registry-files/index_invalid_frontmatter.md deleted file mode 100644 index f19cf719..00000000 --- a/internal/provider/testdata/invalid-registry-files/index_invalid_frontmatter.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -page_title: "Example Provider" -description: |- -Missing indentation. ---- - -# Example Provider - -Example contents. diff --git a/internal/provider/testdata/invalid-registry-files/index_with_layout.md b/internal/provider/testdata/invalid-registry-files/index_with_layout.md deleted file mode 100644 index c4ab1478..00000000 --- a/internal/provider/testdata/invalid-registry-files/index_with_layout.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -layout: "example" -page_title: "Example Provider" -description: |- - Example description. ---- - -# Example Provider - -Example contents. diff --git a/internal/provider/testdata/invalid-registry-files/index_with_sidebar_current.md b/internal/provider/testdata/invalid-registry-files/index_with_sidebar_current.md deleted file mode 100644 index cd0a42c5..00000000 --- a/internal/provider/testdata/invalid-registry-files/index_with_sidebar_current.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -sidebar_current: "example" -page_title: "Example Provider" -description: |- - Example description. ---- - -# Example Provider - -Example contents. diff --git a/internal/provider/testdata/invalid-registry-files/index_with_subcategory.md b/internal/provider/testdata/invalid-registry-files/index_with_subcategory.md deleted file mode 100644 index eb4751c9..00000000 --- a/internal/provider/testdata/invalid-registry-files/index_with_subcategory.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -subcategory: "example" -page_title: "Example Provider" -description: |- - Example description. ---- - -# Example Provider - -Example contents. diff --git a/internal/provider/testdata/invalid-registry-files/resource_invalid_extension.markdown b/internal/provider/testdata/invalid-registry-files/resource_invalid_extension.markdown deleted file mode 100644 index aa156f35..00000000 --- a/internal/provider/testdata/invalid-registry-files/resource_invalid_extension.markdown +++ /dev/null @@ -1,26 +0,0 @@ ---- -subcategory: "Example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Resource: example_thing - -Byline. - -## Example Usage - -```terraform -resource "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/invalid-registry-files/resource_invalid_frontmatter.md b/internal/provider/testdata/invalid-registry-files/resource_invalid_frontmatter.md deleted file mode 100644 index 39a2823b..00000000 --- a/internal/provider/testdata/invalid-registry-files/resource_invalid_frontmatter.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -subcategory: "Example" -page_title: "Example: example_thing" -description: |- -Missing indentation. ---- - -# Resource: example_thing - -Byline. - -## Example Usage - -```terraform -resource "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/invalid-registry-files/resource_with_layout.md b/internal/provider/testdata/invalid-registry-files/resource_with_layout.md deleted file mode 100644 index 59bb04cc..00000000 --- a/internal/provider/testdata/invalid-registry-files/resource_with_layout.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -subcategory: "Example" -layout: "example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Resource: example_thing - -Byline. - -## Example Usage - -```terraform -resource "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/invalid-registry-files/resource_with_sidebar_current.md b/internal/provider/testdata/invalid-registry-files/resource_with_sidebar_current.md deleted file mode 100644 index 91e6dcbb..00000000 --- a/internal/provider/testdata/invalid-registry-files/resource_with_sidebar_current.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -subcategory: "Example" -sidebar_current: "example_thing" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Resource: example_thing - -Byline. - -## Example Usage - -```terraform -resource "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/schema.json b/internal/provider/testdata/schema.json index 868bae22..48876497 100644 --- a/internal/provider/testdata/schema.json +++ b/internal/provider/testdata/schema.json @@ -34,6 +34,32 @@ } } }, + "ephemeral_resource_schemas": { + "null_ephemeral_resource": { + "version": 0, + "block": { + "attributes": { + "id": { + "type": "string", + "description": "This is set to a random value at create time.", + "description_kind": "plain", + "computed": true + }, + "triggers": { + "type": [ + "map", + "string" + ], + "description": "A map of arbitrary strings that, when changed, will force the null resource to be replaced, re-running any associated provisioners.", + "description_kind": "plain", + "optional": true + } + }, + "description": "The `null_resource` resource implements the standard resource lifecycle but takes no further action.\n\nThe `triggers` argument allows specifying an arbitrary set of values that, when changed, will cause the resource to be replaced.", + "description_kind": "plain" + } + } + }, "data_source_schemas": { "null_data_source": { "version": 0, @@ -83,6 +109,25 @@ "deprecated": true } } + }, + "functions": { + "null": { + "description": "Given a string value, returns the same value.", + "summary": "Echo a string", + "return_type": "string", + "parameters": [ + { + "name": "input", + "description": "Value to echo.", + "type": "string" + } + ], + "variadic_parameter": { + "name": "variadicInput", + "description": "Variadic input to echo.", + "type": "string" + } + } } } } diff --git a/internal/provider/testdata/valid-legacy-directories-with-cdktf/website/docs/cdktf/typescript/d/thing.html.markdown b/internal/provider/testdata/valid-legacy-directories-with-cdktf/website/docs/cdktf/typescript/d/thing.html.markdown deleted file mode 100644 index 32e9de67..00000000 --- a/internal/provider/testdata/valid-legacy-directories-with-cdktf/website/docs/cdktf/typescript/d/thing.html.markdown +++ /dev/null @@ -1,37 +0,0 @@ ---- -subcategory: "Example" -layout: "example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Data Source: example_thing - -Byline. - -## Example Usage - -```ts -import { Construct } from "construct"; -import { TerraformStack } from "cdktf"; -import { DataExample } from "./.gen/providers/example/data_example_thing"; - -class MyStack extends TerraformStack { - constructs(scope: Construct, name: string) { - super(scope, name); - - new DataExampleThing(this, "example", { - name: "example", - }); - } -} -``` - -## Argument Reference - -- `name` - (Required) Name of thing. - -## Attribute Reference - -- `id` - Name of thing. diff --git a/internal/provider/testdata/valid-legacy-directories-with-cdktf/website/docs/cdktf/typescript/r/thing.html.markdown b/internal/provider/testdata/valid-legacy-directories-with-cdktf/website/docs/cdktf/typescript/r/thing.html.markdown deleted file mode 100644 index 962ae86b..00000000 --- a/internal/provider/testdata/valid-legacy-directories-with-cdktf/website/docs/cdktf/typescript/r/thing.html.markdown +++ /dev/null @@ -1,37 +0,0 @@ ---- -subcategory: "Example" -layout: "example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Resource: example_thing - -Byline. - -## Example Usage - -```ts -import { Construct } from "construct"; -import { TerraformStack } from "cdktf"; -import { Thing } from "./.gen/providers/example/thing"; - -class MyStack extends TerraformStack { - constructs(scope: Construct, name: string) { - super(scope, name); - - new Thing(this, "example", { - name: "example", - }); - } -} -``` - -## Argument Reference - -- `name` - (Required) Name of thing. - -## Attribute Reference - -- `id` - Name of thing. diff --git a/internal/provider/testdata/valid-legacy-directories-with-cdktf/website/docs/d/thing.html.markdown b/internal/provider/testdata/valid-legacy-directories-with-cdktf/website/docs/d/thing.html.markdown deleted file mode 100644 index caee79a4..00000000 --- a/internal/provider/testdata/valid-legacy-directories-with-cdktf/website/docs/d/thing.html.markdown +++ /dev/null @@ -1,27 +0,0 @@ ---- -subcategory: "Example" -layout: "example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Data Source: example_thing - -Byline. - -## Example Usage - -```terraform -data "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/valid-legacy-directories-with-cdktf/website/docs/r/thing.html.markdown b/internal/provider/testdata/valid-legacy-directories-with-cdktf/website/docs/r/thing.html.markdown deleted file mode 100644 index 59bb04cc..00000000 --- a/internal/provider/testdata/valid-legacy-directories-with-cdktf/website/docs/r/thing.html.markdown +++ /dev/null @@ -1,27 +0,0 @@ ---- -subcategory: "Example" -layout: "example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Resource: example_thing - -Byline. - -## Example Usage - -```terraform -resource "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/valid-legacy-directories/website/docs/d/thing.html.markdown b/internal/provider/testdata/valid-legacy-directories/website/docs/d/thing.html.markdown deleted file mode 100644 index caee79a4..00000000 --- a/internal/provider/testdata/valid-legacy-directories/website/docs/d/thing.html.markdown +++ /dev/null @@ -1,27 +0,0 @@ ---- -subcategory: "Example" -layout: "example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Data Source: example_thing - -Byline. - -## Example Usage - -```terraform -data "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/valid-legacy-directories/website/docs/r/thing.html.markdown b/internal/provider/testdata/valid-legacy-directories/website/docs/r/thing.html.markdown deleted file mode 100644 index 59bb04cc..00000000 --- a/internal/provider/testdata/valid-legacy-directories/website/docs/r/thing.html.markdown +++ /dev/null @@ -1,27 +0,0 @@ ---- -subcategory: "Example" -layout: "example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Resource: example_thing - -Byline. - -## Example Usage - -```terraform -resource "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/valid-legacy-files/2.0-guide.html.markdown b/internal/provider/testdata/valid-legacy-files/2.0-guide.html.markdown deleted file mode 100644 index b02bcc8e..00000000 --- a/internal/provider/testdata/valid-legacy-files/2.0-guide.html.markdown +++ /dev/null @@ -1,11 +0,0 @@ ---- -subcategory: "Example" -layout: "example" -page_title: "Example Guide" -description: |- - Example description. ---- - -# Example Guide - -Example contents. diff --git a/internal/provider/testdata/valid-legacy-files/data_source.html.markdown b/internal/provider/testdata/valid-legacy-files/data_source.html.markdown deleted file mode 100644 index caee79a4..00000000 --- a/internal/provider/testdata/valid-legacy-files/data_source.html.markdown +++ /dev/null @@ -1,27 +0,0 @@ ---- -subcategory: "Example" -layout: "example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Data Source: example_thing - -Byline. - -## Example Usage - -```terraform -data "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/valid-legacy-files/guide.html.markdown b/internal/provider/testdata/valid-legacy-files/guide.html.markdown deleted file mode 100644 index b02bcc8e..00000000 --- a/internal/provider/testdata/valid-legacy-files/guide.html.markdown +++ /dev/null @@ -1,11 +0,0 @@ ---- -subcategory: "Example" -layout: "example" -page_title: "Example Guide" -description: |- - Example description. ---- - -# Example Guide - -Example contents. diff --git a/internal/provider/testdata/valid-legacy-files/index.html.markdown b/internal/provider/testdata/valid-legacy-files/index.html.markdown deleted file mode 100644 index c4ab1478..00000000 --- a/internal/provider/testdata/valid-legacy-files/index.html.markdown +++ /dev/null @@ -1,10 +0,0 @@ ---- -layout: "example" -page_title: "Example Provider" -description: |- - Example description. ---- - -# Example Provider - -Example contents. diff --git a/internal/provider/testdata/valid-legacy-files/resource.html.markdown b/internal/provider/testdata/valid-legacy-files/resource.html.markdown deleted file mode 100644 index 59bb04cc..00000000 --- a/internal/provider/testdata/valid-legacy-files/resource.html.markdown +++ /dev/null @@ -1,27 +0,0 @@ ---- -subcategory: "Example" -layout: "example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Resource: example_thing - -Byline. - -## Example Usage - -```terraform -resource "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/CONTRIBUTING.md b/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/CONTRIBUTING.md deleted file mode 100644 index 423305c4..00000000 --- a/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/CONTRIBUTING.md +++ /dev/null @@ -1,3 +0,0 @@ -# Contributing Guide - -This file has contents and no YAML frontmatter, because it is not a Terraform Provider documentation file and that is okay. diff --git a/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/cdktf/typescript/CONTRIBUTING.md b/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/cdktf/typescript/CONTRIBUTING.md deleted file mode 100644 index 423305c4..00000000 --- a/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/cdktf/typescript/CONTRIBUTING.md +++ /dev/null @@ -1,3 +0,0 @@ -# Contributing Guide - -This file has contents and no YAML frontmatter, because it is not a Terraform Provider documentation file and that is okay. diff --git a/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/cdktf/typescript/data-sources/thing.md b/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/cdktf/typescript/data-sources/thing.md deleted file mode 100644 index 5c415dba..00000000 --- a/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/cdktf/typescript/data-sources/thing.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -subcategory: "Example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Data Source: example_thing - -Byline. - -## Example Usage - -```ts -import { Construct } from "construct"; -import { TerraformStack } from "cdktf"; -import { DataExample } from "./.gen/providers/example/data_example_thing"; - -class MyStack extends TerraformStack { - constructs(scope: Construct, name: string) { - super(scope, name); - - new DataExampleThing(this, "example", { - name: "example", - }); - } -} -``` - -## Argument Reference - -- `name` - (Required) Name of thing. - -## Attribute Reference - -- `id` - Name of thing. diff --git a/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/cdktf/typescript/index.md b/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/cdktf/typescript/index.md deleted file mode 100644 index 9daab155..00000000 --- a/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/cdktf/typescript/index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -page_title: "Example Provider" -description: |- - Example description. ---- - -# Example Provider - -Example contents. diff --git a/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/cdktf/typescript/nonregistrydocs/valid.md b/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/cdktf/typescript/nonregistrydocs/valid.md deleted file mode 100644 index a7f1fce5..00000000 --- a/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/cdktf/typescript/nonregistrydocs/valid.md +++ /dev/null @@ -1,3 +0,0 @@ -# Valid - -Files in `/docs`, but outside Registry documentation directories, should be ignored. diff --git a/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/cdktf/typescript/resources/thing.md b/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/cdktf/typescript/resources/thing.md deleted file mode 100644 index 1f46f48b..00000000 --- a/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/cdktf/typescript/resources/thing.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -subcategory: "Example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Resource: example_thing - -Byline. - -## Example Usage - -```ts -import { Construct } from "construct"; -import { TerraformStack } from "cdktf"; -import { Thing } from "./.gen/providers/example/thing"; - -class MyStack extends TerraformStack { - constructs(scope: Construct, name: string) { - super(scope, name); - - new Thing(this, "example", { - name: "example", - }); - } -} -``` - -## Argument Reference - -- `name` - (Required) Name of thing. - -## Attribute Reference - -- `id` - Name of thing. diff --git a/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/data-sources/thing.md b/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/data-sources/thing.md deleted file mode 100644 index 688fa598..00000000 --- a/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/data-sources/thing.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -subcategory: "Example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Data Source: example_thing - -Byline. - -## Example Usage - -```terraform -data "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/index.md b/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/index.md deleted file mode 100644 index 9daab155..00000000 --- a/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -page_title: "Example Provider" -description: |- - Example description. ---- - -# Example Provider - -Example contents. diff --git a/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/nonregistrydocs/valid.md b/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/nonregistrydocs/valid.md deleted file mode 100644 index a7f1fce5..00000000 --- a/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/nonregistrydocs/valid.md +++ /dev/null @@ -1,3 +0,0 @@ -# Valid - -Files in `/docs`, but outside Registry documentation directories, should be ignored. diff --git a/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/resources/thing.md b/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/resources/thing.md deleted file mode 100644 index aa156f35..00000000 --- a/internal/provider/testdata/valid-registry-directories-with-cdktf/docs/resources/thing.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -subcategory: "Example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Resource: example_thing - -Byline. - -## Example Usage - -```terraform -resource "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/valid-registry-directories/docs/CONTRIBUTING.md b/internal/provider/testdata/valid-registry-directories/docs/CONTRIBUTING.md deleted file mode 100644 index 423305c4..00000000 --- a/internal/provider/testdata/valid-registry-directories/docs/CONTRIBUTING.md +++ /dev/null @@ -1,3 +0,0 @@ -# Contributing Guide - -This file has contents and no YAML frontmatter, because it is not a Terraform Provider documentation file and that is okay. diff --git a/internal/provider/testdata/valid-registry-directories/docs/data-sources/thing.md b/internal/provider/testdata/valid-registry-directories/docs/data-sources/thing.md deleted file mode 100644 index 688fa598..00000000 --- a/internal/provider/testdata/valid-registry-directories/docs/data-sources/thing.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -subcategory: "Example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Data Source: example_thing - -Byline. - -## Example Usage - -```terraform -data "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/valid-registry-directories/docs/index.md b/internal/provider/testdata/valid-registry-directories/docs/index.md deleted file mode 100644 index 9daab155..00000000 --- a/internal/provider/testdata/valid-registry-directories/docs/index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -page_title: "Example Provider" -description: |- - Example description. ---- - -# Example Provider - -Example contents. diff --git a/internal/provider/testdata/valid-registry-directories/docs/nonregistrydocs/valid.md b/internal/provider/testdata/valid-registry-directories/docs/nonregistrydocs/valid.md deleted file mode 100644 index a7f1fce5..00000000 --- a/internal/provider/testdata/valid-registry-directories/docs/nonregistrydocs/valid.md +++ /dev/null @@ -1,3 +0,0 @@ -# Valid - -Files in `/docs`, but outside Registry documentation directories, should be ignored. diff --git a/internal/provider/testdata/valid-registry-directories/docs/resources/thing.md b/internal/provider/testdata/valid-registry-directories/docs/resources/thing.md deleted file mode 100644 index aa156f35..00000000 --- a/internal/provider/testdata/valid-registry-directories/docs/resources/thing.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -subcategory: "Example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Resource: example_thing - -Byline. - -## Example Usage - -```terraform -resource "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/valid-registry-files/2.0-guide.md b/internal/provider/testdata/valid-registry-files/2.0-guide.md deleted file mode 100644 index 9acc401d..00000000 --- a/internal/provider/testdata/valid-registry-files/2.0-guide.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -subcategory: "Example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Example Guide - -Example contents. diff --git a/internal/provider/testdata/valid-registry-files/data_source.md b/internal/provider/testdata/valid-registry-files/data_source.md deleted file mode 100644 index 688fa598..00000000 --- a/internal/provider/testdata/valid-registry-files/data_source.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -subcategory: "Example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Data Source: example_thing - -Byline. - -## Example Usage - -```terraform -data "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/testdata/valid-registry-files/guide.md b/internal/provider/testdata/valid-registry-files/guide.md deleted file mode 100644 index 9acc401d..00000000 --- a/internal/provider/testdata/valid-registry-files/guide.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -subcategory: "Example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Example Guide - -Example contents. diff --git a/internal/provider/testdata/valid-registry-files/index.md b/internal/provider/testdata/valid-registry-files/index.md deleted file mode 100644 index 9daab155..00000000 --- a/internal/provider/testdata/valid-registry-files/index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -page_title: "Example Provider" -description: |- - Example description. ---- - -# Example Provider - -Example contents. diff --git a/internal/provider/testdata/valid-registry-files/resource.md b/internal/provider/testdata/valid-registry-files/resource.md deleted file mode 100644 index aa156f35..00000000 --- a/internal/provider/testdata/valid-registry-files/resource.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -subcategory: "Example" -page_title: "Example: example_thing" -description: |- - Example description. ---- - -# Resource: example_thing - -Byline. - -## Example Usage - -```terraform -resource "example_thing" "example" { - name = "example" -} -``` - -## Argument Reference - -* `name` - (Required) Name of thing. - -## Attribute Reference - -* `id` - Name of thing. diff --git a/internal/provider/util_test.go b/internal/provider/util_test.go index 95e59b84..0e04f13e 100644 --- a/internal/provider/util_test.go +++ b/internal/provider/util_test.go @@ -106,11 +106,19 @@ func Test_extractSchemaFromFile(t *testing.T) { if providerSchema.DataSourceSchemas["null_data_source"] == nil { t.Fatalf("null_data_source not found") } + if providerSchema.Functions["null"] == nil { + t.Fatalf("null function not found") + } + if providerSchema.EphemeralResourceSchemas["null_ephemeral_resource"] == nil { + t.Fatalf("null_ephemeral_resource not found") + } if providerSchema.ResourceSchemas["null_resource"].Block.Attributes["id"] == nil { t.Fatalf("null_resoruce id attribute not found") } if providerSchema.DataSourceSchemas["null_data_source"].Block.Attributes["id"] == nil { t.Fatalf("null_data_source id attribute not found") } - + if providerSchema.EphemeralResourceSchemas["null_ephemeral_resource"].Block.Attributes["id"] == nil { + t.Fatalf("null_ephemeral_resoruce id attribute not found") + } } diff --git a/internal/provider/validate.go b/internal/provider/validate.go index a72be373..0ba0fd21 100644 --- a/internal/provider/validate.go +++ b/internal/provider/validate.go @@ -7,6 +7,7 @@ import ( "context" "errors" "fmt" + "io/fs" "log" "os" "path/filepath" @@ -24,8 +25,8 @@ const ( FileExtensionMarkdown = `.markdown` FileExtensionMd = `.md` - DocumentationGlobPattern = `{docs/index.md,docs/{,cdktf/}{data-sources,guides,resources,functions}/**/*,website/docs/**/*}` - DocumentationDirGlobPattern = `{docs/{,cdktf/}{data-sources,guides,resources,functions}{,/*},website/docs/**/*}` + DocumentationGlobPattern = `{docs/index.*,docs/{,cdktf/}{data-sources,ephemeral-resources,guides,resources,functions}/**/*,website/docs/**/*}` + DocumentationDirGlobPattern = `{docs/{,cdktf/}{data-sources,ephemeral-resources,guides,resources,functions}{,/*},website/docs/**/*}` ) var ValidLegacyFileExtensions = []string{ @@ -54,13 +55,6 @@ var LegacyIndexFrontMatterOptions = &check.FrontMatterOptions{ RequirePageTitle: true, } -var LegacyGuideFrontMatterOptions = &check.FrontMatterOptions{ - NoSidebarCurrent: true, - RequireDescription: true, - RequireLayout: true, - RequirePageTitle: true, -} - var RegistryFrontMatterOptions = &check.FrontMatterOptions{ NoLayout: true, NoSidebarCurrent: true, @@ -81,6 +75,7 @@ var RegistryGuideFrontMatterOptions = &check.FrontMatterOptions{ type validator struct { providerName string providerDir string + providerFS fs.FS providersSchemaPath string tfVersion string @@ -120,9 +115,12 @@ func Validate(ui cli.Ui, providerDir, providerName, providersSchemaPath, tfversi return fmt.Errorf("expected %q to be a directory", providerDir) } + providerFs := os.DirFS(providerDir) + v := &validator{ providerName: providerName, providerDir: providerDir, + providerFS: providerFs, providersSchemaPath: providersSchemaPath, tfVersion: tfversion, @@ -157,9 +155,7 @@ func (v *validator) validate(ctx context.Context) error { } } - providerFs := os.DirFS(v.providerDir) - - files, globErr := doublestar.Glob(providerFs, DocumentationGlobPattern) + files, globErr := doublestar.Glob(v.providerFS, DocumentationGlobPattern) if globErr != nil { return fmt.Errorf("error finding documentation files: %w", err) } @@ -170,43 +166,39 @@ func (v *validator) validate(ctx context.Context) error { err = check.MixedDirectoriesCheck(files) result = errors.Join(result, err) - if dirExists(filepath.Join(v.providerDir, "docs")) { + if dirExists(v.providerFS, "docs") { v.logger.infof("detected static docs directory, running checks") - err = v.validateStaticDocs(filepath.Join(v.providerDir, "docs")) + err = v.validateStaticDocs() result = errors.Join(result, err) } - if dirExists(filepath.Join(v.providerDir, filepath.Join("website", "docs"))) { + if dirExists(v.providerFS, "website/docs") { v.logger.infof("detected legacy website directory, running checks") - err = v.validateLegacyWebsite(filepath.Join(v.providerDir, "website/docs")) + err = v.validateLegacyWebsite() result = errors.Join(result, err) } return result } -func (v *validator) validateStaticDocs(dir string) error { - +func (v *validator) validateStaticDocs() error { + dir := "docs" var result error options := &check.ProviderFileOptions{ + FileOptions: &check.FileOptions{BasePath: v.providerDir}, FrontMatter: RegistryFrontMatterOptions, ValidExtensions: ValidRegistryFileExtensions, } var files []string - err := filepath.WalkDir(dir, func(path string, d os.DirEntry, err error) error { + err := fs.WalkDir(v.providerFS, dir, func(path string, d fs.DirEntry, err error) error { if err != nil { return fmt.Errorf("error walking directory %q: %w", dir, err) } - - rel, err := filepath.Rel(v.providerDir, path) - if err != nil { - return err - } if d.IsDir() { - match, err := doublestar.PathMatch(filepath.FromSlash(DocumentationDirGlobPattern), rel) + match, err := doublestar.Match(DocumentationDirGlobPattern, path) if err != nil { return err } @@ -214,11 +206,11 @@ func (v *validator) validateStaticDocs(dir string) error { return nil // skip valid non-documentation directories } - v.logger.infof("running invalid directories check on %s", rel) - result = errors.Join(result, check.InvalidDirectoriesCheck(rel)) + v.logger.infof("running invalid directories check on %s", path) + result = errors.Join(result, check.InvalidDirectoriesCheck(path)) return nil } - match, err := doublestar.PathMatch(filepath.FromSlash(DocumentationGlobPattern), rel) + match, err := doublestar.Match(DocumentationGlobPattern, path) if err != nil { return err } @@ -227,15 +219,15 @@ func (v *validator) validateStaticDocs(dir string) error { } // Configure FrontMatterOptions based on file type - if d.Name() == "index.md" { + if removeAllExt(d.Name()) == "index" { options.FrontMatter = RegistryIndexFrontMatterOptions - } else if _, relErr := filepath.Rel(rel, "guides"); relErr != nil { + } else if _, relErr := filepath.Rel(dir+"/guides", path); relErr == nil { options.FrontMatter = RegistryGuideFrontMatterOptions } else { options.FrontMatter = RegistryFrontMatterOptions } - v.logger.infof("running file checks on %s", rel) - result = errors.Join(result, check.NewProviderFileCheck(options).Run(path)) + v.logger.infof("running file checks on %s", path) + result = errors.Join(result, check.NewProviderFileCheck(v.providerFS, options).Run(path)) files = append(files, path) return nil @@ -249,18 +241,22 @@ func (v *validator) validateStaticDocs(dir string) error { Schema: v.providerSchema, } - if dirExists(filepath.Join(dir, "data-sources")) { - dataSourceFiles, _ := os.ReadDir(filepath.Join(dir, "data-sources")) + if dirExists(v.providerFS, dir+"/data-sources") { + dataSourceFiles, _ := fs.ReadDir(v.providerFS, dir+"/data-sources") mismatchOpt.DatasourceEntries = dataSourceFiles } - if dirExists(filepath.Join(dir, "resources")) { - resourceFiles, _ := os.ReadDir(filepath.Join(dir, "resources")) + if dirExists(v.providerFS, dir+"/resources") { + resourceFiles, _ := fs.ReadDir(v.providerFS, dir+"/resources") mismatchOpt.ResourceEntries = resourceFiles } - if dirExists(filepath.Join(dir, "functions")) { - functionFiles, _ := os.ReadDir(filepath.Join(dir, "functions")) + if dirExists(v.providerFS, dir+"/functions") { + functionFiles, _ := fs.ReadDir(v.providerFS, dir+"/functions") mismatchOpt.FunctionEntries = functionFiles } + if dirExists(v.providerFS, dir+"/ephemeral-resources") { + ephemeralResourceFiles, _ := fs.ReadDir(v.providerFS, dir+"/ephemeral-resources") + mismatchOpt.EphemeralResourceEntries = ephemeralResourceFiles + } v.logger.infof("running file mismatch check") if err := check.NewFileMismatchCheck(mismatchOpt).Run(); err != nil { @@ -270,27 +266,23 @@ func (v *validator) validateStaticDocs(dir string) error { return result } -func (v *validator) validateLegacyWebsite(dir string) error { - +func (v *validator) validateLegacyWebsite() error { + dir := "website/docs" var result error options := &check.ProviderFileOptions{ + FileOptions: &check.FileOptions{BasePath: v.providerDir}, FrontMatter: LegacyFrontMatterOptions, ValidExtensions: ValidLegacyFileExtensions, } var files []string - err := filepath.WalkDir(dir, func(path string, d os.DirEntry, err error) error { + err := fs.WalkDir(v.providerFS, dir, func(path string, d fs.DirEntry, err error) error { if err != nil { return fmt.Errorf("error walking directory %q: %w", dir, err) } - - rel, err := filepath.Rel(v.providerDir, path) - if err != nil { - return err - } if d.IsDir() { - match, err := doublestar.PathMatch(filepath.FromSlash(DocumentationDirGlobPattern), rel) + match, err := doublestar.Match(DocumentationDirGlobPattern, path) if err != nil { return err } @@ -298,12 +290,12 @@ func (v *validator) validateLegacyWebsite(dir string) error { return nil // skip valid non-documentation directories } - v.logger.infof("running invalid directories check on %s", rel) - result = errors.Join(result, check.InvalidDirectoriesCheck(rel)) + v.logger.infof("running invalid directories check on %s", path) + result = errors.Join(result, check.InvalidDirectoriesCheck(path)) return nil } - match, err := doublestar.PathMatch(filepath.FromSlash(DocumentationGlobPattern), rel) + match, err := doublestar.Match(DocumentationGlobPattern, path) if err != nil { return err } @@ -312,15 +304,13 @@ func (v *validator) validateLegacyWebsite(dir string) error { } // Configure FrontMatterOptions based on file type - if d.Name() == "index.md" { + if removeAllExt(d.Name()) == "index" { options.FrontMatter = LegacyIndexFrontMatterOptions - } else if _, relErr := filepath.Rel(rel, "guides"); relErr != nil { - options.FrontMatter = LegacyGuideFrontMatterOptions } else { options.FrontMatter = LegacyFrontMatterOptions } - v.logger.infof("running file checks on %s", rel) - result = errors.Join(result, check.NewProviderFileCheck(options).Run(path)) + v.logger.infof("running file checks on %s", path) + result = errors.Join(result, check.NewProviderFileCheck(v.providerFS, options).Run(path)) files = append(files, path) return nil @@ -334,18 +324,22 @@ func (v *validator) validateLegacyWebsite(dir string) error { Schema: v.providerSchema, } - if dirExists(filepath.Join(dir, "d")) { - dataSourceFiles, _ := os.ReadDir(filepath.Join(dir, "d")) + if dirExists(v.providerFS, dir+"/d") { + dataSourceFiles, _ := fs.ReadDir(v.providerFS, dir+"/d") mismatchOpt.DatasourceEntries = dataSourceFiles } - if dirExists(filepath.Join(dir, "r")) { - resourceFiles, _ := os.ReadDir(filepath.Join(dir, "r")) + if dirExists(v.providerFS, dir+"/r") { + resourceFiles, _ := fs.ReadDir(v.providerFS, dir+"/r") mismatchOpt.ResourceEntries = resourceFiles } - if dirExists(filepath.Join(dir, "functions")) { - functionFiles, _ := os.ReadDir(filepath.Join(dir, "functions")) + if dirExists(v.providerFS, dir+"/functions") { + functionFiles, _ := fs.ReadDir(v.providerFS, dir+"/functions") mismatchOpt.FunctionEntries = functionFiles } + if dirExists(v.providerFS, dir+"/ephemeral-resources") { + ephemeralResourceFiles, _ := fs.ReadDir(v.providerFS, dir+"/ephemeral-resources") + mismatchOpt.EphemeralResourceEntries = ephemeralResourceFiles + } v.logger.infof("running file mismatch check") if err := check.NewFileMismatchCheck(mismatchOpt).Run(); err != nil { @@ -355,8 +349,8 @@ func (v *validator) validateLegacyWebsite(dir string) error { return result } -func dirExists(name string) bool { - if file, err := os.Stat(name); err != nil { +func dirExists(fileSys fs.FS, name string) bool { + if file, err := fs.Stat(fileSys, name); err != nil { return false } else if !file.IsDir() { return false diff --git a/internal/provider/validate_test.go b/internal/provider/validate_test.go index 4f087b9c..03de43a3 100644 --- a/internal/provider/validate_test.go +++ b/internal/provider/validate_test.go @@ -4,31 +4,181 @@ package provider import ( + "bytes" + "io/fs" "path/filepath" "testing" + "testing/fstest" "github.com/bmatcuk/doublestar/v4" + "github.com/google/go-cmp/cmp" "github.com/hashicorp/cli" + tfjson "github.com/hashicorp/terraform-json" + "gopkg.in/yaml.v3" ) -func TestValidateStaticDocs(t *testing.T) { +// FrontMatterData represents the YAML frontmatter of Terraform Provider documentation. +type FrontMatterData struct { + Description *string `yaml:"description,omitempty"` + Layout *string `yaml:"layout,omitempty"` + PageTitle *string `yaml:"page_title,omitempty"` + SidebarCurrent *string `yaml:"sidebar_current,omitempty"` + Subcategory *string `yaml:"subcategory,omitempty"` +} + +var exampleDescription = "Example description." +var exampleLayout = "Example Layout" +var examplePageTitle = "Example Page Title" +var exampleSidebarCurrent = "Example Sidebar Current" +var exampleSubcategory = "Example Subcategory" + +var ValidRegistryResourceFrontMatter = FrontMatterData{ + Subcategory: &exampleSubcategory, + PageTitle: &examplePageTitle, + Description: &exampleDescription, +} + +var ValidLegacyResourceFrontMatter = FrontMatterData{ + Subcategory: &exampleSubcategory, + Layout: &exampleLayout, + PageTitle: &examplePageTitle, + Description: &exampleDescription, +} + +var ValidRegistryIndexFrontMatter = FrontMatterData{ + PageTitle: &examplePageTitle, + Description: &exampleDescription, +} + +var ValidLegacyIndexFrontMatter = FrontMatterData{ + Layout: &exampleLayout, + PageTitle: &examplePageTitle, + Description: &exampleDescription, +} + +var ValidRegistryGuideFrontMatter = FrontMatterData{ + PageTitle: &examplePageTitle, +} + +var ValidLegacyGuideFrontMatter = FrontMatterData{ + Layout: &exampleLayout, + PageTitle: &examplePageTitle, + Description: &exampleDescription, +} + +var InvalidYAMLFrontMatter = fstest.MapFile{ + Data: []byte("---\nsubcategory: \"Example\"\npage_title: \"Example: example_thing\"\ndescription: |-\nMissing indentation.\n---\n"), +} + +func TestValidateStaticDocs_DirectoryChecks(t *testing.T) { t.Parallel() testCases := map[string]struct { - BasePath string - ExpectError bool + ProviderFS fs.FS ExpectedError string }{ "valid registry directories": { - BasePath: filepath.Join("testdata", "valid-registry-directories"), + ProviderFS: fstest.MapFS{ + "docs/data-sources/thing.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/ephemeral-resources/thing.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/functions/thing.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/guides/thing.md": { + Data: encodeYAML(t, &ValidRegistryGuideFrontMatter), + }, + "docs/nonregistrydocs/valid.md": { + Data: []byte("non-registry documentation"), + }, + "docs/resources/thing.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/CONTRIBUTING.md": { + Data: []byte("contribution guidelines"), + }, + "docs/index.md": { + Data: encodeYAML(t, &ValidRegistryIndexFrontMatter), + }, + }, }, - "valid registry directories with cdktf docs": { - BasePath: filepath.Join("testdata", "valid-registry-directories-with-cdktf"), + ProviderFS: fstest.MapFS{ + "docs/cdktf/typescript/data-sources/thing.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/cdktf/typescript/ephemeral-resources/thing.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/cdktf/typescirpt/guides/thing.md": { + Data: encodeYAML(t, &ValidRegistryGuideFrontMatter), + }, + "docs/cdktf/typescript/nonregistrydocs/valid.md": { + Data: []byte("non-registry documentation"), + }, + "docs/cdktf/typescript/resources/thing.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/cdktf/typescript/CONTRIBUTING.md": { + Data: []byte("contribution guidelines"), + }, + "docs/cdktf/typescript/index.md": { + Data: encodeYAML(t, &ValidRegistryIndexFrontMatter), + }, + "docs/data-sources/thing.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/guides/thing.md": { + Data: encodeYAML(t, &ValidRegistryGuideFrontMatter), + }, + "docs/nonregistrydocs/valid.md": { + Data: []byte("non-registry documentation"), + }, + "docs/resources/thing.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/CONTRIBUTING.md": { + Data: []byte("contribution guidelines"), + }, + "docs/index.md": { + Data: encodeYAML(t, &ValidRegistryIndexFrontMatter), + }, + }, }, "invalid registry directories": { - BasePath: filepath.Join("testdata", "invalid-registry-directories"), - ExpectError: true, - ExpectedError: "invalid Terraform Provider documentation directory found: " + filepath.Join("docs", "resources", "invalid"), + ProviderFS: fstest.MapFS{ + "docs/data-sources/invalid/thing.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/ephemeral-resources/invalid/thing.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/guides/invalid/thing.md": { + Data: encodeYAML(t, &ValidRegistryGuideFrontMatter), + }, + "docs/nonregistrydocs/valid.md": { + Data: []byte("non-registry documentation"), + }, + "docs/functions/invalid/thing.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/resources/invalid/thing.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/CONTRIBUTING.md": { + Data: []byte("contribution guidelines"), + }, + "docs/index.md": { + Data: encodeYAML(t, &ValidRegistryIndexFrontMatter), + }, + }, + ExpectedError: "invalid Terraform Provider documentation directory found: " + filepath.Join("docs", "data-sources", "invalid") + + "\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", "resources", "invalid"), }, } @@ -39,46 +189,484 @@ func TestValidateStaticDocs(t *testing.T) { t.Parallel() v := &validator{ - providerDir: testCase.BasePath, + providerFS: testCase.ProviderFS, providerName: "terraform-provider-test", logger: NewLogger(cli.NewMockUi()), } + got := v.validateStaticDocs() + + if got == nil && testCase.ExpectedError != "" { + t.Fatalf("expected error: %s, but got no error", testCase.ExpectedError) + } + + if got != nil && got.Error() != testCase.ExpectedError { + t.Errorf("Unexpected response (+wanted, -got): %s", cmp.Diff(testCase.ExpectedError, got.Error())) + } + }) + } +} + +func TestValidateStaticDocs_FileChecks(t *testing.T) { + t.Parallel() + testCases := map[string]struct { + ProviderFS fs.FS + ExpectedError string + }{ + "invalid data source files": { + ProviderFS: fstest.MapFS{ + "docs/data-sources/invalid_extension.txt": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/data-sources/invalid_frontmatter.md": &InvalidYAMLFrontMatter, + "docs/data-sources/with_layout.md": { + Data: encodeYAML(t, + &FrontMatterData{ + Layout: &exampleLayout, + Subcategory: &exampleSubcategory, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + "docs/data-sources/with_sidebar_current.md": { + Data: encodeYAML(t, + &FrontMatterData{ + SidebarCurrent: &exampleSidebarCurrent, + Subcategory: &exampleSubcategory, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + }, + ExpectedError: filepath.Join("docs", "data-sources", "invalid_extension.txt") + ": error checking file extension: file does not end with a valid extension, valid extensions: [.md]\n" + + filepath.Join("docs", "data-sources", "invalid_frontmatter.md") + ": error checking file frontmatter: error parsing YAML frontmatter: yaml: line 4: could not find expected ':'\n" + + filepath.Join("docs", "data-sources", "with_layout.md") + ": error checking file frontmatter: YAML frontmatter should not contain layout\n" + + filepath.Join("docs", "data-sources", "with_sidebar_current.md") + ": error checking file frontmatter: YAML frontmatter should not contain sidebar_current", + }, + "invalid ephemeral resource files": { + ProviderFS: fstest.MapFS{ + "docs/ephemeral-resources/invalid_extension.txt": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/ephemeral-resources/invalid_frontmatter.md": &InvalidYAMLFrontMatter, + "docs/ephemeral-resources/with_layout.md": { + Data: encodeYAML(t, + &FrontMatterData{ + Layout: &exampleLayout, + Subcategory: &exampleSubcategory, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + "docs/ephemeral-resources/with_sidebar_current.md": { + Data: encodeYAML(t, + &FrontMatterData{ + SidebarCurrent: &exampleSidebarCurrent, + Subcategory: &exampleSubcategory, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + }, + ExpectedError: filepath.Join("docs", "ephemeral-resources", "invalid_extension.txt") + ": error checking file extension: file does not end with a valid extension, valid extensions: [.md]\n" + + filepath.Join("docs", "ephemeral-resources", "invalid_frontmatter.md") + ": error checking file frontmatter: error parsing YAML frontmatter: yaml: line 4: could not find expected ':'\n" + + filepath.Join("docs", "ephemeral-resources", "with_layout.md") + ": error checking file frontmatter: YAML frontmatter should not contain layout\n" + + filepath.Join("docs", "ephemeral-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": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/resources/invalid_frontmatter.md": &InvalidYAMLFrontMatter, + "docs/resources/with_layout.md": { + Data: encodeYAML(t, + &FrontMatterData{ + Layout: &exampleLayout, + Subcategory: &exampleSubcategory, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + "docs/resources/with_sidebar_current.md": { + Data: encodeYAML(t, + &FrontMatterData{ + SidebarCurrent: &exampleSidebarCurrent, + Subcategory: &exampleSubcategory, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + }, + ExpectedError: filepath.Join("docs", "resources", "invalid_extension.txt") + ": error checking file extension: file does not end with a valid extension, valid extensions: [.md]\n" + + filepath.Join("docs", "resources", "invalid_frontmatter.md") + ": error checking file frontmatter: error parsing YAML frontmatter: yaml: line 4: could not find expected ':'\n" + + filepath.Join("docs", "resources", "with_layout.md") + ": error checking file frontmatter: YAML frontmatter should not contain layout\n" + + filepath.Join("docs", "resources", "with_sidebar_current.md") + ": error checking file frontmatter: YAML frontmatter should not contain sidebar_current", + }, + "invalid guide files": { + ProviderFS: fstest.MapFS{ + "docs/guides/invalid_extension.txt": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/guides/invalid_frontmatter.md": &InvalidYAMLFrontMatter, + "docs/guides/with_layout.md": { + Data: encodeYAML(t, + &FrontMatterData{ + Layout: &exampleLayout, + Subcategory: &exampleSubcategory, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + "docs/guides/with_sidebar_current.md": { + Data: encodeYAML(t, + &FrontMatterData{ + SidebarCurrent: &exampleSidebarCurrent, + Subcategory: &exampleSubcategory, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + "docs/guides/without_page_title.md": { + Data: encodeYAML(t, + &FrontMatterData{ + Subcategory: &exampleSubcategory, + Description: &exampleDescription, + }, + ), + }, + }, + ExpectedError: filepath.Join("docs", "guides", "invalid_extension.txt") + ": error checking file extension: file does not end with a valid extension, valid extensions: [.md]\n" + + filepath.Join("docs", "guides", "invalid_frontmatter.md") + ": error checking file frontmatter: error parsing YAML frontmatter: yaml: line 4: could not find expected ':'\n" + + filepath.Join("docs", "guides", "with_layout.md") + ": error checking file frontmatter: YAML frontmatter should not contain layout\n" + + filepath.Join("docs", "guides", "with_sidebar_current.md") + ": error checking file frontmatter: YAML frontmatter should not contain sidebar_current\n" + + filepath.Join("docs", "guides", "without_page_title.md") + ": error checking file frontmatter: YAML frontmatter missing required page_title", + }, + "invalid index file - invalid extension": { + ProviderFS: fstest.MapFS{ + "docs/index.txt": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + }, + ExpectedError: filepath.Join("docs", "index.txt") + ": error checking file extension: file does not end with a valid extension, valid extensions: [.md]", + }, + "invalid index file - invalid frontmatter": { + ProviderFS: fstest.MapFS{ + "docs/index.md": &InvalidYAMLFrontMatter, + }, + ExpectedError: filepath.Join("docs", "index.md") + ": error checking file frontmatter: error parsing YAML frontmatter: yaml: line 4: could not find expected ':'", + }, + "invalid index file - with layout": { + ProviderFS: fstest.MapFS{ + "docs/index.md": { + Data: encodeYAML(t, + &FrontMatterData{ + Layout: &exampleLayout, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + }, + ExpectedError: filepath.Join("docs", "index.md") + ": error checking file frontmatter: YAML frontmatter should not contain layout", + }, + "invalid index file - with sidebar current": { + ProviderFS: fstest.MapFS{ + "docs/index.md": { + Data: encodeYAML(t, + &FrontMatterData{ + SidebarCurrent: &exampleSidebarCurrent, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + }, + ExpectedError: filepath.Join("docs", "index.md") + ": error checking file frontmatter: YAML frontmatter should not contain sidebar_current", + }, + "invalid index file - with subcategory": { + ProviderFS: fstest.MapFS{ + "docs/index.md": { + Data: encodeYAML(t, + &FrontMatterData{ + Subcategory: &exampleSubcategory, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + }, + ExpectedError: filepath.Join("docs", "index.md") + ": error checking file frontmatter: YAML frontmatter should not contain subcategory", + }, + } + + for name, testCase := range testCases { + name := name + testCase := testCase + t.Run(name, func(t *testing.T) { + t.Parallel() - got := v.validateStaticDocs(filepath.Join(v.providerDir, "docs")) + v := &validator{ + providerFS: testCase.ProviderFS, + providerName: "terraform-provider-test", - if got == nil && testCase.ExpectError { - t.Errorf("expected error, got no error") + logger: NewLogger(cli.NewMockUi()), } + got := v.validateStaticDocs() - if got != nil && !testCase.ExpectError { - t.Errorf("expected no error, got error: %s", got) + if got == nil && testCase.ExpectedError != "" { + t.Fatalf("expected error: %s, but got no error", testCase.ExpectedError) } if got != nil && got.Error() != testCase.ExpectedError { - t.Errorf("expected error: %s, got error: %s", testCase.ExpectedError, got) + t.Errorf("Unexpected response (+wanted, -got): %s", cmp.Diff(testCase.ExpectedError, got.Error())) } }) } } -func TestValidateLegacyWebsite(t *testing.T) { +func TestValidateStaticDocs_FileMismatchCheck(t *testing.T) { t.Parallel() testCases := map[string]struct { - BasePath string - ExpectError bool + ProviderFS fs.FS + ProviderSchema *tfjson.ProviderSchema + ExpectedError string + }{ + "valid - no mismatch": { + ProviderSchema: &tfjson.ProviderSchema{ + DataSourceSchemas: map[string]*tfjson.Schema{ + "test_pet": {}, + }, + EphemeralResourceSchemas: map[string]*tfjson.Schema{ + "test_ephemeral_id": {}, + }, + ResourceSchemas: map[string]*tfjson.Schema{ + "test_id": {}, + }, + Functions: map[string]*tfjson.FunctionSignature{ + "parse_id": {}, + }, + }, + ProviderFS: fstest.MapFS{ + "docs/data-sources/pet.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/ephemeral-resources/ephemeral_id.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/functions/parse_id.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/resources/id.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + }, + }, + "invalid - missing files": { + ProviderSchema: &tfjson.ProviderSchema{ + DataSourceSchemas: map[string]*tfjson.Schema{ + "test_pet": {}, + "test_pet2": {}, + }, + EphemeralResourceSchemas: map[string]*tfjson.Schema{ + "test_ephemeral_id": {}, + "test_ephemeral_id2": {}, + }, + ResourceSchemas: map[string]*tfjson.Schema{ + "test_id": {}, + "test_id2": {}, + }, + Functions: map[string]*tfjson.FunctionSignature{ + "parse_id": {}, + "parse_id2": {}, + }, + }, + ProviderFS: fstest.MapFS{ + "docs/data-sources/pet.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/ephemeral-resources/ephemeral_id.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/functions/parse_id.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/resources/id.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + }, + ExpectedError: "missing documentation file for resource: test_id2\n" + + "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", + }, + "invalid - extra files": { + ProviderSchema: &tfjson.ProviderSchema{ + DataSourceSchemas: map[string]*tfjson.Schema{ + "test_pet": {}, + }, + EphemeralResourceSchemas: map[string]*tfjson.Schema{ + "test_ephemeral_id": {}, + }, + ResourceSchemas: map[string]*tfjson.Schema{ + "test_id": {}, + }, + Functions: map[string]*tfjson.FunctionSignature{ + "parse_id": {}, + }, + }, + ProviderFS: fstest.MapFS{ + "docs/data-sources/pet.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/data-sources/pet2.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/ephemeral-resources/ephemeral_id.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/ephemeral-resources/ephemeral_id2.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/functions/parse_id.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/functions/parse_id2.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/resources/id.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "docs/resources/id2.md": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + }, + ExpectedError: "matching resource for documentation file (id2.md) not found, file is extraneous or incorrectly named\n" + + "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", + }, + } + + for name, testCase := range testCases { + name := name + testCase := testCase + t.Run(name, func(t *testing.T) { + t.Parallel() + + v := &validator{ + providerSchema: testCase.ProviderSchema, + providerFS: testCase.ProviderFS, + providerName: "terraform-provider-test", + + logger: NewLogger(cli.NewMockUi()), + } + got := v.validateStaticDocs() + + if got == nil && testCase.ExpectedError != "" { + t.Fatalf("expected error: %s, but got no error", testCase.ExpectedError) + } + + if got != nil && got.Error() != testCase.ExpectedError { + t.Errorf("Unexpected response (+wanted, -got): %s", cmp.Diff(testCase.ExpectedError, got.Error())) + } + }) + } +} + +func TestValidateLegacyWebsite_DirectoryChecks(t *testing.T) { + t.Parallel() + testCases := map[string]struct { + ProviderFS fs.FS ExpectedError string }{ "valid legacy directories": { - BasePath: filepath.Join("testdata", "valid-legacy-directories"), + ProviderFS: fstest.MapFS{ + "website/docs/d/thing.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/ephemeral-resources/thing.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/functions/thing.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/guides/thing.html.markdown": { + Data: encodeYAML(t, &ValidLegacyGuideFrontMatter), + }, + "website/docs/r/thing.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/index.html.markdown": { + Data: encodeYAML(t, &ValidLegacyIndexFrontMatter), + }, + }, }, "valid legacy directories with cdktf docs": { - BasePath: filepath.Join("testdata", "valid-legacy-directories-with-cdktf"), + ProviderFS: fstest.MapFS{ + "website/docs/cdktf/typescript/d/thing.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/cdktf/typescript/ephemeral-resources/thing.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/cdktf/typescript/guides/thing.html.markdown": { + Data: encodeYAML(t, &ValidLegacyGuideFrontMatter), + }, + "website/docs/cdktf/typescript/r/thing.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/cdktf/typescript/index.html.markdown": { + Data: encodeYAML(t, &ValidLegacyIndexFrontMatter), + }, + "website/docs/d/thing.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/guides/thing.html.markdown": { + Data: encodeYAML(t, &ValidLegacyGuideFrontMatter), + }, + "website/docs/r/thing.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/index.html.markdown": { + Data: encodeYAML(t, &ValidLegacyIndexFrontMatter), + }, + }, }, "invalid legacy directories": { - BasePath: filepath.Join("testdata", "invalid-legacy-directories"), - ExpectError: true, - ExpectedError: "invalid Terraform Provider documentation directory found: " + filepath.Join("website", "docs", "r", "invalid"), + ProviderFS: fstest.MapFS{ + "website/docs/d/invalid/thing.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/ephemeral-resources/invalid/thing.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/functions/invalid/thing.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/guides/invalid/thing.html.markdown": { + Data: encodeYAML(t, &ValidLegacyGuideFrontMatter), + }, + "website/docs/r/invalid/thing.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/index.html.markdown": { + Data: encodeYAML(t, &ValidLegacyIndexFrontMatter), + }, + }, + ExpectedError: "invalid Terraform Provider documentation directory found: " + filepath.Join("website", "docs", "d", "invalid") + + "\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", "r", "invalid"), }, } @@ -89,24 +677,402 @@ func TestValidateLegacyWebsite(t *testing.T) { t.Parallel() v := &validator{ - providerDir: testCase.BasePath, + providerFS: testCase.ProviderFS, providerName: "terraform-provider-test", logger: NewLogger(cli.NewMockUi()), } + got := v.validateLegacyWebsite() - got := v.validateLegacyWebsite(filepath.Join(v.providerDir, "website")) + if got == nil && testCase.ExpectedError != "" { + t.Fatalf("expected error: %s, but got no error", testCase.ExpectedError) + } - if got == nil && testCase.ExpectError { - t.Errorf("expected error, got no error") + if got != nil && got.Error() != testCase.ExpectedError { + t.Errorf("Unexpected response (+wanted, -got): %s", cmp.Diff(testCase.ExpectedError, got.Error())) } + }) + } +} - if got != nil && !testCase.ExpectError { - t.Errorf("expected no error, got error: %s", got) +func TestValidateLegacyWebsite_FileChecks(t *testing.T) { + t.Parallel() + testCases := map[string]struct { + ProviderFS fs.FS + ExpectedError string + }{ + "invalid data source files": { + ProviderFS: fstest.MapFS{ + "website/docs/d/invalid_extension.txt": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "website/docs/d/invalid_frontmatter.html.markdown": &InvalidYAMLFrontMatter, + "website/docs/d/without_layout.html.markdown": { + Data: encodeYAML(t, + &FrontMatterData{ + Subcategory: &exampleSubcategory, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + "website/docs/d/with_sidebar_current.html.markdown": { + Data: encodeYAML(t, + &FrontMatterData{ + SidebarCurrent: &exampleSidebarCurrent, + Subcategory: &exampleSubcategory, + Layout: &exampleLayout, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + }, + ExpectedError: filepath.Join("website", "docs", "d", "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", "d", "invalid_frontmatter.html.markdown") + ": error checking file frontmatter: error parsing YAML frontmatter: yaml: line 4: could not find expected ':'\n" + + filepath.Join("website", "docs", "d", "with_sidebar_current.html.markdown") + ": error checking file frontmatter: YAML frontmatter should not contain sidebar_current\n" + + filepath.Join("website", "docs", "d", "without_layout.html.markdown") + ": error checking file frontmatter: YAML frontmatter missing required layout", + }, + "invalid ephemeral resource files": { + ProviderFS: fstest.MapFS{ + "website/docs/ephemeral-resources/invalid_extension.txt": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "website/docs/ephemeral-resources/invalid_frontmatter.html.markdown": &InvalidYAMLFrontMatter, + "website/docs/ephemeral-resources/without_layout.html.markdown": { + Data: encodeYAML(t, + &FrontMatterData{ + Subcategory: &exampleSubcategory, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + "website/docs/ephemeral-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", "ephemeral-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", "ephemeral-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", "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 resource files": { + ProviderFS: fstest.MapFS{ + "website/docs/r/invalid_extension.txt": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + "website/docs/r/invalid_frontmatter.html.markdown": &InvalidYAMLFrontMatter, + "website/docs/r/without_layout.html.markdown": { + Data: encodeYAML(t, + &FrontMatterData{ + Subcategory: &exampleSubcategory, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + "website/docs/r/with_sidebar_current.html.markdown": { + Data: encodeYAML(t, + &FrontMatterData{ + SidebarCurrent: &exampleSidebarCurrent, + Subcategory: &exampleSubcategory, + Layout: &exampleLayout, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + }, + ExpectedError: filepath.Join("website", "docs", "r", "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", "r", "invalid_frontmatter.html.markdown") + ": error checking file frontmatter: error parsing YAML frontmatter: yaml: line 4: could not find expected ':'\n" + + filepath.Join("website", "docs", "r", "with_sidebar_current.html.markdown") + ": error checking file frontmatter: YAML frontmatter should not contain sidebar_current\n" + + filepath.Join("website", "docs", "r", "without_layout.html.markdown") + ": error checking file frontmatter: YAML frontmatter missing required layout", + }, + "invalid guide files": { + ProviderFS: fstest.MapFS{ + "website/docs/guides/invalid_extension.txt": { + Data: encodeYAML(t, &ValidLegacyGuideFrontMatter), + }, + "website/docs/guides/invalid_frontmatter.html.markdown": &InvalidYAMLFrontMatter, + "website/docs/guides/with_sidebar_current.html.markdown": { + Data: encodeYAML(t, + &FrontMatterData{ + SidebarCurrent: &exampleSidebarCurrent, + Layout: &exampleLayout, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + "website/docs/guides/without_description.html.markdown": { + Data: encodeYAML(t, + &FrontMatterData{ + Layout: &exampleLayout, + PageTitle: &examplePageTitle, + }, + ), + }, + "website/docs/guides/without_layout.html.markdown": { + Data: encodeYAML(t, + &FrontMatterData{ + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + "website/docs/guides/without_page_title.html.markdown": { + Data: encodeYAML(t, + &FrontMatterData{ + Layout: &exampleLayout, + Description: &exampleDescription, + }, + ), + }, + }, + ExpectedError: filepath.Join("website", "docs", "guides", "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", "guides", "invalid_frontmatter.html.markdown") + ": error checking file frontmatter: error parsing YAML frontmatter: yaml: line 4: could not find expected ':'\n" + + filepath.Join("website", "docs", "guides", "with_sidebar_current.html.markdown") + ": error checking file frontmatter: YAML frontmatter should not contain sidebar_current\n" + + filepath.Join("website", "docs", "guides", "without_description.html.markdown") + ": error checking file frontmatter: YAML frontmatter missing required description\n" + + filepath.Join("website", "docs", "guides", "without_layout.html.markdown") + ": error checking file frontmatter: YAML frontmatter missing required layout\n" + + filepath.Join("website", "docs", "guides", "without_page_title.html.markdown") + ": error checking file frontmatter: YAML frontmatter missing required page_title", + }, + "invalid index file - invalid extension": { + ProviderFS: fstest.MapFS{ + "website/docs/index.txt": { + Data: encodeYAML(t, &ValidRegistryResourceFrontMatter), + }, + }, + ExpectedError: filepath.Join("website", "docs", "index.txt") + ": error checking file extension: file does not end with a valid extension, valid extensions: [.html.markdown .html.md .markdown .md]", + }, + "invalid index file - invalid frontmatter": { + ProviderFS: fstest.MapFS{ + "website/docs/index.html.markdown": &InvalidYAMLFrontMatter, + }, + ExpectedError: filepath.Join("website", "docs", "index.html.markdown") + ": error checking file frontmatter: error parsing YAML frontmatter: yaml: line 4: could not find expected ':'", + }, + "invalid index file - with sidebar current": { + ProviderFS: fstest.MapFS{ + "website/docs/index.html.markdown": { + Data: encodeYAML(t, + &FrontMatterData{ + SidebarCurrent: &exampleSidebarCurrent, + Layout: &exampleLayout, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + }, + ExpectedError: filepath.Join("website", "docs", "index.html.markdown") + ": error checking file frontmatter: YAML frontmatter should not contain sidebar_current", + }, + "invalid index file - with subcategory": { + ProviderFS: fstest.MapFS{ + "website/docs/index.html.markdown": { + Data: encodeYAML(t, + &FrontMatterData{ + Subcategory: &exampleSubcategory, + Layout: &exampleLayout, + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + }, + ExpectedError: filepath.Join("website", "docs", "index.html.markdown") + ": error checking file frontmatter: YAML frontmatter should not contain subcategory", + }, + "invalid index file - without layout": { + ProviderFS: fstest.MapFS{ + "website/docs/index.html.markdown": { + Data: encodeYAML(t, + &FrontMatterData{ + PageTitle: &examplePageTitle, + Description: &exampleDescription, + }, + ), + }, + }, + ExpectedError: filepath.Join("website", "docs", "index.html.markdown") + ": error checking file frontmatter: YAML frontmatter missing required layout", + }, + } + + for name, testCase := range testCases { + name := name + testCase := testCase + t.Run(name, func(t *testing.T) { + t.Parallel() + + v := &validator{ + providerFS: testCase.ProviderFS, + providerName: "terraform-provider-test", + + logger: NewLogger(cli.NewMockUi()), + } + got := v.validateLegacyWebsite() + + if got == nil && testCase.ExpectedError != "" { + t.Fatalf("expected error: %s, but got no error", testCase.ExpectedError) + } + + if got != nil && got.Error() != testCase.ExpectedError { + t.Errorf("Unexpected response (+wanted, -got): %s", cmp.Diff(testCase.ExpectedError, got.Error())) + } + }) + } +} + +func TestValidateLegacyWebsite_FileMismatchCheck(t *testing.T) { + t.Parallel() + testCases := map[string]struct { + ProviderFS fs.FS + ProviderSchema *tfjson.ProviderSchema + ExpectedError string + }{ + "valid - no mismatch": { + ProviderSchema: &tfjson.ProviderSchema{ + DataSourceSchemas: map[string]*tfjson.Schema{ + "test_pet": {}, + }, + EphemeralResourceSchemas: map[string]*tfjson.Schema{ + "test_ephemeral_id": {}, + }, + ResourceSchemas: map[string]*tfjson.Schema{ + "test_id": {}, + }, + Functions: map[string]*tfjson.FunctionSignature{ + "parse_id": {}, + }, + }, + ProviderFS: fstest.MapFS{ + "website/docs/d/pet.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/ephemeral-resources/ephemeral_id.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/functions/parse_id.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/r/id.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + }, + }, + "invalid - missing files": { + ProviderSchema: &tfjson.ProviderSchema{ + DataSourceSchemas: map[string]*tfjson.Schema{ + "test_pet": {}, + "test_pet2": {}, + }, + EphemeralResourceSchemas: map[string]*tfjson.Schema{ + "test_ephemeral_id": {}, + "test_ephemeral_id2": {}, + }, + ResourceSchemas: map[string]*tfjson.Schema{ + "test_id": {}, + "test_id2": {}, + }, + Functions: map[string]*tfjson.FunctionSignature{ + "parse_id": {}, + "parse_id2": {}, + }, + }, + ProviderFS: fstest.MapFS{ + "website/docs/d/pet.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/ephemeral-resources/ephemeral_id.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/functions/parse_id.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/r/id.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + }, + ExpectedError: "missing documentation file for resource: test_id2\n" + + "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", + }, + "invalid - extra files": { + ProviderSchema: &tfjson.ProviderSchema{ + DataSourceSchemas: map[string]*tfjson.Schema{ + "test_pet": {}, + }, + EphemeralResourceSchemas: map[string]*tfjson.Schema{ + "test_ephemeral_id": {}, + }, + ResourceSchemas: map[string]*tfjson.Schema{ + "test_id": {}, + }, + Functions: map[string]*tfjson.FunctionSignature{ + "parse_id": {}, + }, + }, + ProviderFS: fstest.MapFS{ + "website/docs/d/pet.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/d/pet2.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/ephemeral-resources/ephemeral_id.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/ephemeral-resources/ephemeral_id2.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/functions/parse_id.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/functions/parse_id2.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/r/id.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + "website/docs/r/id2.html.markdown": { + Data: encodeYAML(t, &ValidLegacyResourceFrontMatter), + }, + }, + ExpectedError: "matching resource for documentation file (id2.html.markdown) not found, file is extraneous or incorrectly named\n" + + "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", + }, + } + + for name, testCase := range testCases { + name := name + testCase := testCase + t.Run(name, func(t *testing.T) { + t.Parallel() + + v := &validator{ + providerSchema: testCase.ProviderSchema, + providerFS: testCase.ProviderFS, + providerName: "terraform-provider-test", + + logger: NewLogger(cli.NewMockUi()), + } + got := v.validateLegacyWebsite() + + if got == nil && testCase.ExpectedError != "" { + t.Fatalf("expected error: %s, but got no error", testCase.ExpectedError) } if got != nil && got.Error() != testCase.ExpectedError { - t.Errorf("expected error: %s, got error: %s", testCase.ExpectedError, got) + t.Errorf("Unexpected response (+wanted, -got): %s", cmp.Diff(testCase.ExpectedError, got.Error())) } }) } @@ -166,3 +1132,15 @@ func TestDocumentationDirGlobPattern(t *testing.T) { }) } } + +func encodeYAML(t *testing.T, data *FrontMatterData) []byte { + t.Helper() + var buf bytes.Buffer + buf.Write([]byte("---\n")) + err := yaml.NewEncoder(&buf).Encode(data) + if err != nil { + t.Fatalf("error encoding YAML: %s", err) + } + buf.Write([]byte("---\n")) + return buf.Bytes() +} diff --git a/tools/go.mod b/tools/go.mod index ba85d85e..738e2a3d 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -1,8 +1,8 @@ module tools -go 1.21 +go 1.22.7 -require github.com/hashicorp/copywrite v0.18.0 +require github.com/hashicorp/copywrite v0.19.0 require ( github.com/AlecAivazis/survey/v2 v2.3.6 // indirect @@ -18,7 +18,7 @@ require ( github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/go-openapi/errors v0.20.2 // indirect github.com/go-openapi/strfmt v0.21.3 // indirect - github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + github.com/golang-jwt/jwt/v4 v4.5.1 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-github/v45 v45.2.0 // indirect github.com/google/go-github/v53 v53.0.0 // indirect diff --git a/tools/go.sum b/tools/go.sum index b903a248..cfc168fa 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -97,8 +97,9 @@ github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr6 github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= +github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -147,8 +148,8 @@ github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslC github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hashicorp/consul/api v1.13.0/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= -github.com/hashicorp/copywrite v0.18.0 h1:6f3aBDyQLBXhD6cdGSnsEM37vCDi3JJrkbR9HPBJf5c= -github.com/hashicorp/copywrite v0.18.0/go.mod h1:6wvQH+ICDoD2bpjO1RJ6fi+h3aY5NeLEM12oTkEtFoc= +github.com/hashicorp/copywrite v0.19.0 h1:f9LVxTDBfFYeQmdBpOsZ+HWknXonI8ZwubbO/RwyuCo= +github.com/hashicorp/copywrite v0.19.0/go.mod h1:6wvQH+ICDoD2bpjO1RJ6fi+h3aY5NeLEM12oTkEtFoc= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=