ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
auto_sync.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2# SPDX-License-Identifier: MIT
3# Copyright (c) 2026 Brighton Sikarskie
4"""Auto-Sync Utility.
5
6Automatically updates internal cryptographic hashes and appends missing
7suppressions to the ledger as 'unreviewed' drafts.
8"""
9
10import subprocess
11import sys
12from pathlib import Path
13
14
15def _repo_root() -> Path:
16 return Path(__file__).resolve().parents[2]
17
18
19def run(cmd: list[str]) -> bool:
20 """Run a subprocess."""
21 print(f"==> Running: {' '.join(cmd)}")
22 proc = subprocess.run(cmd, cwd=_repo_root(), check=False) # noqa: S603
23 return proc.returncode == 0
24
25
26def update_ledger() -> None:
27 """Update ledger."""
28 ledger_path = _repo_root() / ".github" / "suppression-review-ledger.tsv"
29
30 # 1. Get current candidates
31 proc = subprocess.run(
32 [sys.executable, "scripts/checks/check_suppressions.py", "--ledger-candidates"],
33 cwd=_repo_root(),
34 capture_output=True,
35 text=True,
36 check=False,
37 )
38
39 if proc.returncode == 0 and not proc.stdout.strip():
40 # Clean tree, no missing sites
41 return
42
43 # Check if there are candidates
44 lines = proc.stdout.splitlines()
45 if len(lines) <= 1: # just the header
46 return
47
48 # Read existing ledger
49 existing = ledger_path.read_text(encoding="utf-8").splitlines()
50 header = existing[0]
51 rows = existing[1:]
52
53 # Parse existing into a dict
54 ledger_dict = {}
55 for r in rows:
56 if not r.strip():
57 continue
58 parts = r.split("\t")
59 ledger_dict[parts[0]] = r
60
61 # Append new candidates ONLY if missing
62 added = 0
63 for line in lines[1:]: # skip header
64 if not line.strip():
65 continue
66 parts = line.split("\t")
67 if parts[0] not in ledger_dict:
68 ledger_dict[parts[0]] = line
69 added += 1
70
71 if added == 0:
72 return
73
74 print(f"==> Found {added} missing suppressions. Appending to ledger as 'unreviewed' drafts...")
75
76 # Write back sorted
77 new_content = [header]
78 new_content.extend(ledger_dict[k] for k in sorted(ledger_dict.keys()))
79
80 ledger_path.write_text("\n".join(new_content) + "\n", encoding="utf-8")
81 print("==> Ledger updated. Run 'just quality::local::review-suppressions' to approve them.")
82
83
84def main() -> None:
85 """Main."""
86 # 1. Bless Python checking script scopes
87 run([sys.executable, "scripts/checks/suppression_checker_scope.py", "--update"])
88
89 # 2. Update MC/DC coverage ratchets
90 run([sys.executable, "scripts/checks/mcdc_compound_ratchet.py", "--update"])
91
92 # 3. Format the tree (in case modifications broke formatting)
93 run(["bash", "scripts/checks/format_tree.sh"])
94
95 # 4. Sync the ledger with new unreviewed sites
96 update_ledger()
97
98
99if __name__ == "__main__":
100 main()
void main(void)
The application entry point Reset_Handler hands control to.
Definition main.c:298