"""Export the reviewed FAN-R2 firmware changes without writing sibling firmware.""" import difflib import hashlib import json from pathlib import Path ROOT = Path(__file__).resolve().parents[1] FILES = ('main/board_pins.h', 'main/rail_cfg.c', 'test/test_rail_cfg.c') def main(): source = ROOT.parent / 'firmware' candidate = ROOT / 'out/firmware-fan-r2' output = ROOT / 'firmware-sync' output.mkdir(exist_ok=True) patch = [] manifest = {'source': str(source), 'candidate': str(candidate), 'files': []} for name in FILES: before = (source / name).read_bytes() after = (candidate / name).read_bytes() if before == after: raise ValueError(f'Expected reviewed change missing: {name}') patch.extend(difflib.unified_diff( before.decode('utf-8').splitlines(keepends=True), after.decode('utf-8').splitlines(keepends=True), fromfile='a/firmware/' + name, tofile='b/firmware/' + name)) manifest['files'].append({ 'path': name, 'source_sha256': hashlib.sha256(before).hexdigest(), 'candidate_sha256': hashlib.sha256(after).hexdigest(), }) # Normalize line endings so git can apply the patch to the CRLF source tree. patch_text = ''.join(patch).replace('\r\n', '\n') with (output / 'fan-r2.patch').open('w', encoding='utf-8', newline='\n') as stream: stream.write(patch_text) (output / 'manifest.json').write_text(json.dumps(manifest, indent=2) + '\n', encoding='utf-8') print(f'Exported {len(FILES)} files to {output / "fan-r2.patch"}') if __name__ == '__main__': main()