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.
They suggest this:
go install github.com/google/yamlfmt/cmd/yamlfmt@latest
This 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.
You can pass files to it explicitly:
~/go/bin/yamlfmt .github/workflows/*.yml
Or 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 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 }}
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/*.yml
The 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.
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/.yamlfmt
I set the following options in that file:
formatter:
retain_line_breaks: true
indentless_arrays: true
scan_folded_as_literal: true
Now 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> Done
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/*.yml
Which 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/*.yml
Output:
2023/07/13 07:16:36 The following files had formatting differences:
.github/workflows/publish.yml
Created 2023-07-13T07:11:44-07:00, updated 2023-07-13T08:28:37-07:00 · History · Edit