Files
HubAudio/tools/docs/role_refactor.py
T

169 lines
3.5 KiB
Python

#!/usr/bin/env python3
"""
HubAudio Documentation Role Refactor
Replaces hardware implementation names with architectural role names.
Example:
python role_refactor.py docs --dry-run
python role_refactor.py docs --write
"""
from pathlib import Path
import argparse
import re
import sys
# ----------------------------------------------------------------------
# Mapping
# ----------------------------------------------------------------------
ROLE_MAP = {
"ADAU1467": "Audio Processor",
"ESP32-S3": "System Controller",
"Si4684": "Radio Receiver",
"BT1026": "Bluetooth Receiver",
"BT1035": "Bluetooth Transmitter",
"PCS2P2309NZ": "Clock Buffer",
"BQ24074": "Battery Charger",
"BQ27441": "Fuel Gauge",
"TPS65217": "Power Manager",
"25AA1024": "Audio EEPROM",
}
# ----------------------------------------------------------------------
# Ignore folders
# ----------------------------------------------------------------------
IGNORE = {
"datasheets",
"hardware",
"firmware",
".git",
"__pycache__",
}
# ----------------------------------------------------------------------
# Replace inside one file
# ----------------------------------------------------------------------
def process_file(path: Path, write: bool):
text = path.read_text(encoding="utf-8")
original = text
replacements = []
for implementation, role in ROLE_MAP.items():
pattern = r"\b" + re.escape(implementation) + r"\b"
matches = len(re.findall(pattern, text))
if matches:
text = re.sub(pattern, role, text)
replacements.append((implementation, role, matches))
if not replacements:
return False, []
print(f"\n{path}")
total = 0
for old, new, count in replacements:
total += count
print(f" {old:18} -> {new:24} ({count})")
print(f" Total replacements: {total}")
if write:
path.write_text(text, encoding="utf-8")
return True, replacements
# ----------------------------------------------------------------------
# Scan tree
# ----------------------------------------------------------------------
def scan(root: Path, write: bool):
modified = 0
files = 0
for file in root.rglob("*.md"):
if any(part in IGNORE for part in file.parts):
continue
changed, _ = process_file(file, write)
if changed:
modified += 1
files += 1
print("\n----------------------------------------")
print(f"Markdown scanned : {files}")
print(f"Files modified : {modified}")
if write:
print("\nChanges written to disk.")
else:
print("\nDry run completed.")
# ----------------------------------------------------------------------
# Main
# ----------------------------------------------------------------------
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"path",
help="Root documentation directory"
)
parser.add_argument(
"--write",
action="store_true",
help="Write modifications"
)
parser.add_argument(
"--dry-run",
action="store_true",
help="Only show modifications"
)
args = parser.parse_args()
if args.write and args.dry_run:
print("Choose either --write or --dry-run")
sys.exit(1)
root = Path(args.path)
if not root.exists():
print("Directory not found.")
sys.exit(1)
scan(root, write=args.write)
if __name__ == "__main__":
main()