Bump github.com/hashicorp/terraform-plugin-docs from 0.14.1 to 0.15.0

Bumps [github.com/hashicorp/terraform-plugin-docs](https://github.com/hashicorp/terraform-plugin-docs) from 0.14.1 to 0.15.0.
- [Release notes](https://github.com/hashicorp/terraform-plugin-docs/releases)
- [Changelog](https://github.com/hashicorp/terraform-plugin-docs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/terraform-plugin-docs/compare/v0.14.1...v0.15.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/terraform-plugin-docs
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot] 2023-07-04 08:39:56 +00:00 committed by GitHub
parent e8584b0270
commit 4e94047737
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 207 additions and 93 deletions

2
go.mod
View File

@ -4,7 +4,7 @@ go 1.18
require ( require (
code.gitea.io/sdk/gitea v0.15.1 code.gitea.io/sdk/gitea v0.15.1
github.com/hashicorp/terraform-plugin-docs v0.14.1 github.com/hashicorp/terraform-plugin-docs v0.15.0
github.com/hashicorp/terraform-plugin-log v0.9.0 github.com/hashicorp/terraform-plugin-log v0.9.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.27.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.27.0
) )

4
go.sum
View File

@ -84,8 +84,8 @@ github.com/hashicorp/terraform-exec v0.18.1 h1:LAbfDvNQU1l0NOQlTuudjczVhHj061fNX
github.com/hashicorp/terraform-exec v0.18.1/go.mod h1:58wg4IeuAJ6LVsLUeD2DWZZoc/bYi6dzhLHzxM41980= github.com/hashicorp/terraform-exec v0.18.1/go.mod h1:58wg4IeuAJ6LVsLUeD2DWZZoc/bYi6dzhLHzxM41980=
github.com/hashicorp/terraform-json v0.17.0 h1:EiA1Wp07nknYQAiv+jIt4dX4Cq5crgP+TsTE45MjMmM= github.com/hashicorp/terraform-json v0.17.0 h1:EiA1Wp07nknYQAiv+jIt4dX4Cq5crgP+TsTE45MjMmM=
github.com/hashicorp/terraform-json v0.17.0/go.mod h1:Huy6zt6euxaY9knPAFKjUITn8QxUFIe9VuSzb4zn/0o= github.com/hashicorp/terraform-json v0.17.0/go.mod h1:Huy6zt6euxaY9knPAFKjUITn8QxUFIe9VuSzb4zn/0o=
github.com/hashicorp/terraform-plugin-docs v0.14.1 h1:MikFi59KxrP/ewrZoaowrB9he5Vu4FtvhamZFustiA4= github.com/hashicorp/terraform-plugin-docs v0.15.0 h1:W5xYB5kCUBqO7lyjE2UMmUBh95c0aAf4jwO0Xuuw2Ec=
github.com/hashicorp/terraform-plugin-docs v0.14.1/go.mod h1:k2NW8+t113jAus6bb5tQYQgEAX/KueE/u8X2Z45V1GM= github.com/hashicorp/terraform-plugin-docs v0.15.0/go.mod h1:K5Taof1Y7sL4dw6Ie0qMFyQnHN0W+RSVMD0iIyFDFJc=
github.com/hashicorp/terraform-plugin-go v0.16.0 h1:DSOQ0rz5FUiVO4NUzMs8ln9gsPgHMTsfns7Nk+6gPuE= github.com/hashicorp/terraform-plugin-go v0.16.0 h1:DSOQ0rz5FUiVO4NUzMs8ln9gsPgHMTsfns7Nk+6gPuE=
github.com/hashicorp/terraform-plugin-go v0.16.0/go.mod h1:4sn8bFuDbt+2+Yztt35IbOrvZc0zyEi87gJzsTgCES8= github.com/hashicorp/terraform-plugin-go v0.16.0/go.mod h1:4sn8bFuDbt+2+Yztt35IbOrvZc0zyEi87gJzsTgCES8=
github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0=

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package main package main
import ( import (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package main package main
var ( var (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package cmd package cmd
import ( import (
@ -11,12 +14,12 @@ import (
type generateCmd struct { type generateCmd struct {
commonCmd commonCmd
flagLegacySidebar bool
flagIgnoreDeprecated bool flagIgnoreDeprecated bool
flagProviderName string flagProviderName string
flagRenderedProviderName string flagRenderedProviderName string
flagProviderDir string
flagRenderedWebsiteDir string flagRenderedWebsiteDir string
flagExamplesDir string flagExamplesDir string
flagWebsiteTmpDir string flagWebsiteTmpDir string
@ -25,7 +28,7 @@ type generateCmd struct {
} }
func (cmd *generateCmd) Synopsis() string { func (cmd *generateCmd) Synopsis() string {
return "generates a plugin website from code, templates, and examples for the current directory" return "generates a plugin website from code, templates, and examples"
} }
func (cmd *generateCmd) Help() string { func (cmd *generateCmd) Help() string {
@ -68,13 +71,13 @@ func (cmd *generateCmd) Help() string {
func (cmd *generateCmd) Flags() *flag.FlagSet { func (cmd *generateCmd) Flags() *flag.FlagSet {
fs := flag.NewFlagSet("generate", flag.ExitOnError) fs := flag.NewFlagSet("generate", flag.ExitOnError)
fs.BoolVar(&cmd.flagLegacySidebar, "legacy-sidebar", false, "generate the legacy .erb sidebar file")
fs.StringVar(&cmd.flagProviderName, "provider-name", "", "provider name, as used in Terraform configurations") fs.StringVar(&cmd.flagProviderName, "provider-name", "", "provider name, as used in Terraform configurations")
fs.StringVar(&cmd.flagProviderDir, "provider-dir", "", "relative or absolute path to the root provider code directory when running the command outside the root provider code directory")
fs.StringVar(&cmd.flagRenderedProviderName, "rendered-provider-name", "", "provider name, as generated in documentation (ex. page titles, ...)") fs.StringVar(&cmd.flagRenderedProviderName, "rendered-provider-name", "", "provider name, as generated in documentation (ex. page titles, ...)")
fs.StringVar(&cmd.flagRenderedWebsiteDir, "rendered-website-dir", "docs", "output directory") fs.StringVar(&cmd.flagRenderedWebsiteDir, "rendered-website-dir", "docs", "output directory based on provider-dir")
fs.StringVar(&cmd.flagExamplesDir, "examples-dir", "examples", "examples directory") fs.StringVar(&cmd.flagExamplesDir, "examples-dir", "examples", "examples directory based on provider-dir")
fs.StringVar(&cmd.flagWebsiteTmpDir, "website-temp-dir", "", "temporary directory (used during generation)") fs.StringVar(&cmd.flagWebsiteTmpDir, "website-temp-dir", "", "temporary directory (used during generation)")
fs.StringVar(&cmd.flagWebsiteSourceDir, "website-source-dir", "templates", "templates directory") fs.StringVar(&cmd.flagWebsiteSourceDir, "website-source-dir", "templates", "templates directory based on provider-dir")
fs.StringVar(&cmd.tfVersion, "tf-version", "", "terraform binary version to download") fs.StringVar(&cmd.tfVersion, "tf-version", "", "terraform binary version to download")
fs.BoolVar(&cmd.flagIgnoreDeprecated, "ignore-deprecated", false, "don't generate documentation for deprecated resources and data-sources") fs.BoolVar(&cmd.flagIgnoreDeprecated, "ignore-deprecated", false, "don't generate documentation for deprecated resources and data-sources")
return fs return fs
@ -94,7 +97,7 @@ func (cmd *generateCmd) Run(args []string) int {
func (cmd *generateCmd) runInternal() error { func (cmd *generateCmd) runInternal() error {
err := provider.Generate( err := provider.Generate(
cmd.ui, cmd.ui,
cmd.flagLegacySidebar, cmd.flagProviderDir,
cmd.flagProviderName, cmd.flagProviderName,
cmd.flagRenderedProviderName, cmd.flagRenderedProviderName,
cmd.flagRenderedWebsiteDir, cmd.flagRenderedWebsiteDir,

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package cmd package cmd
import ( import (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package cmd package cmd
//TODO: this command can run an emulated server to simulate the registry //TODO: this command can run an emulated server to simulate the registry

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package cmd package cmd
import ( import (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package mdplain package mdplain
import "github.com/russross/blackfriday" import "github.com/russross/blackfriday"

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package mdplain package mdplain
import ( import (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package provider package provider
import ( import (
@ -64,15 +67,17 @@ var (
type generator struct { type generator struct {
ignoreDeprecated bool ignoreDeprecated bool
legacySidebar bool
tfVersion string tfVersion string
// providerDir is the absolute path to the root provider directory
providerDir string
providerName string providerName string
renderedProviderName string renderedProviderName string
renderedWebsiteDir string renderedWebsiteDir string
examplesDir string examplesDir string
templatesDir string
websiteTmpDir string websiteTmpDir string
websiteSourceDir string
ui cli.Ui ui cli.Ui
} }
@ -85,18 +90,48 @@ func (g *generator) warnf(format string, a ...interface{}) {
g.ui.Warn(fmt.Sprintf(format, a...)) g.ui.Warn(fmt.Sprintf(format, a...))
} }
func Generate(ui cli.Ui, legacySidebar bool, providerName, renderedProviderName, renderedWebsiteDir, examplesDir, websiteTmpDir, websiteSourceDir, tfVersion string, ignoreDeprecated bool) error { func Generate(ui cli.Ui, providerDir, providerName, renderedProviderName, renderedWebsiteDir, examplesDir, websiteTmpDir, templatesDir, tfVersion string, ignoreDeprecated bool) error {
// Ensure provider directory is resolved absolute path
if providerDir == "" {
wd, err := os.Getwd()
if err != nil {
return fmt.Errorf("error getting working directory: %w", err)
}
providerDir = wd
} else {
absProviderDir, err := filepath.Abs(providerDir)
if err != nil {
return fmt.Errorf("error getting absolute path with provider directory %q: %w", providerDir, err)
}
providerDir = absProviderDir
}
// Verify provider directory
providerDirFileInfo, err := os.Stat(providerDir)
if err != nil {
return fmt.Errorf("error getting information for provider directory %q: %w", providerDir, err)
}
if !providerDirFileInfo.IsDir() {
return fmt.Errorf("expected %q to be a directory", providerDir)
}
g := &generator{ g := &generator{
ignoreDeprecated: ignoreDeprecated, ignoreDeprecated: ignoreDeprecated,
legacySidebar: legacySidebar,
tfVersion: tfVersion, tfVersion: tfVersion,
providerDir: providerDir,
providerName: providerName, providerName: providerName,
renderedProviderName: renderedProviderName, renderedProviderName: renderedProviderName,
renderedWebsiteDir: renderedWebsiteDir, renderedWebsiteDir: renderedWebsiteDir,
examplesDir: examplesDir, examplesDir: examplesDir,
templatesDir: templatesDir,
websiteTmpDir: websiteTmpDir, websiteTmpDir: websiteTmpDir,
websiteSourceDir: websiteSourceDir,
ui: ui, ui: ui,
} }
@ -109,14 +144,9 @@ func Generate(ui cli.Ui, legacySidebar bool, providerName, renderedProviderName,
func (g *generator) Generate(ctx context.Context) error { func (g *generator) Generate(ctx context.Context) error {
var err error var err error
wd, err := os.Getwd()
if err != nil {
return err
}
providerName := g.providerName providerName := g.providerName
if g.providerName == "" { if g.providerName == "" {
providerName = filepath.Base(wd) providerName = filepath.Base(g.providerDir)
} }
if g.renderedProviderName == "" { if g.renderedProviderName == "" {
@ -146,19 +176,19 @@ func (g *generator) Generate(ctx context.Context) error {
} }
} }
websiteSourceDirInfo, err := os.Stat(g.websiteSourceDir) templatesDirInfo, err := os.Stat(g.ProviderTemplatesDir())
switch { switch {
case os.IsNotExist(err): case os.IsNotExist(err):
// do nothing, no template dir // do nothing, no template dir
case err != nil: case err != nil:
return err return err
default: default:
if !websiteSourceDirInfo.IsDir() { if !templatesDirInfo.IsDir() {
return fmt.Errorf("template path is not a directory: %s", g.websiteSourceDir) return fmt.Errorf("template path is not a directory: %s", g.ProviderTemplatesDir())
} }
g.infof("copying any existing content to tmp dir") g.infof("copying any existing content to tmp dir")
err = cp(g.websiteSourceDir, filepath.Join(g.websiteTmpDir, "templates")) err = cp(g.ProviderTemplatesDir(), g.TempTemplatesDir())
if err != nil { if err != nil {
return err return err
} }
@ -182,44 +212,63 @@ func (g *generator) Generate(ctx context.Context) error {
return err return err
} }
// TODO: may not ever need this, unsure on when this will go live
if g.legacySidebar {
g.infof("rendering legacy sidebar...")
g.warnf("TODO...!")
}
return nil return nil
} }
// ProviderDocsDir returns the absolute path to the joined provider and
// given website documentation directory, which defaults to "docs".
func (g generator) ProviderDocsDir() string {
return filepath.Join(g.providerDir, g.renderedWebsiteDir)
}
// ProviderExamplesDir returns the absolute path to the joined provider and
// given examples directory, which defaults to "examples".
func (g generator) ProviderExamplesDir() string {
return filepath.Join(g.providerDir, g.examplesDir)
}
// ProviderTemplatesDir returns the absolute path to the joined provider and
// given templates directory, which defaults to "templates".
func (g generator) ProviderTemplatesDir() string {
return filepath.Join(g.providerDir, g.templatesDir)
}
// TempTemplatesDir returns the absolute path to the joined temporary and
// hardcoded "templates" sub-directory, which is where provider templates are
// copied.
func (g generator) TempTemplatesDir() string {
return filepath.Join(g.websiteTmpDir, "templates")
}
func (g *generator) renderMissingResourceDoc(providerName, name, typeName string, schema *tfjson.Schema, websiteFileTemplate resourceFileTemplate, fallbackWebsiteFileTemplate resourceFileTemplate, websiteStaticCandidateTemplates []resourceFileTemplate, examplesFileTemplate resourceFileTemplate, examplesImportTemplate *resourceFileTemplate) error { func (g *generator) renderMissingResourceDoc(providerName, name, typeName string, schema *tfjson.Schema, websiteFileTemplate resourceFileTemplate, fallbackWebsiteFileTemplate resourceFileTemplate, websiteStaticCandidateTemplates []resourceFileTemplate, examplesFileTemplate resourceFileTemplate, examplesImportTemplate *resourceFileTemplate) error {
tmplPath, err := websiteFileTemplate.Render(name, providerName) tmplPath, err := websiteFileTemplate.Render(g.providerDir, name, providerName)
if err != nil { if err != nil {
return fmt.Errorf("unable to render path for resource %q: %w", name, err) return fmt.Errorf("unable to render path for resource %q: %w", name, err)
} }
tmplPath = filepath.Join(g.websiteTmpDir, g.websiteSourceDir, tmplPath) tmplPath = filepath.Join(g.TempTemplatesDir(), tmplPath)
if fileExists(tmplPath) { if fileExists(tmplPath) {
g.infof("resource %q template exists, skipping", name) g.infof("resource %q template exists, skipping", name)
return nil return nil
} }
for _, candidate := range websiteStaticCandidateTemplates { for _, candidate := range websiteStaticCandidateTemplates {
candidatePath, err := candidate.Render(name, providerName) candidatePath, err := candidate.Render(g.providerDir, name, providerName)
if err != nil { if err != nil {
return fmt.Errorf("unable to render path for resource %q: %w", name, err) return fmt.Errorf("unable to render path for resource %q: %w", name, err)
} }
candidatePath = filepath.Join(g.websiteTmpDir, g.websiteSourceDir, candidatePath) candidatePath = filepath.Join(g.TempTemplatesDir(), candidatePath)
if fileExists(candidatePath) { if fileExists(candidatePath) {
g.infof("resource %q static file exists, skipping", name) g.infof("resource %q static file exists, skipping", name)
return nil return nil
} }
} }
examplePath, err := examplesFileTemplate.Render(name, providerName) examplePath, err := examplesFileTemplate.Render(g.providerDir, name, providerName)
if err != nil { if err != nil {
return fmt.Errorf("unable to render example file path for %q: %w", name, err) return fmt.Errorf("unable to render example file path for %q: %w", name, err)
} }
if examplePath != "" { if examplePath != "" {
examplePath = filepath.Join(g.examplesDir, examplePath) examplePath = filepath.Join(g.ProviderExamplesDir(), examplePath)
} }
if !fileExists(examplePath) { if !fileExists(examplePath) {
examplePath = "" examplePath = ""
@ -227,12 +276,12 @@ func (g *generator) renderMissingResourceDoc(providerName, name, typeName string
importPath := "" importPath := ""
if examplesImportTemplate != nil { if examplesImportTemplate != nil {
importPath, err = examplesImportTemplate.Render(name, providerName) importPath, err = examplesImportTemplate.Render(g.providerDir, name, providerName)
if err != nil { if err != nil {
return fmt.Errorf("unable to render example import file path for %q: %w", name, err) return fmt.Errorf("unable to render example import file path for %q: %w", name, err)
} }
if importPath != "" { if importPath != "" {
importPath = filepath.Join(g.examplesDir, importPath) importPath = filepath.Join(g.ProviderExamplesDir(), importPath)
} }
if !fileExists(importPath) { if !fileExists(importPath) {
importPath = "" importPath = ""
@ -241,11 +290,11 @@ func (g *generator) renderMissingResourceDoc(providerName, name, typeName string
targetResourceTemplate := defaultResourceTemplate targetResourceTemplate := defaultResourceTemplate
fallbackTmplPath, err := fallbackWebsiteFileTemplate.Render(name, providerName) fallbackTmplPath, err := fallbackWebsiteFileTemplate.Render(g.providerDir, name, providerName)
if err != nil { if err != nil {
return fmt.Errorf("unable to render path for resource %q: %w", name, err) return fmt.Errorf("unable to render path for resource %q: %w", name, err)
} }
fallbackTmplPath = filepath.Join(g.websiteTmpDir, g.websiteSourceDir, fallbackTmplPath) fallbackTmplPath = filepath.Join(g.TempTemplatesDir(), fallbackTmplPath)
if fileExists(fallbackTmplPath) { if fileExists(fallbackTmplPath) {
g.infof("resource %q fallback template exists", name) g.infof("resource %q fallback template exists", name)
tmplData, err := os.ReadFile(fallbackTmplPath) tmplData, err := os.ReadFile(fallbackTmplPath)
@ -256,7 +305,7 @@ func (g *generator) renderMissingResourceDoc(providerName, name, typeName string
} }
g.infof("generating template for %q", name) g.infof("generating template for %q", name)
md, err := targetResourceTemplate.Render(name, providerName, g.renderedProviderName, typeName, examplePath, importPath, schema) md, err := targetResourceTemplate.Render(g.providerDir, name, providerName, g.renderedProviderName, typeName, examplePath, importPath, schema)
if err != nil { if err != nil {
return fmt.Errorf("unable to render template for %q: %w", name, err) return fmt.Errorf("unable to render template for %q: %w", name, err)
} }
@ -270,41 +319,41 @@ func (g *generator) renderMissingResourceDoc(providerName, name, typeName string
} }
func (g *generator) renderMissingProviderDoc(providerName string, schema *tfjson.Schema, websiteFileTemplate providerFileTemplate, websiteStaticCandidateTemplates []providerFileTemplate, examplesFileTemplate providerFileTemplate) error { func (g *generator) renderMissingProviderDoc(providerName string, schema *tfjson.Schema, websiteFileTemplate providerFileTemplate, websiteStaticCandidateTemplates []providerFileTemplate, examplesFileTemplate providerFileTemplate) error {
tmplPath, err := websiteFileTemplate.Render(providerName) tmplPath, err := websiteFileTemplate.Render(g.providerDir, providerName)
if err != nil { if err != nil {
return fmt.Errorf("unable to render path for provider %q: %w", providerName, err) return fmt.Errorf("unable to render path for provider %q: %w", providerName, err)
} }
tmplPath = filepath.Join(g.websiteTmpDir, g.websiteSourceDir, tmplPath) tmplPath = filepath.Join(g.TempTemplatesDir(), tmplPath)
if fileExists(tmplPath) { if fileExists(tmplPath) {
g.infof("provider %q template exists, skipping", providerName) g.infof("provider %q template exists, skipping", providerName)
return nil return nil
} }
for _, candidate := range websiteStaticCandidateTemplates { for _, candidate := range websiteStaticCandidateTemplates {
candidatePath, err := candidate.Render(providerName) candidatePath, err := candidate.Render(g.providerDir, providerName)
if err != nil { if err != nil {
return fmt.Errorf("unable to render path for provider %q: %w", providerName, err) return fmt.Errorf("unable to render path for provider %q: %w", providerName, err)
} }
candidatePath = filepath.Join(g.websiteTmpDir, g.websiteSourceDir, candidatePath) candidatePath = filepath.Join(g.TempTemplatesDir(), candidatePath)
if fileExists(candidatePath) { if fileExists(candidatePath) {
g.infof("provider %q static file exists, skipping", providerName) g.infof("provider %q static file exists, skipping", providerName)
return nil return nil
} }
} }
examplePath, err := examplesFileTemplate.Render(providerName) examplePath, err := examplesFileTemplate.Render(g.providerDir, providerName)
if err != nil { if err != nil {
return fmt.Errorf("unable to render example file path for %q: %w", providerName, err) return fmt.Errorf("unable to render example file path for %q: %w", providerName, err)
} }
if examplePath != "" { if examplePath != "" {
examplePath = filepath.Join(g.examplesDir, examplePath) examplePath = filepath.Join(g.ProviderExamplesDir(), examplePath)
} }
if !fileExists(examplePath) { if !fileExists(examplePath) {
examplePath = "" examplePath = ""
} }
g.infof("generating template for %q", providerName) g.infof("generating template for %q", providerName)
md, err := defaultProviderTemplate.Render(providerName, g.renderedProviderName, examplePath, schema) md, err := defaultProviderTemplate.Render(g.providerDir, providerName, g.renderedProviderName, examplePath, schema)
if err != nil { if err != nil {
return fmt.Errorf("unable to render template for %q: %w", providerName, err) return fmt.Errorf("unable to render template for %q: %w", providerName, err)
} }
@ -367,7 +416,7 @@ func (g *generator) renderMissingDocs(providerName string, providerSchema *tfjso
func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfjson.ProviderSchema) error { func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfjson.ProviderSchema) error {
g.infof("cleaning rendered website dir") g.infof("cleaning rendered website dir")
err := os.RemoveAll(g.renderedWebsiteDir) err := os.RemoveAll(g.ProviderDocsDir())
if err != nil { if err != nil {
return err return err
} }
@ -382,7 +431,7 @@ func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfj
return nil return nil
} }
rel, err := filepath.Rel(filepath.Join(g.websiteTmpDir, g.websiteSourceDir), path) rel, err := filepath.Rel(filepath.Join(g.TempTemplatesDir()), path)
if err != nil { if err != nil {
return err return err
} }
@ -395,7 +444,7 @@ func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfj
return nil return nil
} }
renderedPath := filepath.Join(g.renderedWebsiteDir, rel) renderedPath := filepath.Join(g.ProviderDocsDir(), rel)
err = os.MkdirAll(filepath.Dir(renderedPath), 0755) err = os.MkdirAll(filepath.Dir(renderedPath), 0755)
if err != nil { if err != nil {
return err return err
@ -424,10 +473,11 @@ func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfj
switch relDir { switch relDir {
case "data-sources/": case "data-sources/":
resSchema, resName := resourceSchema(providerSchema.DataSourceSchemas, shortName, relFile) resSchema, resName := resourceSchema(providerSchema.DataSourceSchemas, shortName, relFile)
exampleFilePath := filepath.Join(g.examplesDir, "data-sources", resName, "data-source.tf") exampleFilePath := filepath.Join(g.ProviderExamplesDir(), "data-sources", resName, "data-source.tf")
if resSchema != nil { if resSchema != nil {
tmpl := resourceTemplate(tmplData) tmpl := resourceTemplate(tmplData)
render, err := tmpl.Render(resName, providerName, g.renderedProviderName, "Data Source", exampleFilePath, "", resSchema) render, err := tmpl.Render(g.providerDir, resName, providerName, g.renderedProviderName, "Data Source", exampleFilePath, "", resSchema)
if err != nil { if err != nil {
return fmt.Errorf("unable to render data source template %q: %w", rel, err) return fmt.Errorf("unable to render data source template %q: %w", rel, err)
} }
@ -440,12 +490,12 @@ func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfj
g.warnf("data source entitled %q, or %q does not exist", shortName, resName) g.warnf("data source entitled %q, or %q does not exist", shortName, resName)
case "resources/": case "resources/":
resSchema, resName := resourceSchema(providerSchema.ResourceSchemas, shortName, relFile) resSchema, resName := resourceSchema(providerSchema.ResourceSchemas, shortName, relFile)
exampleFilePath := filepath.Join(g.examplesDir, "resources", resName, "resource.tf") exampleFilePath := filepath.Join(g.ProviderExamplesDir(), "resources", resName, "resource.tf")
importFilePath := filepath.Join(g.examplesDir, "resources", resName, "import.sh") importFilePath := filepath.Join(g.ProviderExamplesDir(), "resources", resName, "import.sh")
if resSchema != nil { if resSchema != nil {
tmpl := resourceTemplate(tmplData) tmpl := resourceTemplate(tmplData)
render, err := tmpl.Render(resName, providerName, g.renderedProviderName, "Resource", exampleFilePath, importFilePath, resSchema) render, err := tmpl.Render(g.providerDir, resName, providerName, g.renderedProviderName, "Resource", exampleFilePath, importFilePath, resSchema)
if err != nil { if err != nil {
return fmt.Errorf("unable to render resource template %q: %w", rel, err) return fmt.Errorf("unable to render resource template %q: %w", rel, err)
} }
@ -459,8 +509,8 @@ func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfj
case "": // provider case "": // provider
if relFile == "index.md.tmpl" { if relFile == "index.md.tmpl" {
tmpl := providerTemplate(tmplData) tmpl := providerTemplate(tmplData)
exampleFilePath := filepath.Join(g.examplesDir, "provider", "provider.tf") exampleFilePath := filepath.Join(g.ProviderExamplesDir(), "provider", "provider.tf")
render, err := tmpl.Render(providerName, g.renderedProviderName, exampleFilePath, providerSchema.ConfigSchema) render, err := tmpl.Render(g.providerDir, providerName, g.renderedProviderName, exampleFilePath, providerSchema.ConfigSchema)
if err != nil { if err != nil {
return fmt.Errorf("unable to render provider template %q: %w", rel, err) return fmt.Errorf("unable to render provider template %q: %w", rel, err)
} }
@ -473,7 +523,7 @@ func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfj
} }
tmpl := docTemplate(tmplData) tmpl := docTemplate(tmplData)
err = tmpl.Render(out) err = tmpl.Render(g.providerDir, out)
if err != nil { if err != nil {
return fmt.Errorf("unable to render template %q: %w", rel, err) return fmt.Errorf("unable to render template %q: %w", rel, err)
} }
@ -510,6 +560,7 @@ func (g *generator) terraformProviderSchema(ctx context.Context, providerName st
outFile = outFile + ".exe" outFile = outFile + ".exe"
} }
buildCmd := exec.Command("go", "build", "-o", outFile) buildCmd := exec.Command("go", "build", "-o", outFile)
buildCmd.Dir = g.providerDir
// TODO: constrain env here to make it a little safer? // TODO: constrain env here to make it a little safer?
_, err = runCmd(buildCmd) _, err = runCmd(buildCmd)
if err != nil { if err != nil {

View File

@ -1,9 +1,13 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package provider package provider
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"io" "io"
"path/filepath"
"strings" "strings"
"text/template" "text/template"
@ -32,17 +36,17 @@ type (
docTemplate string docTemplate string
) )
func newTemplate(name, text string) (*template.Template, error) { func newTemplate(providerDir, name, text string) (*template.Template, error) {
tmpl := template.New(name) tmpl := template.New(name)
titleCaser := cases.Title(language.Und) titleCaser := cases.Title(language.Und)
tmpl.Funcs(map[string]interface{}{ tmpl.Funcs(map[string]interface{}{
"codefile": tmplfuncs.CodeFile, "codefile": codeFile(providerDir),
"lower": strings.ToLower, "lower": strings.ToLower,
"plainmarkdown": mdplain.PlainMarkdown, "plainmarkdown": mdplain.PlainMarkdown,
"prefixlines": tmplfuncs.PrefixLines, "prefixlines": tmplfuncs.PrefixLines,
"split": strings.Split, "split": strings.Split,
"tffile": terraformCodeFile, "tffile": terraformCodeFile(providerDir),
"title": titleCaser.String, "title": titleCaser.String,
"trimspace": strings.TrimSpace, "trimspace": strings.TrimSpace,
"upper": strings.ToUpper, "upper": strings.ToUpper,
@ -57,13 +61,29 @@ func newTemplate(name, text string) (*template.Template, error) {
return tmpl, nil return tmpl, nil
} }
func terraformCodeFile(file string) (string, error) { func codeFile(providerDir string) func(string, string) (string, error) {
// TODO: omit comment handling return func(format string, file string) (string, error) {
return tmplfuncs.CodeFile("terraform", file) if filepath.IsAbs(file) {
return tmplfuncs.CodeFile(format, file)
}
return tmplfuncs.CodeFile(format, filepath.Join(providerDir, file))
}
} }
func renderTemplate(name string, text string, out io.Writer, data interface{}) error { func terraformCodeFile(providerDir string) func(string) (string, error) {
tmpl, err := newTemplate(name, text) // TODO: omit comment handling
return func(file string) (string, error) {
if filepath.IsAbs(file) {
return tmplfuncs.CodeFile("terraform", file)
}
return tmplfuncs.CodeFile("terraform", filepath.Join(providerDir, file))
}
}
func renderTemplate(providerDir, name string, text string, out io.Writer, data interface{}) error {
tmpl, err := newTemplate(providerDir, name, text)
if err != nil { if err != nil {
return err return err
} }
@ -76,10 +96,10 @@ func renderTemplate(name string, text string, out io.Writer, data interface{}) e
return nil return nil
} }
func renderStringTemplate(name, text string, data interface{}) (string, error) { func renderStringTemplate(providerDir, name, text string, data interface{}) (string, error) {
var buf bytes.Buffer var buf bytes.Buffer
err := renderTemplate(name, text, &buf, data) err := renderTemplate(providerDir, name, text, &buf, data)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -87,21 +107,21 @@ func renderStringTemplate(name, text string, data interface{}) (string, error) {
return buf.String(), nil return buf.String(), nil
} }
func (t docTemplate) Render(out io.Writer) error { func (t docTemplate) Render(providerDir string, out io.Writer) error {
s := string(t) s := string(t)
if s == "" { if s == "" {
return nil return nil
} }
return renderTemplate("docTemplate", s, out, nil) return renderTemplate(providerDir, "docTemplate", s, out, nil)
} }
func (t resourceFileTemplate) Render(name, providerName string) (string, error) { func (t resourceFileTemplate) Render(providerDir, name, providerName string) (string, error) {
s := string(t) s := string(t)
if s == "" { if s == "" {
return "", nil return "", nil
} }
return renderStringTemplate("resourceFileTemplate", s, struct { return renderStringTemplate(providerDir, "resourceFileTemplate", s, struct {
Name string Name string
ShortName string ShortName string
@ -116,18 +136,18 @@ func (t resourceFileTemplate) Render(name, providerName string) (string, error)
}) })
} }
func (t providerFileTemplate) Render(name string) (string, error) { func (t providerFileTemplate) Render(providerDir, name string) (string, error) {
s := string(t) s := string(t)
if s == "" { if s == "" {
return "", nil return "", nil
} }
return renderStringTemplate("providerFileTemplate", s, struct { return renderStringTemplate(providerDir, "providerFileTemplate", s, struct {
Name string Name string
ShortName string ShortName string
}{name, providerShortName(name)}) }{name, providerShortName(name)})
} }
func (t providerTemplate) Render(providerName, renderedProviderName, exampleFile string, schema *tfjson.Schema) (string, error) { func (t providerTemplate) Render(providerDir, providerName, renderedProviderName, exampleFile string, schema *tfjson.Schema) (string, error) {
schemaBuffer := bytes.NewBuffer(nil) schemaBuffer := bytes.NewBuffer(nil)
err := schemamd.Render(schema, schemaBuffer) err := schemamd.Render(schema, schemaBuffer)
if err != nil { if err != nil {
@ -138,7 +158,8 @@ func (t providerTemplate) Render(providerName, renderedProviderName, exampleFile
if s == "" { if s == "" {
return "", nil return "", nil
} }
return renderStringTemplate("providerTemplate", s, struct {
return renderStringTemplate(providerDir, "providerTemplate", s, struct {
Description string Description string
HasExample bool HasExample bool
@ -165,7 +186,7 @@ func (t providerTemplate) Render(providerName, renderedProviderName, exampleFile
}) })
} }
func (t resourceTemplate) Render(name, providerName, renderedProviderName, typeName, exampleFile, importFile string, schema *tfjson.Schema) (string, error) { func (t resourceTemplate) Render(providerDir, name, providerName, renderedProviderName, typeName, exampleFile, importFile string, schema *tfjson.Schema) (string, error) {
schemaBuffer := bytes.NewBuffer(nil) schemaBuffer := bytes.NewBuffer(nil)
err := schemamd.Render(schema, schemaBuffer) err := schemamd.Render(schema, schemaBuffer)
if err != nil { if err != nil {
@ -177,7 +198,7 @@ func (t resourceTemplate) Render(name, providerName, renderedProviderName, typeN
return "", nil return "", nil
} }
return renderStringTemplate("resourceTemplate", s, struct { return renderStringTemplate(providerDir, "resourceTemplate", s, struct {
Type string Type string
Name string Name string
Description string Description string
@ -233,8 +254,8 @@ description: |-
{{- end }} {{- end }}
{{ .SchemaMarkdown | trimspace }} {{ .SchemaMarkdown | trimspace }}
{{- if .HasImport }}
{{ if .HasImport -}}
## Import ## Import
Import is supported using the following syntax: Import is supported using the following syntax:

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package provider package provider
import ( import (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package provider package provider
import ( import (

View File

@ -1,9 +1,11 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package tmplfuncs package tmplfuncs
import ( import (
"fmt" "fmt"
"os" "os"
"path/filepath"
"strings" "strings"
) )
@ -12,15 +14,7 @@ func PrefixLines(prefix, text string) string {
} }
func CodeFile(format, file string) (string, error) { func CodeFile(format, file string) (string, error) {
// paths are relative to the rendering process work dir, which content, err := os.ReadFile(file)
// may be undesirable, probably need to think about it
wd, err := os.Getwd()
if err != nil {
return "", err
}
fullPath := filepath.Join(wd, file)
content, err := os.ReadFile(fullPath)
if err != nil { if err != nil {
return "", fmt.Errorf("unable to read content from %q: %w", file, err) return "", fmt.Errorf("unable to read content from %q: %w", file, err)
} }

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package schemamd package schemamd
import ( import (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package schemamd package schemamd
import ( import (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package schemamd package schemamd
import ( import (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package schemamd package schemamd
import ( import (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package schemamd package schemamd
import ( import (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package schemamd package schemamd
import ( import (

4
vendor/modules.txt vendored
View File

@ -142,8 +142,8 @@ github.com/hashicorp/terraform-exec/tfexec
# github.com/hashicorp/terraform-json v0.17.0 # github.com/hashicorp/terraform-json v0.17.0
## explicit; go 1.18 ## explicit; go 1.18
github.com/hashicorp/terraform-json github.com/hashicorp/terraform-json
# github.com/hashicorp/terraform-plugin-docs v0.14.1 # github.com/hashicorp/terraform-plugin-docs v0.15.0
## explicit; go 1.18 ## explicit; go 1.19
github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs
github.com/hashicorp/terraform-plugin-docs/internal/cmd github.com/hashicorp/terraform-plugin-docs/internal/cmd
github.com/hashicorp/terraform-plugin-docs/internal/mdplain github.com/hashicorp/terraform-plugin-docs/internal/mdplain