Skip to content

Commit

Permalink
Add Support for Provider-defined Function Documentation (#328)
Browse files Browse the repository at this point in the history
* Implement `functionmd` package

* Implement provider-defined function support for `generate` command

* Fix spacing for `functionmd.RenderFunctions()` output

* Update README.md

* Implement provider-defined function support for `migrate` command

* Add copywrite headers

* Add `templates` directory to list of accepted directory names in `validate`

* Update `provider-build` acceptance tests

* Add Changelog entries

* Update README.md to include Terraform binary requirement for functions
SBGoods authored Jan 23, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 56c7fae commit 69163cd
Showing 26 changed files with 1,107 additions and 39 deletions.
6 changes: 6 additions & 0 deletions .changes/unreleased/ENHANCEMENTS-20240122-160317.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: ENHANCEMENTS
body: 'validate: Add `functions` to list of allowed template and rendered website
subdirectories'
time: 2024-01-22T16:03:17.035362-05:00
custom:
Issue: "328"
5 changes: 5 additions & 0 deletions .changes/unreleased/FEATURES-20240122-160026.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kind: FEATURES
body: 'generate: Add support for Provider-defined Function documentation'
time: 2024-01-22T16:00:26.052538-05:00
custom:
Issue: "328"
5 changes: 5 additions & 0 deletions .changes/unreleased/FEATURES-20240122-160050.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kind: FEATURES
body: 'migrate: Add support for Provider-defined Function documentation'
time: 2024-01-22T16:00:50.279982-05:00
custom:
Issue: "328"
62 changes: 43 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -105,6 +105,7 @@ When you run `tfplugindocs`, by default from the root directory of a provider co
* Generate a default provider template file, if missing (**index.md**)
* Generate resource template files, if missing
* Generate data source template files, if missing
* Generate function template files, if missing (Requires Terraform v1.8.0+)
* Copy all non-template files to the output website directory
* Process all the remaining templates to generate files for the output website directory
@@ -165,19 +166,21 @@ The `migrate` subcommand takes the following actions:

The generation of missing documentation is based on a number of assumptions / conventional paths.

> **NOTE:** In the following conventional paths, `<data source name>` and `<resource name>` include the provider prefix as well.
> **NOTE:** In the following conventional paths, `<data source name>` and `<resource name>` include the provider prefix as well, but the provider prefix is **NOT** included in`<function name>`.
> 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`

For templates:

| 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/<data source name>.md[.tmpl]` | Data source page (or template) |
| `templates/resources.md[.tmpl]` | Generic resource page (or template) |
| `templates/resources/<resource name>.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/<data source name>.md[.tmpl]` | Data source page (or template) |
| `templates/functions.md[.tmpl]` | Generic function page (or template) |
| `templates/functions/<function name>.md[.tmpl]` | Function page (or template) |
| `templates/resources.md[.tmpl]` | Generic resource page (or template) |
| `templates/resources/<resource name>.md[.tmpl]` | Resource page (or template) |

Note: the `.tmpl` extension is necessary, for the file to be correctly handled as a template.

@@ -188,6 +191,7 @@ For examples:
| `examples/` | Root of examples |
| `examples/provider/provider.tf` | Provider example config |
| `examples/data-sources/<data source name>/data-source.tf` | Data source example config |
| `examples/functions/<function name>/function.tf` | Function example config |
| `examples/resources/<resource name>/resource.tf` | Resource example config |
| `examples/resources/<resource name>/import.sh` | Resource example import command |

@@ -197,13 +201,14 @@ 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/<data source name>.html.markdown` | Data source page |
| `website/docs/r/<resource name>.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/<data source name>.html.markdown` | Data source page |
| `website/docs/functons/<function name>.html.markdown` | Functions page |
| `website/docs/r/<resource name>.html.markdown` | Resource page |

Docs website directory structure:

@@ -213,6 +218,7 @@ Docs website directory structure:
| `docs/guides` | Root of guides subdirectory |
| `docs/index.html.markdown` | Docs index page |
| `docs/data-sources/<data source name>.html.markdown` | Data source page |
| `docs/functions/<function name>.html.markdown` | Function page |
| `docs/resources/<resource name>.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/`,
@@ -229,7 +235,7 @@ using the following data fields and functions:

#### Data fields

##### Provider
##### Provider Fields

| Field | Type | Description |
|------------------------:|:------:|-------------------------------------------------------------------------------------------|
@@ -241,7 +247,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
##### Resources / Data Source Fields

| Field | Type | Description |
|------------------------:|:------:|-------------------------------------------------------------------------------------------|
@@ -257,7 +263,25 @@ 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 Resource / Data Source Schema definition |

#### Functions
##### Provider-defined Function Fields

| Field | Type | Description |
|------------------------------------:|:------:|-------------------------------------------------------------------------------------------|
| `.Name` | string | Name of the function (ex. `echo`) |
| `.Type` | string | Returns `Function` |
| `.Description` | string | Function description |
| `.Summary` | string | Function summary |
| `.HasExample` | bool | Is there an example file? |
| `.ExampleFile` | string | Path to the file with the terraform configuration example |
| `.ProviderName` | string | Canonical provider name (ex. `terraform-provider-random`) |
| `.ProviderShortName` | string | Short version of the provider name (ex. `random`) |
| `.RenderedProviderName` | string | Value provided via argument `--rendered-provider-name`, otherwise same as `.ProviderName` |
| `.FunctionSignatureMarkdown` | string | a Markdown formatted Function signature |
| `.FunctionArgumentsMarkdown` | string | a Markdown formatted Function arguments definition |
| `.HasVariadic` | bool | Does this function have a variadic argument? |
| `.FunctionVariadicArgumentMarkdown` | string | a Markdown formatted Function variadic argument definition |

#### Template Functions

| Function | Description |
|-----------------|---------------------------------------------------------------------------------------------------|
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@ generating missing resource content
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 provider content
provider "terraform-provider-scaffolding" template exists, skipping
rendering static website
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@ generating missing resource content
resource "scaffolding_example" template exists, skipping
generating missing data source content
data-source "scaffolding_example" template exists, skipping
generating missing function content
generating missing provider content
provider "terraform-provider-scaffolding" template exists, skipping
rendering static website
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@ generating missing resource content
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 provider content
generating new template for "terraform-provider-scaffolding"
rendering static website
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@ generating missing resource content
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 provider content
provider "terraform-provider-null" template exists, skipping
rendering static website
Original file line number Diff line number Diff line change
@@ -9,6 +9,8 @@ cmp stdout expected-output.txt
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


-- expected-output.txt --
rendering website for provider "terraform-provider-scaffolding" (as "terraform-provider-scaffolding")
@@ -20,12 +22,15 @@ generating missing resource content
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
function "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 "functions/example.md.tmpl"
rendering "index.md.tmpl"
rendering "resources/example.md.tmpl"
-- expected-datasource.md --
@@ -84,6 +89,53 @@ data "scaffolding_example" "example" {
configurable_attribute = "some-value"
}
```
-- expected-function.md --
# Data Fields

Name: example
Type: function
Description: Given a string value, returns the same value.
Summary: Echo a string
HasExample: true
ExampleFile: $WORK/examples/functions/example/function.tf
ProviderName: terraform-provider-scaffolding
ProviderShortName: scaffolding
RenderedProviderName: terraform-provider-scaffolding
FunctionSignatureMarkdown: <!-- signature generated by tfplugindocs -->
```text
example(input string, variadicInput string...) string
```
FunctionArgumentsMarkdown: <!-- arguments generated by tfplugindocs -->
1. `input` (String) Value to echo.
HasVariadic: true
FunctionVariadicArgumentMarkdown: <!-- variadic argument generated by tfplugindocs -->
1. `variadicInput` (Variadic, String) Variadic input to echo.

# Functions

lower: function
plainmarkdown: function
prefixlines: Prefix: function
split: [example]
title: Function
trimspace: function
upper: FUNCTION

# Conditionals and File Functions

printf tffile:
## Example Usage

{{tffile "$WORK/examples/functions/example/function.tf"}}

tffile:
## Example Usage

```terraform
output "test" {
value = provider::scaffolding::example("testvalue1", "testvalue2")
}
```
-- expected-index.md --
# Data Fields

@@ -250,6 +302,48 @@ tffile:
{{ if .HasExample -}}
## Example Usage

{{tffile .ExampleFile }}
{{- end }}
-- templates/functions.md.tmpl --
# Data Fields

Name: {{.Name}}
Type: {{.Type}}
Description: {{.Description}}
Summary: {{.Summary}}
HasExample: {{.HasExample}}
ExampleFile: {{.ExampleFile}}
ProviderName: {{.ProviderName}}
ProviderShortName: {{.ProviderShortName}}
RenderedProviderName: {{.RenderedProviderName}}
FunctionSignatureMarkdown: {{.FunctionSignatureMarkdown}}
FunctionArgumentsMarkdown: {{.FunctionArgumentsMarkdown}}
HasVariadic: {{.HasVariadic}}
FunctionVariadicArgumentMarkdown: {{.FunctionVariadicArgumentMarkdown}}

# Functions

lower: {{ .Type | lower }}
plainmarkdown: {{ .Type | plainmarkdown }}
prefixlines: {{ .Type | prefixlines "Prefix: " }}
split: {{ split .Name "_" }}
title: {{ .Type | title }}
trimspace: {{ .Type | trimspace }}
upper: {{ .Type | upper }}

# Conditionals and File Functions

printf tffile:
{{ if .HasExample -}}
## Example Usage

{{ printf "{{tffile %q}}" .ExampleFile }}
{{- end }}

tffile:
{{ if .HasExample -}}
## Example Usage

{{tffile .ExampleFile }}
{{- end }}
-- templates/index.md.tmpl --
@@ -360,6 +454,10 @@ The document generation tool looks for files in the following locations by defau
data "scaffolding_example" "example" {
configurable_attribute = "some-value"
}
-- examples/functions/example/function.tf --
output "test" {
value = provider::scaffolding::example("testvalue1", "testvalue2")
}
-- examples/provider/provider.tf --
provider "scaffolding" {
# example configuration here
@@ -442,6 +540,25 @@ terraform import scaffolding_example.example
"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"
}
}
}
}
}
Loading

0 comments on commit 69163cd

Please sign in to comment.