Skip to content

Instantly share code, notes, and snippets.

@dlamblin
Created March 24, 2023 02:05
Show Gist options
  • Save dlamblin/b485efd8f33a173f8dc1d80e18ab3cd6 to your computer and use it in GitHub Desktop.
Save dlamblin/b485efd8f33a173f8dc1d80e18ab3cd6 to your computer and use it in GitHub Desktop.
Format YAML by key name order with fmtyaml.py
#!/usr/bin/env python3
# vim: et sw=4 ai
"""
This script takes in files named in presumed yaml format and OVERWRITES them
with all their keys sorted by the key name. It does not preserve comments. I've
not tested it with lists.
Using '-' as a filename opens and consumes stdin in addition to other files.
stdin is written to stdout with the same processing.
Use: fmtyaml.py <filename> ... Overwrites all the filenames with
contents sorted by keys
fmtyaml.py <in.yaml >out.yaml Writes out.yaml with in.yaml sorted
by keys
fmtyaml.py <filename> ... - <in >out A combination of the above two
CAVETS:
reqires pyyaml
This may rely on the python version's internal dictionary key ordering.
Tested with 3.10
"""
import sys
import fileinput
import yaml
def process(lines, is_stdin, filename):
content = yaml.safe_load(lines)
if not is_stdin:
with open(filename, 'w') as dst:
yaml.safe_dump(content, dst)
else:
print(yaml.safe_dump(content))
if __name__ == "__main__":
if '--help' in sys.argv or '-h' in sys.argv:
print(__doc__)
sys.exit(0)
was_file_name = None
was_stdin = False
with fileinput.input(encoding='utf-8', mode='r') as input_files:
lines = ''
for line in input_files:
if input_files.isfirstline():
if was_file_name:
process(lines, was_stdin, was_file_name)
was_file_name = input_files.filename()
was_std_in = input_files.isstdin()
lines = ''
lines += line
process(lines, was_std_in, was_file_name)
@dlamblin
Copy link
Author

It's a little hacky working with fileinput which operates line by line when I really want to work file by file.
It unsafe as far as handling non-yaml. It might parse and then throw out something unexpected, or more likely it'll fail during safe_load() which is better, but not handled gracefully.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment