82 lines
2.9 KiB
Python
82 lines
2.9 KiB
Python
"""Show or compare the config Klipper builds from macros/klipper-macros.cfg.
|
|||
|
|
|
||
|
|
Klipper expands [include ...] in order and merges sections with the same
|
||
|
|
name (the last value of an option wins). This script does the same, so a
|
||
|
|
refactor can be checked for unintended changes.
|
||
|
|
|
||
|
|
python tools/effective_config.py list sections of the working tree
|
||
|
|
python tools/effective_config.py HEAD compare HEAD with the working tree
|
||
|
|
python tools/effective_config.py A B compare two git refs
|
||
|
|
python tools/effective_config.py HEAD -v also print old/new values
|
||
|
|
"""
|
||
|
|
import configparser
|
||
|
|
import os
|
||
|
|
import re
|
||
|
|
import subprocess
|
||
|
|
import sys
|
||
|
|
import tempfile
|
||
|
|
|
||
|
|
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||
|
|
BASE = os.path.join('macros', 'klipper-macros.cfg')
|
||
|
|
|
||
|
|
|
||
|
|
def expand(path):
|
||
|
|
lines = []
|
||
|
|
with open(path, encoding='utf-8') as f:
|
||
|
|
for line in f.read().replace('\r\n', '\n').split('\n'):
|
||
|
|
m = re.match(r'^\[include ([^\]]+)\]', line.split('#')[0])
|
||
|
|
if m:
|
||
|
|
inc = os.path.join(os.path.dirname(path), m.group(1).strip())
|
||
|
|
lines += expand(inc)
|
||
|
|
else:
|
||
|
|
lines.append(line)
|
||
|
|
return lines
|
||
|
|
|
||
|
|
|
||
|
|
def load(root):
|
||
|
|
cp = configparser.RawConfigParser(strict=False,
|
||
|
|
inline_comment_prefixes=(';', '#'))
|
||
|
|
cp.read_string('\n'.join(expand(os.path.join(root, BASE))))
|
||
|
|
return {s: dict(cp.items(s)) for s in cp.sections()}
|
||
|
|
|
||
|
|
|
||
|
|
def checkout(ref, tmp):
|
||
|
|
archive = subprocess.run(['git', '-C', ROOT, 'archive', ref, 'macros'],
|
||
|
|
check=True, capture_output=True).stdout
|
||
|
|
subprocess.run(['tar', '-x', '-C', tmp], input=archive, check=True)
|
||
|
|
return tmp
|
||
|
|
|
||
|
|
|
||
|
|
def main(argv):
|
||
|
|
verbose = '-v' in argv
|
||
|
|
refs = [a for a in argv if a != '-v']
|
||
|
|
with tempfile.TemporaryDirectory() as t1, tempfile.TemporaryDirectory() as t2:
|
||
|
|
if not refs:
|
||
|
|
for s in sorted(load(ROOT)):
|
||
|
|
print(s)
|
||
|
|
return 0
|
||
|
|
old = load(checkout(refs[0], t1))
|
||
|
|
new = load(checkout(refs[1], t2) if len(refs) > 1 else ROOT)
|
||
|
|
added, removed = sorted(set(new) - set(old)), sorted(set(old) - set(new))
|
||
|
|
changed = 0
|
||
|
|
for s in added:
|
||
|
|
print('added ', s)
|
||
|
|
for s in removed:
|
||
|
|
print('removed ', s)
|
||
|
|
for s in sorted(set(old) & set(new)):
|
||
|
|
keys = sorted(k for k in set(old[s]) | set(new[s])
|
||
|
|
if old[s].get(k) != new[s].get(k))
|
||
|
|
if keys:
|
||
|
|
changed += 1
|
||
|
|
print('changed ', s, keys)
|
||
|
|
if verbose:
|
||
|
|
for k in keys:
|
||
|
|
print(' old %s: %r' % (k, old[s].get(k)))
|
||
|
|
print(' new %s: %r' % (k, new[s].get(k)))
|
||
|
|
print('%d sections, %d added, %d removed, %d changed'
|
||
|
|
% (len(new), len(added), len(removed), changed))
|
||
|
|
return 0
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == '__main__':
|
||
|
|
sys.exit(main(sys.argv[1:]))
|