diff --git a/.changes/unreleased/ENHANCEMENTS-20230606-141357.yaml b/.changes/unreleased/ENHANCEMENTS-20230606-141357.yaml new file mode 100644 index 00000000..891f6806 --- /dev/null +++ b/.changes/unreleased/ENHANCEMENTS-20230606-141357.yaml @@ -0,0 +1,6 @@ +kind: ENHANCEMENTS +body: 'generate: Added `provider-dir` flag, which enables the command to be run from + any directory' +time: 2023-06-06T14:13:57.482032-04:00 +custom: + Issue: "259" diff --git a/README.md b/README.md index 97f16ae9..0cfde412 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Usage: tfplugindocs [--version] [--help] [] Available commands are: the generate command is run by default - generate generates a plugin website from code, templates, and examples for the current directory + generate generates a plugin website from code, templates, and examples validate validates a plugin website for the current directory ``` @@ -39,14 +39,15 @@ $ tfplugindocs generate --help Usage: tfplugindocs generate [] - --examples-dir examples directory (default: "examples") - --ignore-deprecated don't generate documentation for deprecated resources and data-sources (default: "false") - --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 (default: "docs") - --tf-version terraform binary version to download - --website-source-dir templates directory (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: @@ -59,7 +60,7 @@ Usage: tfplugindocs validate [] ### How it Works -When you run `tfplugindocs` from root directory of the provider the tool takes the following actions: +When you run `tfplugindocs`, by default from the root directory of a provider codebase, the tool takes the following actions: * Copy all the templates and static files to a temporary directory * Build (`go build`) a temporary binary of the provider source code diff --git a/internal/cmd/generate.go b/internal/cmd/generate.go index 3bd3468d..29b25ed5 100644 --- a/internal/cmd/generate.go +++ b/internal/cmd/generate.go @@ -19,6 +19,7 @@ type generateCmd struct { flagProviderName string flagRenderedProviderName string + flagProviderDir string flagRenderedWebsiteDir string flagExamplesDir string flagWebsiteTmpDir string @@ -27,7 +28,7 @@ type generateCmd struct { } 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 { @@ -71,11 +72,12 @@ func (cmd *generateCmd) Help() string { func (cmd *generateCmd) Flags() *flag.FlagSet { fs := flag.NewFlagSet("generate", flag.ExitOnError) 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.flagRenderedWebsiteDir, "rendered-website-dir", "docs", "output directory") - fs.StringVar(&cmd.flagExamplesDir, "examples-dir", "examples", "examples directory") + 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.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.BoolVar(&cmd.flagIgnoreDeprecated, "ignore-deprecated", false, "don't generate documentation for deprecated resources and data-sources") return fs @@ -95,6 +97,7 @@ func (cmd *generateCmd) Run(args []string) int { func (cmd *generateCmd) runInternal() error { err := provider.Generate( cmd.ui, + cmd.flagProviderDir, cmd.flagProviderName, cmd.flagRenderedProviderName, cmd.flagRenderedWebsiteDir, diff --git a/internal/provider/generate.go b/internal/provider/generate.go index 388368b6..71fd1f8a 100644 --- a/internal/provider/generate.go +++ b/internal/provider/generate.go @@ -69,12 +69,15 @@ type generator struct { ignoreDeprecated bool tfVersion string + // providerDir is the absolute path to the root provider directory + providerDir string + providerName string renderedProviderName string renderedWebsiteDir string examplesDir string + templatesDir string websiteTmpDir string - websiteSourceDir string ui cli.Ui } @@ -87,17 +90,48 @@ func (g *generator) warnf(format string, a ...interface{}) { g.ui.Warn(fmt.Sprintf(format, a...)) } -func Generate(ui cli.Ui, 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{ ignoreDeprecated: ignoreDeprecated, tfVersion: tfVersion, + providerDir: providerDir, providerName: providerName, renderedProviderName: renderedProviderName, renderedWebsiteDir: renderedWebsiteDir, examplesDir: examplesDir, + templatesDir: templatesDir, websiteTmpDir: websiteTmpDir, - websiteSourceDir: websiteSourceDir, ui: ui, } @@ -110,14 +144,9 @@ func Generate(ui cli.Ui, providerName, renderedProviderName, renderedWebsiteDir, func (g *generator) Generate(ctx context.Context) error { var err error - wd, err := os.Getwd() - if err != nil { - return err - } - providerName := g.providerName if g.providerName == "" { - providerName = filepath.Base(wd) + providerName = filepath.Base(g.providerDir) } if g.renderedProviderName == "" { @@ -147,19 +176,19 @@ func (g *generator) Generate(ctx context.Context) error { } } - websiteSourceDirInfo, err := os.Stat(g.websiteSourceDir) + templatesDirInfo, err := os.Stat(g.ProviderTemplatesDir()) switch { case os.IsNotExist(err): // do nothing, no template dir case err != nil: return err default: - if !websiteSourceDirInfo.IsDir() { - return fmt.Errorf("template path is not a directory: %s", g.websiteSourceDir) + if !templatesDirInfo.IsDir() { + return fmt.Errorf("template path is not a directory: %s", g.ProviderTemplatesDir()) } 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 { return err } @@ -186,35 +215,60 @@ func (g *generator) Generate(ctx context.Context) error { 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 { - tmplPath, err := websiteFileTemplate.Render(name, providerName) + tmplPath, err := websiteFileTemplate.Render(g.providerDir, name, providerName) if err != nil { 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) { g.infof("resource %q template exists, skipping", name) return nil } for _, candidate := range websiteStaticCandidateTemplates { - candidatePath, err := candidate.Render(name, providerName) + candidatePath, err := candidate.Render(g.providerDir, name, providerName) if err != nil { 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) { g.infof("resource %q static file exists, skipping", name) return nil } } - examplePath, err := examplesFileTemplate.Render(name, providerName) + examplePath, err := examplesFileTemplate.Render(g.providerDir, name, providerName) if err != nil { return fmt.Errorf("unable to render example file path for %q: %w", name, err) } if examplePath != "" { - examplePath = filepath.Join(g.examplesDir, examplePath) + examplePath = filepath.Join(g.ProviderExamplesDir(), examplePath) } if !fileExists(examplePath) { examplePath = "" @@ -222,12 +276,12 @@ func (g *generator) renderMissingResourceDoc(providerName, name, typeName string importPath := "" if examplesImportTemplate != nil { - importPath, err = examplesImportTemplate.Render(name, providerName) + importPath, err = examplesImportTemplate.Render(g.providerDir, name, providerName) if err != nil { return fmt.Errorf("unable to render example import file path for %q: %w", name, err) } if importPath != "" { - importPath = filepath.Join(g.examplesDir, importPath) + importPath = filepath.Join(g.ProviderExamplesDir(), importPath) } if !fileExists(importPath) { importPath = "" @@ -236,11 +290,11 @@ func (g *generator) renderMissingResourceDoc(providerName, name, typeName string targetResourceTemplate := defaultResourceTemplate - fallbackTmplPath, err := fallbackWebsiteFileTemplate.Render(name, providerName) + fallbackTmplPath, err := fallbackWebsiteFileTemplate.Render(g.providerDir, name, providerName) if err != nil { 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) { g.infof("resource %q fallback template exists", name) tmplData, err := os.ReadFile(fallbackTmplPath) @@ -251,7 +305,7 @@ func (g *generator) renderMissingResourceDoc(providerName, name, typeName string } 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 { return fmt.Errorf("unable to render template for %q: %w", name, err) } @@ -265,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 { - tmplPath, err := websiteFileTemplate.Render(providerName) + tmplPath, err := websiteFileTemplate.Render(g.providerDir, providerName) if err != nil { 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) { g.infof("provider %q template exists, skipping", providerName) return nil } for _, candidate := range websiteStaticCandidateTemplates { - candidatePath, err := candidate.Render(providerName) + candidatePath, err := candidate.Render(g.providerDir, providerName) if err != nil { 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) { g.infof("provider %q static file exists, skipping", providerName) return nil } } - examplePath, err := examplesFileTemplate.Render(providerName) + examplePath, err := examplesFileTemplate.Render(g.providerDir, providerName) if err != nil { return fmt.Errorf("unable to render example file path for %q: %w", providerName, err) } if examplePath != "" { - examplePath = filepath.Join(g.examplesDir, examplePath) + examplePath = filepath.Join(g.ProviderExamplesDir(), examplePath) } if !fileExists(examplePath) { examplePath = "" } 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 { return fmt.Errorf("unable to render template for %q: %w", providerName, err) } @@ -362,7 +416,7 @@ 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.renderedWebsiteDir) + err := os.RemoveAll(g.ProviderDocsDir()) if err != nil { return err } @@ -377,7 +431,7 @@ func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfj 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 { return err } @@ -390,7 +444,7 @@ func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfj return nil } - renderedPath := filepath.Join(g.renderedWebsiteDir, rel) + renderedPath := filepath.Join(g.ProviderDocsDir(), rel) err = os.MkdirAll(filepath.Dir(renderedPath), 0755) if err != nil { return err @@ -419,10 +473,11 @@ func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfj switch relDir { case "data-sources/": 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 { 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 { return fmt.Errorf("unable to render data source template %q: %w", rel, err) } @@ -435,12 +490,12 @@ func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfj g.warnf("data source entitled %q, or %q does not exist", shortName, resName) case "resources/": resSchema, resName := resourceSchema(providerSchema.ResourceSchemas, shortName, relFile) - exampleFilePath := filepath.Join(g.examplesDir, "resources", resName, "resource.tf") - importFilePath := filepath.Join(g.examplesDir, "resources", resName, "import.sh") + exampleFilePath := filepath.Join(g.ProviderExamplesDir(), "resources", resName, "resource.tf") + importFilePath := filepath.Join(g.ProviderExamplesDir(), "resources", resName, "import.sh") if resSchema != nil { 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 { return fmt.Errorf("unable to render resource template %q: %w", rel, err) } @@ -454,8 +509,8 @@ func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfj case "": // provider if relFile == "index.md.tmpl" { tmpl := providerTemplate(tmplData) - exampleFilePath := filepath.Join(g.examplesDir, "provider", "provider.tf") - render, err := tmpl.Render(providerName, g.renderedProviderName, exampleFilePath, providerSchema.ConfigSchema) + exampleFilePath := filepath.Join(g.ProviderExamplesDir(), "provider", "provider.tf") + render, err := tmpl.Render(g.providerDir, providerName, g.renderedProviderName, exampleFilePath, providerSchema.ConfigSchema) if err != nil { return fmt.Errorf("unable to render provider template %q: %w", rel, err) } @@ -468,7 +523,7 @@ func (g *generator) renderStaticWebsite(providerName string, providerSchema *tfj } tmpl := docTemplate(tmplData) - err = tmpl.Render(out) + err = tmpl.Render(g.providerDir, out) if err != nil { return fmt.Errorf("unable to render template %q: %w", rel, err) } @@ -505,6 +560,7 @@ func (g *generator) terraformProviderSchema(ctx context.Context, providerName st outFile = outFile + ".exe" } buildCmd := exec.Command("go", "build", "-o", outFile) + buildCmd.Dir = g.providerDir // TODO: constrain env here to make it a little safer? _, err = runCmd(buildCmd) if err != nil { diff --git a/internal/provider/template.go b/internal/provider/template.go index 2896fde5..3d71b419 100644 --- a/internal/provider/template.go +++ b/internal/provider/template.go @@ -7,6 +7,7 @@ import ( "bytes" "fmt" "io" + "path/filepath" "strings" "text/template" @@ -35,17 +36,17 @@ type ( docTemplate string ) -func newTemplate(name, text string) (*template.Template, error) { +func newTemplate(providerDir, name, text string) (*template.Template, error) { tmpl := template.New(name) titleCaser := cases.Title(language.Und) tmpl.Funcs(map[string]interface{}{ - "codefile": tmplfuncs.CodeFile, + "codefile": codeFile(providerDir), "lower": strings.ToLower, "plainmarkdown": mdplain.PlainMarkdown, "prefixlines": tmplfuncs.PrefixLines, "split": strings.Split, - "tffile": terraformCodeFile, + "tffile": terraformCodeFile(providerDir), "title": titleCaser.String, "trimspace": strings.TrimSpace, "upper": strings.ToUpper, @@ -60,13 +61,29 @@ func newTemplate(name, text string) (*template.Template, error) { return tmpl, nil } -func terraformCodeFile(file string) (string, error) { +func codeFile(providerDir string) func(string, string) (string, error) { + return func(format string, file string) (string, error) { + if filepath.IsAbs(file) { + return tmplfuncs.CodeFile(format, file) + } + + return tmplfuncs.CodeFile(format, filepath.Join(providerDir, file)) + } +} + +func terraformCodeFile(providerDir string) func(string) (string, error) { // TODO: omit comment handling - return tmplfuncs.CodeFile("terraform", file) + 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(name string, text string, out io.Writer, data interface{}) error { - tmpl, err := newTemplate(name, text) +func renderTemplate(providerDir, name string, text string, out io.Writer, data interface{}) error { + tmpl, err := newTemplate(providerDir, name, text) if err != nil { return err } @@ -79,10 +96,10 @@ func renderTemplate(name string, text string, out io.Writer, data interface{}) e 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 - err := renderTemplate(name, text, &buf, data) + err := renderTemplate(providerDir, name, text, &buf, data) if err != nil { return "", err } @@ -90,21 +107,21 @@ func renderStringTemplate(name, text string, data interface{}) (string, error) { 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) if s == "" { 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) if s == "" { return "", nil } - return renderStringTemplate("resourceFileTemplate", s, struct { + return renderStringTemplate(providerDir, "resourceFileTemplate", s, struct { Name string ShortName string @@ -119,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) if s == "" { return "", nil } - return renderStringTemplate("providerFileTemplate", s, struct { + return renderStringTemplate(providerDir, "providerFileTemplate", s, struct { Name string ShortName string }{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) err := schemamd.Render(schema, schemaBuffer) if err != nil { @@ -141,7 +158,8 @@ func (t providerTemplate) Render(providerName, renderedProviderName, exampleFile if s == "" { return "", nil } - return renderStringTemplate("providerTemplate", s, struct { + + return renderStringTemplate(providerDir, "providerTemplate", s, struct { Description string HasExample bool @@ -168,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) err := schemamd.Render(schema, schemaBuffer) if err != nil { @@ -180,7 +198,7 @@ func (t resourceTemplate) Render(name, providerName, renderedProviderName, typeN return "", nil } - return renderStringTemplate("resourceTemplate", s, struct { + return renderStringTemplate(providerDir, "resourceTemplate", s, struct { Type string Name string Description string diff --git a/internal/provider/template_test.go b/internal/provider/template_test.go index 88804e25..349f6892 100644 --- a/internal/provider/template_test.go +++ b/internal/provider/template_test.go @@ -34,7 +34,7 @@ Prefixlines: This text used multiple lines ` - result, err := renderStringTemplate("testTemplate", template, struct { + result, err := renderStringTemplate("test-provider-dir", "testTemplate", template, struct { Text string MultiLineTest string }{ diff --git a/internal/tmplfuncs/tmplfuncs.go b/internal/tmplfuncs/tmplfuncs.go index 8fd393f5..15bcc761 100644 --- a/internal/tmplfuncs/tmplfuncs.go +++ b/internal/tmplfuncs/tmplfuncs.go @@ -6,7 +6,6 @@ package tmplfuncs import ( "fmt" "os" - "path/filepath" "strings" ) @@ -15,15 +14,7 @@ func PrefixLines(prefix, text string) string { } func CodeFile(format, file string) (string, error) { - // paths are relative to the rendering process work dir, which - // 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) + content, err := os.ReadFile(file) if err != nil { return "", fmt.Errorf("unable to read content from %q: %w", file, err) }