johannh.me
← writing
/ #tools

A small tool for diffing config files

Eighty lines of Python I now use every day.

diff is the wrong tool for config files. It shows you that line 40 changed; it doesn’t show you that the timeout key moved from the [server] section to [http] and picked up a different default on the way.

So I wrote diffconf: parse both files into a normalized tree, walk the trees together, and report semantic changes — keys added, removed, moved, or re-typed — instead of textual ones.

def walk(a, b, path=()):
    for key in sorted(set(a) | set(b)):
        pa, pb = a.get(key, MISSING), b.get(key, MISSING)
        if isinstance(pa, dict) and isinstance(pb, dict):
            yield from walk(pa, pb, path + (key,))
        elif pa != pb:
            yield Change(path + (key,), pa, pb)

It supports INI, TOML, JSON, and a subset of YAML. It is eighty lines, it has no dependencies, and it has caught three production incidents before they shipped.