drep/languages/definitions/terraform.rs
1//! Terraform: tflint over `.tf` and `.tfvars`.
2
3use crate::languages::spec::{
4 DEFAULT_TOOL_TIMEOUT_SECS, DiagnosticsStream, LanguageSupport, OutputFormat, ToolSpec,
5};
6
7/// Terraform deterministic checker.
8///
9/// tflint's SARIF `uri` is repo-relative, verified against its real output.
10/// Some of its results carry a `physicalLocation` with no `region`; the
11/// SARIF parser already defaults those to line 1.
12///
13/// `--recursive` is what makes nested modules visible at all: bare tflint
14/// lints only the module in its cwd, so a commit touching `modules/*/`
15/// produced no findings and passed silently. Verified against the real
16/// binary: the recursive run descends, emits each finding's uri relative to
17/// the invocation directory, and exits 2 when any module has findings. Each
18/// module's config is its own - a nested module without a `.tflint.hcl` is
19/// linted under tflint's defaults rather than the root config, which is
20/// tflint's documented per-module resolution, not something drep can
21/// override from here.
22pub static TFLINT: ToolSpec = ToolSpec {
23 name: "tflint",
24 command: &["tflint", "--format", "sarif", "--recursive"],
25 local_paths: &[],
26 config_files: &[".tflint.hcl"],
27 config_flag: None,
28 output_format: OutputFormat::Sarif,
29 diagnostics_stream: DiagnosticsStream::Stdout,
30 timeout_secs: DEFAULT_TOOL_TIMEOUT_SECS,
31 timeout_context: None,
32 establishes_compilation: false,
33 serial_in_repository: false,
34 // tflint dropped positional file arguments in v0.47: handed `main.tf` it
35 // exits 1 with a SARIF `tflint-errors` run saying "Command line arguments
36 // support was dropped in v0.47. Use --chdir or --filter instead.". That
37 // result carries no location, and a locationless SARIF result is reported
38 // as the tool failing rather than as a finding. Run the configured module
39 // bare and narrow findings back to the requested files, exactly as tsc
40 // and clippy do.
41 accepts_files: false,
42};
43
44/// Terraform language entry.
45pub static TERRAFORM: LanguageSupport = LanguageSupport {
46 name: "terraform",
47 display_name: "Terraform",
48 extensions: &[".tf", ".tfvars"],
49 filenames: &[],
50 filename_prefixes: &[],
51 tools: &[&TFLINT],
52 conventions: &[
53 "Unpinned provider versions and module sources",
54 "Changes that force replacement of stateful resources",
55 "Hardcoded values that belong in variables",
56 "Missing tags and attributes the account policy requires",
57 "count and for_each churn that recreates identical resources",
58 ],
59 // `.terraform` holds downloaded providers and module copies: thousands of
60 // generated files per lock file revision.
61 vendored_dirs: &[".terraform"],
62};
63
64/// The family's entries in registration order. See `ALL_LANGUAGES`.
65pub(crate) static FAMILY: &[&LanguageSupport] = &[&TERRAFORM];