dda793c0ef
- Introduced `kicad_cli.sh` for local and Docker-based kicad-cli execution. - Created `schops.py` for schematic operations including ERC, BOM, netlist exports, and bulk edits. - Added README.md for schops with installation and usage instructions. - Included requirements.txt for necessary Python packages. - Implemented rules engine for applying field defaults and renaming nets. - Added tests for rules engine functionality. - Introduced scope guard script to enforce file modification policies based on PR labels. - Created watch script to monitor KiCad files and trigger hardware gate on changes.
46 lines
1.9 KiB
Python
46 lines
1.9 KiB
Python
#!/usr/bin/env python3
|
|
"""Generate KiCad Custom Rules snippet from compliance profile.
|
|
|
|
This outputs a text snippet compatible with KiCad's Custom Rules (stored in *.kicad_dru).
|
|
Recommended workflow:
|
|
- run this generator
|
|
- paste/import into PCB Editor -> Board Setup -> Custom Rules
|
|
- commit the resulting <board>.kicad_dru (generated by KiCad) if you want it versioned
|
|
|
|
We keep it minimal and profile-driven: track width, clearance, via/hole sizes, annular ring.
|
|
"""
|
|
import argparse
|
|
from tools.compliance.common import load_profile, load_active_profile_name
|
|
|
|
def mm(v):
|
|
# format for KiCad constraints
|
|
return f"{v:.3f}mm"
|
|
|
|
def main():
|
|
ap = argparse.ArgumentParser()
|
|
ap.add_argument("--profile", default="", help="Profile name (default: active profile)")
|
|
args = ap.parse_args()
|
|
|
|
prof_name = args.profile.strip() or load_active_profile_name()
|
|
prof = load_profile(prof_name)
|
|
rules = prof.get("pcb_rules") or {}
|
|
|
|
tw = float(rules.get("min_track_width_mm", 0.20))
|
|
cl = float(rules.get("min_clearance_mm", 0.20))
|
|
drill = float(rules.get("min_via_drill_mm", 0.30))
|
|
ar = float(rules.get("min_annular_ring_mm", 0.15))
|
|
|
|
out = []
|
|
out.append("(version 1)")
|
|
out.append(f"# Generated from compliance profile: {prof_name}")
|
|
out.append(f"# Min track width: {tw} mm; min clearance: {cl} mm; min drill: {drill} mm; min annular ring: {ar} mm")
|
|
out.append("")
|
|
out.append(f"(rule \"Track width (all layers)\" (condition \"A.Type == 'track'\") (constraint track_width (min {mm(tw)})) )")
|
|
out.append(f"(rule \"Clearance (track/pad/via)\" (condition \"A.Net != B.Net\") (constraint clearance (min {mm(cl)})) )")
|
|
out.append(f"(rule \"Hole diameter (all)\" (constraint hole_size (min {mm(drill)})) )")
|
|
out.append(f"(rule \"Annular ring width (plated)\" (condition \"A.isPlated()\") (constraint annular_width (min {mm(ar)})) )")
|
|
print("\n".join(out))
|
|
|
|
if __name__ == "__main__":
|
|
main()
|