Skip to content

Commit

Permalink
Allowing single word resources to use templates (#147)
Browse files Browse the repository at this point in the history
* Allowing single word resources to use templates

* Updating CHANGELOG.md

* Add unit test for resourceName

* Returning error if resource not found

* Adding field names to test structs
  • Loading branch information
bendbennett committed Jun 10, 2022
1 parent ed20132 commit cbd432b
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 28 deletions.
10 changes: 8 additions & 2 deletions CHANGELOG.md
@@ -1,12 +1,18 @@
# 0.9.1 (Unreleased)

BUG FIXES:

* cmd/tfplugindocs: Allow single word resources to use templates ([147](https://github.com/hashicorp/terraform-plugin-docs/pull/147)).

# 0.9.0 (June 1, 2022)

NEW FEATURES:

* cmd/tflugindocs: Additional CLI arguments `provider-name`, `rendered-provider-name`, `rendered-website-dir`, `examples-dir`, `website-temp-dir`, and `website-source-dir`. These allow to further customise generated doc ([#95](https://github.com/hashicorp/terraform-plugin-docs/pull/95)).
* cmd/tfplugindocs: Additional CLI arguments `provider-name`, `rendered-provider-name`, `rendered-website-dir`, `examples-dir`, `website-temp-dir`, and `website-source-dir`. These allow to further customise generated doc ([#95](https://github.com/hashicorp/terraform-plugin-docs/pull/95)).

ENHANCEMENTS:

* cmd/tflugindocs: Implemented usage output (i.e. `--help`) for `generate` and `validate` commands ([#95](https://github.com/hashicorp/terraform-plugin-docs/pull/95)).
* cmd/tfplugindocs: Implemented usage output (i.e. `--help`) for `generate` and `validate` commands ([#95](https://github.com/hashicorp/terraform-plugin-docs/pull/95)).

# 0.8.1 (May 10, 2022)

Expand Down
54 changes: 28 additions & 26 deletions internal/provider/generate.go
Expand Up @@ -414,35 +414,37 @@ func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfj
g.infof("rendering %q", rel)
switch relDir {
case "data-sources/":
resName := shortName + "_" + removeAllExt(relFile)
resSchema, ok := providerSchema.DataSourceSchemas[resName]
if ok {
tmpl := resourceTemplate(tmplData)
render, err := tmpl.Render(resName, providerName, "Data Source", "", "", resSchema)
if err != nil {
return fmt.Errorf("unable to render data source template %q: %w", rel, err)
}
_, err = out.WriteString(render)
if err != nil {
return fmt.Errorf("unable to write rendered string: %w", err)
}
return nil
resSchema, resName := resourceSchema(providerSchema.DataSourceSchemas, shortName, relFile)
if resSchema == nil {
return fmt.Errorf("unable to find resource for provider (%s) and template (%s)", shortName, relFile)
}

tmpl := resourceTemplate(tmplData)
render, err := tmpl.Render(resName, providerName, "Data Source", "", "", resSchema)
if err != nil {
return fmt.Errorf("unable to render data source template %q: %w", rel, err)
}
_, err = out.WriteString(render)
if err != nil {
return fmt.Errorf("unable to write rendered string: %w", err)
}
return nil
case "resources/":
resName := shortName + "_" + removeAllExt(relFile)
resSchema, ok := providerSchema.ResourceSchemas[resName]
if ok {
tmpl := resourceTemplate(tmplData)
render, err := tmpl.Render(resName, providerName, "Resource", "", "", resSchema)
if err != nil {
return fmt.Errorf("unable to render resource template %q: %w", rel, err)
}
_, err = out.WriteString(render)
if err != nil {
return fmt.Errorf("unable to write regindered string: %w", err)
}
return nil
resSchema, resName := resourceSchema(providerSchema.ResourceSchemas, shortName, relFile)
if resSchema == nil {
return fmt.Errorf("unable to find resource for provider (%s) and template (%s)", shortName, relFile)
}

tmpl := resourceTemplate(tmplData)
render, err := tmpl.Render(resName, providerName, "Resource", "", "", resSchema)
if err != nil {
return fmt.Errorf("unable to render resource template %q: %w", rel, err)
}
_, err = out.WriteString(render)
if err != nil {
return fmt.Errorf("unable to write regindered string: %w", err)
}
return nil
case "": // provider
if relFile == "index.md.tmpl" {
tmpl := providerTemplate(tmplData)
Expand Down
1 change: 1 addition & 0 deletions internal/provider/template.go
Expand Up @@ -8,6 +8,7 @@ import (
"text/template"

tfjson "github.com/hashicorp/terraform-json"

"github.com/hashicorp/terraform-plugin-docs/internal/mdplain"
"github.com/hashicorp/terraform-plugin-docs/internal/tmplfuncs"
"github.com/hashicorp/terraform-plugin-docs/schemamd"
Expand Down
19 changes: 19 additions & 0 deletions internal/provider/util.go
Expand Up @@ -9,6 +9,8 @@ import (
"os/exec"
"path/filepath"
"strings"

tfjson "github.com/hashicorp/terraform-json"
)

func providerShortName(n string) string {
Expand Down Expand Up @@ -52,6 +54,23 @@ func removeAllExt(file string) string {
}
}

// resourceSchema determines whether there is a schema in the supplied schemas map which
// has either the providerShortName or the providerShortName concatenated with the
// templateFileName (stripped of file extension.
func resourceSchema(schemas map[string]*tfjson.Schema, providerShortName, templateFileName string) (*tfjson.Schema, string) {
if schema, ok := schemas[providerShortName]; ok {
return schema, providerShortName
}

resName := providerShortName + "_" + removeAllExt(templateFileName)

if schema, ok := schemas[resName]; ok {
return schema, resName
}

return nil, ""
}

func writeFile(path string, data string) error {
dir, _ := filepath.Split(path)
err := os.MkdirAll(dir, 0755)
Expand Down
78 changes: 78 additions & 0 deletions internal/provider/util_test.go
@@ -0,0 +1,78 @@
package provider

import (
"testing"

"github.com/google/go-cmp/cmp"
tfjson "github.com/hashicorp/terraform-json"
)

func Test_resourceSchema(t *testing.T) {
cases := map[string]struct {
schemas map[string]*tfjson.Schema
providerShortName string
templateFileName string
expectedSchema *tfjson.Schema
expectedResourceName string
}{
"provider short name matches schema name": {
schemas: map[string]*tfjson.Schema{
"http": {},
},
providerShortName: "http",
templateFileName: "http.md.tmpl",
expectedSchema: &tfjson.Schema{},
expectedResourceName: "http",
},
"provider short name does not match schema name": {
schemas: map[string]*tfjson.Schema{
"http": {},
},
providerShortName: "tls",
templateFileName: "http.md.tmpl",
expectedSchema: nil,
expectedResourceName: "",
},
"provider short name concatenated with template file name matches schema name": {
schemas: map[string]*tfjson.Schema{
"tls_cert_request": {},
},
providerShortName: "tls",
templateFileName: "cert_request.md.tmpl",
expectedSchema: &tfjson.Schema{},
expectedResourceName: "tls_cert_request",
},
"provider short name concatenated with template file name does not match schema name": {
schemas: map[string]*tfjson.Schema{
"tls_cert_request": {},
},
providerShortName: "tls",
templateFileName: "not_found.md.tmpl",
expectedSchema: nil,
expectedResourceName: "",
},
"provider short name concatenated with same template file name matches schema name": {
schemas: map[string]*tfjson.Schema{
"tls_tls": {},
},
providerShortName: "tls",
templateFileName: "tls.md.tmpl",
expectedSchema: &tfjson.Schema{},
expectedResourceName: "tls_tls",
},
}

for name, c := range cases {
t.Run(name, func(t *testing.T) {
actualSchema, actualResourceName := resourceSchema(c.schemas, c.providerShortName, c.templateFileName)

if !cmp.Equal(c.expectedSchema, actualSchema) {
t.Errorf("expected: %+v, got: %+v", c.expectedSchema, actualSchema)
}

if !cmp.Equal(c.expectedResourceName, actualResourceName) {
t.Errorf("expected: %s, got: %s", c.expectedResourceName, actualResourceName)
}
})
}
}

0 comments on commit cbd432b

Please sign in to comment.