Auto-formatting YAML files with yamlfmt
I decided to see if there was an equivalent of Black or Prettier for YAML files. I found yamlfmt from Google.
Update: It turns out Prettier can format YAML too.
Installation
They suggest this:
go install github.com/google/yamlfmt/cmd/yamlfmt@latestThis worked on my machine because I had Go installed via Homebrew (go version go1.20.4 darwin/arm64 according to go version).
I wasn’t sure where it had been installed - it turns out that if you don’t have a GOPATH environment variable set then tools installed like this default to landing in ~/go/bin.
If you don’t have Go installed, you can instead download a compiled binary from google/yamlfmt/releases.
Usage
You can pass files to it explicitly:
~/go/bin/yamlfmt .github/workflows/*.ymlOr you can run against every file .yml or .yaml file in a directory and its subdirectories:
~/go/bin/yamlfmt .The default format looked like this:
name: Publish Python Packageon: release: types: [created]jobs: test: runs-on: ubuntu-latest strategy: matrix: python-version: ["3.8", "3.9", "3.10", "3.11"] steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }}Configuration
It removed some of my whitespace (I had newlines in front of those on: and jobs: keys), and I really didn’t like the way it handled lists - adding an unnecessary additional two spaces of indent before each list item.
You can pass it configuration to fix this.
Here’s what I ended up with:
~/go/bin/yamlfmt \ -formatter indentless_arrays=true,retain_line_breaks=true \ .github/workflows/*.ymlThe order of this matters: you can’t put -formatter after the list of files or it will be silently ignored.
This gave me:
name: Publish Python Package
on: release: types: [created]
jobs: test: runs-on: ubuntu-latest strategy: matrix: python-version: ["3.8", "3.9", "3.10", "3.11"] steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }}There’s also a mechanism where you can put configuration options in a .yamlfmt file, or a file passed using --conf - those are explained here.
Configuring defaults
You can set system-wide defaults for the tool by adding a .yamlfmt in the right place. On macOS I found it worked putting it here:
/.config/yamlfmt/.yamlfmtI set the following options in that file:
formatter: retain_line_breaks: true indentless_arrays: true scan_folded_as_literal: trueNow I can run ymalfmt anywhere without extra arguments and get my preferred formatting rules.
I added scan_folded_as_literal: true because I noticed that it was reformatting my > string literal blocks to a single line, which I didn’t like. Here’s what it was doing:
expected: > Here comes a table <table> <thead><tr><th>One</th><th>Two</th></tr></thead> <tbody> <tr><td>1</td><td>2</td></tr> </tbody> </table> Done Here comes a table <table> <thead><tr><th>One</th><th>Two</th></tr></thead> <tbody> <tr><td>1</td><td>2</td></tr> </tbody> </table> DoneRunning it in CI with -lint
The -lint option lets you check formatting in CI and fail if it would reformat (like black --check). You can run it like this:
~/go/bin/yamlfmt \ -formatter indentless_arrays=true,retain_line_breaks=true \ -lint \ .github/workflows/*.ymlWhich will output a full copy of the reformatted file, with as indicator as to which lines it changes.
I found that a bit noisy. You can add -quiet to get a less verbose output showing just the file paths that would change:
~/go/bin/yamlfmt \ -formatter indentless_arrays=true,retain_line_breaks=true \ -lint \ -quiet \ .github/workflows/*.ymlOutput:
2023/07/13 07:16:36 The following files had formatting differences:
.github/workflows/publish.yml