Add sync_global_tables.py to merge MIKILAB_* entries into KiCad's global tables
Automates the manual merge step from README.md section 1: regenerates sym-lib-table.global/fp-lib-table.global from the project tables, then adds any MIKILAB_* entries missing from KiCad's installed global tables (~/Library/Preferences/kicad/10.0/), leaving every other entry untouched and backing up both files first. Refuses to run while KiCad is open, since it would otherwise overwrite the merge with its in-memory copy on exit. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013gndCxJXQfouCQy4hP7NSX
This commit is contained in:
Executable
+91
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Sync this library's MIKILAB_* entries into KiCad's global lib tables.
|
||||
|
||||
Regenerates sym-lib-table.global / fp-lib-table.global from the local
|
||||
sym-lib-table / fp-lib-table, then merges any MIKILAB_* entries missing
|
||||
from KiCad's global tables (~/Library/Preferences/kicad/10.0/), leaving
|
||||
every other entry untouched. Backs up both global tables before writing.
|
||||
|
||||
KiCad must be fully closed (all windows, all sub-apps like eeschema /
|
||||
pcbnew) before running this -- otherwise KiCad will overwrite the merged
|
||||
tables with its in-memory copy when it exits.
|
||||
"""
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
LIB_ROOT = Path(__file__).resolve().parent.parent
|
||||
KICAD_DIR = Path.home() / "Library/Preferences/kicad/10.0"
|
||||
|
||||
TABLES = (
|
||||
("sym-lib-table", "sym-lib-table.global"),
|
||||
("fp-lib-table", "fp-lib-table.global"),
|
||||
)
|
||||
|
||||
|
||||
def running_kicad_processes():
|
||||
out = subprocess.run(["pgrep", "-fl", "KiCad|eeschema|pcbnew"],
|
||||
capture_output=True, text=True)
|
||||
lines = [l for l in out.stdout.splitlines() if l.strip()]
|
||||
return lines
|
||||
|
||||
|
||||
def main():
|
||||
procs = running_kicad_processes()
|
||||
if procs:
|
||||
print("KiCad (or a sub-app) is still running -- close it fully first:")
|
||||
for l in procs:
|
||||
print(" ", l)
|
||||
sys.exit(1)
|
||||
|
||||
subprocess.run([sys.executable, str(LIB_ROOT / "scripts" / "generate_global_tables.py")], check=True)
|
||||
|
||||
stamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
any_merged = False
|
||||
|
||||
for global_name, generated_name in TABLES:
|
||||
target = KICAD_DIR / global_name
|
||||
if not target.exists():
|
||||
print(f"skip: {target} does not exist")
|
||||
continue
|
||||
|
||||
target_text = target.read_text()
|
||||
existing_names = set(re.findall(r'\(lib \(name "([^"]+)"', target_text))
|
||||
|
||||
generated_lines = (LIB_ROOT / generated_name).read_text().splitlines()
|
||||
new_libs = []
|
||||
for line in generated_lines:
|
||||
line = line.strip()
|
||||
if not line.startswith("(lib"):
|
||||
continue
|
||||
m = re.search(r'\(lib \(name "([^"]+)"', line)
|
||||
if m and m.group(1) not in existing_names:
|
||||
new_libs.append(line)
|
||||
|
||||
if not new_libs:
|
||||
print(f"{target}: already up to date")
|
||||
continue
|
||||
|
||||
backup = target.with_name(f"{global_name}.bak.{stamp}")
|
||||
backup.write_text(target_text)
|
||||
|
||||
idx = target_text.rstrip().rfind(")")
|
||||
merged = (target_text.rstrip()[:idx] + "\n " + "\n ".join(new_libs)
|
||||
+ "\n" + target_text.rstrip()[idx:] + "\n")
|
||||
target.write_text(merged)
|
||||
any_merged = True
|
||||
print(f"Merged {len(new_libs)} new librar{'y' if len(new_libs)==1 else 'ies'} into {target} (backup: {backup.name})")
|
||||
for l in new_libs:
|
||||
m = re.search(r'\(lib \(name "([^"]+)"', l)
|
||||
print(f" + {m.group(1)}")
|
||||
|
||||
if not any_merged:
|
||||
print("Nothing to sync -- global tables already match the library.")
|
||||
else:
|
||||
print("Done. Start KiCad to pick up the new libraries.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user