Building from source¶
Requirements¶
- Go 1.25 or later. This project follows the Go support policy and supports the two latest major releases. The 1.25 floor comes from
golang.org/x/tools, whose Go 1.27-compatible release requires it. - Go Modules. Dependency management is via
go.mod; there is no vendor directory.
CI builds and tests against both 1.25.x and 1.27.x. The 1.27 job exists specifically to guard the package without types was imported regression — see Troubleshooting.
Building¶
Installing your build¶
This puts the binaries in $GOBIN (typically $GOPATH/bin), shadowing any released version on your PATH. Confirm which one you are running:
A locally built binary reports the version baked into version/version.go rather than a release tag, since the release version is injected at link time by GoReleaser. See Releasing.
Trying it against a real provider¶
The fastest way to sanity-check a change is to run your build against an actual provider:
To exercise one check in isolation:
Project layout¶
| Path | Contents |
|---|---|
cmd/tfsprout/ |
Standard command entry point |
cmd/tfsproutx/ |
Extended command entry point |
passes/ |
Standard checks, plus the information-gathering analyzers they depend on |
xpasses/ |
Extra checks |
helper/analysisutils/ |
Constructors and runners for common analyzer shapes |
helper/astutils/ |
Generic Go AST utilities |
helper/terraformtype/ |
Terraform Plugin SDK type models and package path constants |
helper/cmdflags/ |
Shared command flags, currently the version flag |
version/ |
Version constants, overridden at link time on release |
Note that passes/ holds both checks and non-check analyzers. Directories named for a check ID (AT001, S013) are checks; the others (commentignore, helper, stdlib, terraform, testaccfuncdecl, testfuncdecl) gather information for them. See How tfsprout works.
Helpful tooling¶
Writing an analyzer means reasoning about AST shapes. These help:
Dumping the AST of a small file containing the pattern you want to match is usually the quickest way to work out what to write.
Dependencies¶
Updates are managed by Dependabot. CI enforces a tidy module:
Run both before opening a pull request.
Building the documentation site¶
The site at https://jfrappier.github.io/tfsprout/ is built with
MkDocs and the
Cinder theme. Every dependency is
pinned in requirements-docs.txt, which needs Python 3.10 or later —
pymdown-extensions 11 dropped 3.9, and on an older interpreter pip reports
only that no matching distribution was found:
That serves the site on http://127.0.0.1:8000 and rebuilds on save. CI builds
with --strict, which turns broken internal links and unresolved anchors into
errors, so run it that way before opening a pull request:
What is generated rather than written¶
docs-theme/hooks.py builds two kinds of page at build time, so do not look for
them in docs/:
| Page | Built from |
|---|---|
checks/<ID> |
passes/<ID>/README.md or xpasses/<ID>/README.md |
changelog |
CHANGELOG.md |
The practical consequence is that a check's documentation lives beside its
analyzer. Adding a check directory with a README.md is all it takes for the
check to get a page, a sidebar entry, and a search index entry — see
Adding an analyzer.
Check READMEs are read both on GitHub and on the site, so they use GitHub's
> [!NOTE] alert syntax; the hook rewrites it into a MkDocs admonition when it
builds the page.