Fix pause/resume chain, shared print cleanup, add CLAUDE.md
- RESUME is defined only in print/pause_resume.cfg; heat_soak.cfg's duplicate replaced it (no unretract, no fan restore). It now runs HEAT_SOAK_RESUME -> _RESUME_PRINT -> RESUME_BASE. - PAUSE runs PAUSE_BASE first, then retracts and parks once (X20 Y345); a parked flag makes resume undo only what PAUSE did. - New _PRINT_CLEANUP shared by PRINT_END and CANCEL_PRINT: heaters incl. iHEATER_OFF, fan, M221 S100, bdwidth off, mesh and skew cleared. In PRINT_END it runs after RESTORE_GCODE_STATE so the flow reset sticks. - Add CLAUDE.md and tools/effective_config.py. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
eaf9c82617
commit
9dc733b5bb
7 files changed
+245
-85
No files matched your search
@@ -0,0 +1,82 @@
|
||||
"""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:]))
|
||||
Reference in new issue
Block a user