Skip to content

bidsmith fmt

fmt is bidsmith’s opinionated formatter. It parses each .bid file, then re-emits it in canonical form: stable whitespace, consistent indentation, a stable attribute order, normalized quoting.

Running fmt on a file that’s already canonical is a no-op — the operation is idempotent.

Synopsis

Terminal window
bidsmith fmt [PATH] [--check] [--minimal]

Arguments

ArgumentDefaultDescription
PATH.File or directory to format. Directories are walked recursively for .bid files.

Flags

FlagDescription
--checkDon’t write any files. Exit 1 if any file would change. Use in CI.
--minimalAlso drop optional attributes whose value equals the schema default (e.g. status = "ENABLED", delivery_method = "STANDARD"). This is the form refresh and export already emit. Omitting an attribute keeps it managed at the default — plan still enforces it — so the only thing lost is the noise. Compliance declarations such as contains_eu_political_advertising stay even at their default, and so does any attribute you’ve written a comment about.

Environment variables

None. fmt runs entirely offline.

Exit codes

CodeMeaning
0All files are canonical (or were rewritten to canonical).
1With --check: at least one file would change. Without --check: a parse error or I/O error.

Examples

Format every .bid file in the current project

Terminal window
bidsmith fmt .

Rewrites files in place. Combine with git diff to see what changed.

Verify everything is canonical (CI)

Terminal window
bidsmith fmt --check .

Exit 0 if nothing would change. Exit 1 and list the affected files if they aren’t canonical. Run as a status check on pull requests so no non-canonical files reach main.

Format one file

Terminal window
bidsmith fmt summer-2026.bid

Drop attributes left at their default

Terminal window
bidsmith fmt --minimal .

Turns this:

resource "google_ads_campaign" "spring" {
name = "Spring Sale"
status = "ENABLED"
advertising_channel_type = "SEARCH"
campaign_budget = google_ads_campaign_budget.spring.id
contains_eu_political_advertising = "DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING"
}

into this:

resource "google_ads_campaign" "spring" {
name = "Spring Sale"
advertising_channel_type = "SEARCH"
campaign_budget = google_ads_campaign_budget.spring.id
contains_eu_political_advertising = "DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING"
}

status = "ENABLED" is the default, so it’s dropped — the campaign is still enabled, and a plan still flips it back if someone pauses it in the UI. A status = "PAUSED" would stay, because it carries information. The EU-political line stays because it’s a compliance declaration. This is the same output bidsmith refresh produces.

Comments survive

fmt never deletes a comment. Write the why right next to the number it explains and it stays there, however many times you format:

# Signed off by finance, March 2026.
resource "google_ads_campaign_budget" "summer" {
name = "Summer sale"
# EUR 20/day. Modelled on last summer's spend, +15% for the
# extended sale window.
amount_micros = 20000000 # 20 EUR
keywords = [
"running shoes",
"trail shoes", # our best converter, don't drop it
]
}

Comments stay attached to whatever they were written against — above a block or an attribute, or at the end of its line. fmt tidies the indentation to match, and keeps one blank line where you left one.

What “canonical” means

bidsmith’s canonical form is deterministic, not pretty-print. Given the same input it always produces the same output. Specifics:

  • Two-space indentation for nested blocks.
  • = aligned within an attribute block where it improves readability.
  • Attributes before nested blocks within each block.
  • Stable attribute order within a resource — required first, optional after, in the order the schema declares them.
  • Compact forms for things that have one (e.g. bulk keyword {} sub-blocks in a single criterion resource; RSA headlines = [...] list attributes when more concise than per-headline blocks).
  • Comments kept, re-indented to the depth of whatever they’re written against.

The exact canonical form is whatever bidsmith fmt produces — it’s not specified independently. If fmt --check passes, you’re canonical.

See also