From 81e91634a5832922c2b7f615bbbadfa58da77572 Mon Sep 17 00:00:00 2001 From: SBGoods Date: Thu, 29 Jun 2023 13:22:05 -0400 Subject: [PATCH 1/6] Introduce exclude-rendered-website-sub-dir flag --- README.md | 19 ++++++++------- internal/cmd/generate.go | 15 +++++++----- internal/provider/generate.go | 44 +++++++++++++++++++++++------------ 3 files changed, 48 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 0cfde412..bc50e2d6 100644 --- a/README.md +++ b/README.md @@ -39,15 +39,16 @@ $ tfplugindocs generate --help Usage: tfplugindocs generate [] - --examples-dir examples directory based on provider-dir (default: "examples") - --ignore-deprecated don't generate documentation for deprecated resources and data-sources (default: "false") - --provider-dir relative or absolute path to the root provider code directory when running the command outside the root provider code directory - --provider-name provider name, as used in Terraform configurations - --rendered-provider-name provider name, as generated in documentation (ex. page titles, ...) - --rendered-website-dir output directory based on provider-dir (default: "docs") - --tf-version terraform binary version to download - --website-source-dir templates directory based on provider-dir (default: "templates") - --website-temp-dir temporary directory (used during generation) + --examples-dir examples directory based on provider-dir (default: "examples") + --exclude-rendered-website-sub-dir excludes a subdirectory within rendered-website-dir from being deleted during documentation generation + --ignore-deprecated don't generate documentation for deprecated resources and data-sources (default: "false") + --provider-dir relative or absolute path to the root provider code directory when running the command outside the root provider code directory + --provider-name provider name, as used in Terraform configurations + --rendered-provider-name provider name, as generated in documentation (ex. page titles, ...) + --rendered-website-dir output directory based on provider-dir (default: "docs") + --tf-version terraform binary version to download + --website-source-dir templates directory based on provider-dir (default: "templates") + --website-temp-dir temporary directory (used during generation) ``` `validate` command: diff --git a/internal/cmd/generate.go b/internal/cmd/generate.go index 29b25ed5..00606cd2 100644 --- a/internal/cmd/generate.go +++ b/internal/cmd/generate.go @@ -19,12 +19,13 @@ type generateCmd struct { flagProviderName string flagRenderedProviderName string - flagProviderDir string - flagRenderedWebsiteDir string - flagExamplesDir string - flagWebsiteTmpDir string - flagWebsiteSourceDir string - tfVersion string + flagProviderDir string + flagRenderedWebsiteDir string + flagExamplesDir string + flagExcludeRenderedWebsiteSubDir string + flagWebsiteTmpDir string + flagWebsiteSourceDir string + tfVersion string } func (cmd *generateCmd) Synopsis() string { @@ -76,6 +77,7 @@ func (cmd *generateCmd) Flags() *flag.FlagSet { 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 based on provider-dir") fs.StringVar(&cmd.flagExamplesDir, "examples-dir", "examples", "examples directory based on provider-dir") + fs.StringVar(&cmd.flagExcludeRenderedWebsiteSubDir, "exclude-rendered-website-sub-dir", "", "excludes a subdirectory within rendered-website-dir from being deleted during documentation generation") fs.StringVar(&cmd.flagWebsiteTmpDir, "website-temp-dir", "", "temporary directory (used during generation)") 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") @@ -102,6 +104,7 @@ func (cmd *generateCmd) runInternal() error { cmd.flagRenderedProviderName, cmd.flagRenderedWebsiteDir, cmd.flagExamplesDir, + cmd.flagExcludeRenderedWebsiteSubDir, cmd.flagWebsiteTmpDir, cmd.flagWebsiteSourceDir, cmd.tfVersion, diff --git a/internal/provider/generate.go b/internal/provider/generate.go index 71fd1f8a..4d40b900 100644 --- a/internal/provider/generate.go +++ b/internal/provider/generate.go @@ -8,6 +8,7 @@ import ( "fmt" "os" "os/exec" + "path" "path/filepath" "runtime" "strings" @@ -72,12 +73,13 @@ type generator struct { // providerDir is the absolute path to the root provider directory providerDir string - providerName string - renderedProviderName string - renderedWebsiteDir string - examplesDir string - templatesDir string - websiteTmpDir string + providerName string + renderedProviderName string + renderedWebsiteDir string + examplesDir string + excludeRenderedWebsiteSubDir string + templatesDir string + websiteTmpDir string ui cli.Ui } @@ -90,7 +92,7 @@ func (g *generator) warnf(format string, a ...interface{}) { g.ui.Warn(fmt.Sprintf(format, a...)) } -func Generate(ui cli.Ui, providerDir, providerName, renderedProviderName, renderedWebsiteDir, examplesDir, websiteTmpDir, templatesDir, tfVersion string, ignoreDeprecated bool) error { +func Generate(ui cli.Ui, providerDir, providerName, renderedProviderName, renderedWebsiteDir, examplesDir, excludeRenderedWebsiteSubDir, websiteTmpDir, templatesDir, tfVersion string, ignoreDeprecated bool) error { // Ensure provider directory is resolved absolute path if providerDir == "" { wd, err := os.Getwd() @@ -125,13 +127,14 @@ func Generate(ui cli.Ui, providerDir, providerName, renderedProviderName, render ignoreDeprecated: ignoreDeprecated, tfVersion: tfVersion, - providerDir: providerDir, - providerName: providerName, - renderedProviderName: renderedProviderName, - renderedWebsiteDir: renderedWebsiteDir, - examplesDir: examplesDir, - templatesDir: templatesDir, - websiteTmpDir: websiteTmpDir, + providerDir: providerDir, + providerName: providerName, + renderedProviderName: renderedProviderName, + renderedWebsiteDir: renderedWebsiteDir, + examplesDir: examplesDir, + excludeRenderedWebsiteSubDir: excludeRenderedWebsiteSubDir, + templatesDir: templatesDir, + websiteTmpDir: websiteTmpDir, ui: ui, } @@ -416,11 +419,22 @@ func (g *generator) renderMissingDocs(providerName string, providerSchema *tfjso func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfjson.ProviderSchema) error { g.infof("cleaning rendered website dir") - err := os.RemoveAll(g.ProviderDocsDir()) + dirEntry, err := os.ReadDir(g.ProviderDocsDir()) if err != nil { return err } + for _, file := range dirEntry { + if file.IsDir() && file.Name() == g.excludeRenderedWebsiteSubDir { + g.infof("excluding specified sub dir %q from cleanup", g.excludeRenderedWebsiteSubDir) + continue + } + err = os.RemoveAll(path.Join(g.ProviderDocsDir(), file.Name())) + if err != nil { + return err + } + } + shortName := providerShortName(providerName) g.infof("rendering templated website to static markdown") From f6f5a3a8e0649452de2d47dd157f980b08a1f741 Mon Sep 17 00:00:00 2001 From: SBGoods Date: Thu, 29 Jun 2023 13:22:52 -0400 Subject: [PATCH 2/6] Add "cdktf" to list of allowed directories --- internal/provider/validate.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/provider/validate.go b/internal/provider/validate.go index c2748e80..329e05d1 100644 --- a/internal/provider/validate.go +++ b/internal/provider/validate.go @@ -98,6 +98,7 @@ func validateStaticDocs(ui cli.Ui, dir string) error { "data-sources", "guides", "resources", + "cdktf", ), checkBlockedExtensions( ".html.md.tmpl", From e8894f5e5d9db6b72350e688047b0b9272166af0 Mon Sep 17 00:00:00 2001 From: SBGoods Date: Thu, 29 Jun 2023 14:41:44 -0400 Subject: [PATCH 3/6] Add Changie entry --- .changes/unreleased/ENHANCEMENTS-20230629-144119.yaml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changes/unreleased/ENHANCEMENTS-20230629-144119.yaml diff --git a/.changes/unreleased/ENHANCEMENTS-20230629-144119.yaml b/.changes/unreleased/ENHANCEMENTS-20230629-144119.yaml new file mode 100644 index 00000000..32ef6726 --- /dev/null +++ b/.changes/unreleased/ENHANCEMENTS-20230629-144119.yaml @@ -0,0 +1,7 @@ +kind: ENHANCEMENTS +body: 'generate: Added `exclude-rendered-website-sub-dir` flag, which excludes the + specified subdirectory in the rendered website directory from being deleted during + generation' +time: 2023-06-29T14:41:19.134991-04:00 +custom: + Issue: "267" From 912e43d8564dd08c02a3c2069943dc6819dab683 Mon Sep 17 00:00:00 2001 From: SBGoods Date: Wed, 5 Jul 2023 15:52:34 -0400 Subject: [PATCH 4/6] Revert `exclude-rendered-website-sub-dir` flag and only remove files and directories directly managed by `tfplugindocs` --- .../ENHANCEMENTS-20230629-144119.yaml | 5 +- README.md | 19 +++--- go.mod | 3 +- go.sum | 6 +- internal/cmd/generate.go | 15 ++--- internal/provider/generate.go | 63 ++++++++++++------- 6 files changed, 65 insertions(+), 46 deletions(-) diff --git a/.changes/unreleased/ENHANCEMENTS-20230629-144119.yaml b/.changes/unreleased/ENHANCEMENTS-20230629-144119.yaml index 32ef6726..16982145 100644 --- a/.changes/unreleased/ENHANCEMENTS-20230629-144119.yaml +++ b/.changes/unreleased/ENHANCEMENTS-20230629-144119.yaml @@ -1,7 +1,6 @@ kind: ENHANCEMENTS -body: 'generate: Added `exclude-rendered-website-sub-dir` flag, which excludes the - specified subdirectory in the rendered website directory from being deleted during - generation' +body: 'generate: Prevent files and subdirectories in the rendered website directory + that are not directly managed by `tfplugindocs` from being deleted during generation' time: 2023-06-29T14:41:19.134991-04:00 custom: Issue: "267" diff --git a/README.md b/README.md index bc50e2d6..0cfde412 100644 --- a/README.md +++ b/README.md @@ -39,16 +39,15 @@ $ tfplugindocs generate --help Usage: tfplugindocs generate [] - --examples-dir examples directory based on provider-dir (default: "examples") - --exclude-rendered-website-sub-dir excludes a subdirectory within rendered-website-dir from being deleted during documentation generation - --ignore-deprecated don't generate documentation for deprecated resources and data-sources (default: "false") - --provider-dir relative or absolute path to the root provider code directory when running the command outside the root provider code directory - --provider-name provider name, as used in Terraform configurations - --rendered-provider-name provider name, as generated in documentation (ex. page titles, ...) - --rendered-website-dir output directory based on provider-dir (default: "docs") - --tf-version terraform binary version to download - --website-source-dir templates directory based on provider-dir (default: "templates") - --website-temp-dir temporary directory (used during generation) + --examples-dir examples directory based on provider-dir (default: "examples") + --ignore-deprecated don't generate documentation for deprecated resources and data-sources (default: "false") + --provider-dir relative or absolute path to the root provider code directory when running the command outside the root provider code directory + --provider-name provider name, as used in Terraform configurations + --rendered-provider-name provider name, as generated in documentation (ex. page titles, ...) + --rendered-website-dir output directory based on provider-dir (default: "docs") + --tf-version terraform binary version to download + --website-source-dir templates directory based on provider-dir (default: "templates") + --website-temp-dir temporary directory (used during generation) ``` `validate` command: diff --git a/go.mod b/go.mod index 7b47ad7e..9df512c2 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/mitchellh/cli v1.1.5 github.com/russross/blackfriday v1.6.0 github.com/zclconf/go-cty v1.13.2 + golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df golang.org/x/text v0.10.0 ) @@ -40,6 +41,6 @@ require ( github.com/shopspring/decimal v1.3.1 // indirect github.com/spf13/cast v1.5.0 // indirect golang.org/x/crypto v0.8.0 // indirect - golang.org/x/mod v0.10.0 // indirect + golang.org/x/mod v0.11.0 // indirect golang.org/x/sys v0.7.0 // indirect ) diff --git a/go.sum b/go.sum index 638e82b0..e07ae1ac 100644 --- a/go.sum +++ b/go.sum @@ -118,8 +118,10 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +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.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= +golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= diff --git a/internal/cmd/generate.go b/internal/cmd/generate.go index 00606cd2..29b25ed5 100644 --- a/internal/cmd/generate.go +++ b/internal/cmd/generate.go @@ -19,13 +19,12 @@ type generateCmd struct { flagProviderName string flagRenderedProviderName string - flagProviderDir string - flagRenderedWebsiteDir string - flagExamplesDir string - flagExcludeRenderedWebsiteSubDir string - flagWebsiteTmpDir string - flagWebsiteSourceDir string - tfVersion string + flagProviderDir string + flagRenderedWebsiteDir string + flagExamplesDir string + flagWebsiteTmpDir string + flagWebsiteSourceDir string + tfVersion string } func (cmd *generateCmd) Synopsis() string { @@ -77,7 +76,6 @@ func (cmd *generateCmd) Flags() *flag.FlagSet { 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 based on provider-dir") fs.StringVar(&cmd.flagExamplesDir, "examples-dir", "examples", "examples directory based on provider-dir") - fs.StringVar(&cmd.flagExcludeRenderedWebsiteSubDir, "exclude-rendered-website-sub-dir", "", "excludes a subdirectory within rendered-website-dir from being deleted during documentation generation") fs.StringVar(&cmd.flagWebsiteTmpDir, "website-temp-dir", "", "temporary directory (used during generation)") 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") @@ -104,7 +102,6 @@ func (cmd *generateCmd) runInternal() error { cmd.flagRenderedProviderName, cmd.flagRenderedWebsiteDir, cmd.flagExamplesDir, - cmd.flagExcludeRenderedWebsiteSubDir, cmd.flagWebsiteTmpDir, cmd.flagWebsiteSourceDir, cmd.tfVersion, diff --git a/internal/provider/generate.go b/internal/provider/generate.go index 4d40b900..b4c3293f 100644 --- a/internal/provider/generate.go +++ b/internal/provider/generate.go @@ -23,6 +23,7 @@ import ( "github.com/hashicorp/terraform-exec/tfexec" tfjson "github.com/hashicorp/terraform-json" "github.com/mitchellh/cli" + "golang.org/x/exp/slices" ) var ( @@ -64,6 +65,16 @@ var ( providerFileTemplate("index.html.markdown"), providerFileTemplate("index.html.md"), } + + managedWebsiteSubDirectories = []string{ + "data-sources", + "guides", + "resources", + } + + managedWebsiteFiles = []string{ + "index.md", + } ) type generator struct { @@ -73,13 +84,12 @@ type generator struct { // providerDir is the absolute path to the root provider directory providerDir string - providerName string - renderedProviderName string - renderedWebsiteDir string - examplesDir string - excludeRenderedWebsiteSubDir string - templatesDir string - websiteTmpDir string + providerName string + renderedProviderName string + renderedWebsiteDir string + examplesDir string + templatesDir string + websiteTmpDir string ui cli.Ui } @@ -92,7 +102,7 @@ func (g *generator) warnf(format string, a ...interface{}) { g.ui.Warn(fmt.Sprintf(format, a...)) } -func Generate(ui cli.Ui, providerDir, providerName, renderedProviderName, renderedWebsiteDir, examplesDir, excludeRenderedWebsiteSubDir, websiteTmpDir, templatesDir, 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() @@ -127,14 +137,13 @@ func Generate(ui cli.Ui, providerDir, providerName, renderedProviderName, render ignoreDeprecated: ignoreDeprecated, tfVersion: tfVersion, - providerDir: providerDir, - providerName: providerName, - renderedProviderName: renderedProviderName, - renderedWebsiteDir: renderedWebsiteDir, - examplesDir: examplesDir, - excludeRenderedWebsiteSubDir: excludeRenderedWebsiteSubDir, - templatesDir: templatesDir, - websiteTmpDir: websiteTmpDir, + providerDir: providerDir, + providerName: providerName, + renderedProviderName: renderedProviderName, + renderedWebsiteDir: renderedWebsiteDir, + examplesDir: examplesDir, + templatesDir: templatesDir, + websiteTmpDir: websiteTmpDir, ui: ui, } @@ -425,13 +434,25 @@ func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfj } for _, file := range dirEntry { - if file.IsDir() && file.Name() == g.excludeRenderedWebsiteSubDir { - g.infof("excluding specified sub dir %q from cleanup", g.excludeRenderedWebsiteSubDir) + + // Remove subdirectories managed by tfplugindocs + if file.IsDir() && slices.Contains(managedWebsiteSubDirectories, file.Name()) { + g.infof("removing directory: %q", file.Name()) + err = os.RemoveAll(path.Join(g.ProviderDocsDir(), file.Name())) + if err != nil { + return err + } continue } - err = os.RemoveAll(path.Join(g.ProviderDocsDir(), file.Name())) - if err != nil { - return err + + // Remove files managed by tfplugindocs + if !file.IsDir() && slices.Contains(managedWebsiteFiles, file.Name()) { + g.infof("removing file: %q", file.Name()) + err = os.RemoveAll(path.Join(g.ProviderDocsDir(), file.Name())) + if err != nil { + return err + } + continue } } From 2f6f1ef5273f4648db68ea57afe2f634031cf83e Mon Sep 17 00:00:00 2001 From: SBGoods Date: Wed, 5 Jul 2023 16:04:47 -0400 Subject: [PATCH 5/6] Merge branch 'main' into SBGoods/skip-subdir --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 99ed25ac..448b2577 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/russross/blackfriday v1.6.0 github.com/zclconf/go-cty v1.13.2 golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df - golang.org/x/text v0.10.0 + golang.org/x/text v0.11.0 ) require ( From 1d294ea05d7b79e0ba0d2a566fe3c86ceef3ad93 Mon Sep 17 00:00:00 2001 From: SBGoods Date: Thu, 6 Jul 2023 11:15:12 -0400 Subject: [PATCH 6/6] Add changie entry for validate enhancement --- .changes/unreleased/ENHANCEMENTS-20230706-111427.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/unreleased/ENHANCEMENTS-20230706-111427.yaml diff --git a/.changes/unreleased/ENHANCEMENTS-20230706-111427.yaml b/.changes/unreleased/ENHANCEMENTS-20230706-111427.yaml new file mode 100644 index 00000000..2f5c35d6 --- /dev/null +++ b/.changes/unreleased/ENHANCEMENTS-20230706-111427.yaml @@ -0,0 +1,5 @@ +kind: ENHANCEMENTS +body: 'validate: Add `cdktf` to list of allowed rendered website subdirectories' +time: 2023-07-06T11:14:27.351158-04:00 +custom: + Issue: "267"