master
John Lauer 0.9.340: routing tests, demo runner + evidence (arav-rog 2026-09-07), vendoring and overlay tools, release notes 25dcdaf 1mo ago
"""Create a small, entirely unrouted two-layer routing regression board."""
from pathlib import Path
import json
import uuid


def make(directory):
    directory = Path(directory)
    directory.mkdir(parents=True, exist_ok=True)
    base = Path(__file__).resolve().parents[2] / 'templates/blank-board.kicad_pcb'
    text = base.read_text()
    blocks=[]
    def footprint(ref,x,y,pads):
        body=f'(footprint "RoutingFixture:{ref}" (layer "F.Cu") (uuid "{uuid.uuid4()}") (at {x} {y})\n'
        body+=f'(property "Reference" "{ref}" (at 0 -3) (layer "F.SilkS") (effects (font (size 1 1) (thickness 0.15))))\n'
        body+=f'(property "Value" "ROUTING_TEST" (at 0 -5) (layer "F.Fab") (effects (font (size 1 1) (thickness 0.15))))\n'
        body+='(attr through_hole exclude_from_pos_files exclude_from_bom)\n'
        for number, px, py, net in pads:
            body+=f'(pad "{number}" thru_hole circle (at {px} {py}) (size 2 2) (drill 1) (layers "*.Cu" "*.Mask") (net "{net}") (uuid "{uuid.uuid4()}"))\n'
        blocks.append(body+')\n')
    footprint('J1',105,85,[(str(i),0,(i-1)*5,f'NET_{i}') for i in range(1,7)])
    footprint('J2',145,85,[(str(i),0,(i-1)*5,f'NET_{i}') for i in range(1,7)])
    footprint('J3',125,116,[('1',0,0,'NET_6')])
    blocks.append(f'(gr_rect (start 98 78) (end 152 122) (stroke (width 0.05) (type default)) (fill none) (layer "Edge.Cuts") (uuid "{uuid.uuid4()}"))\n')
    output=directory/'live-routing.kicad_pcb'
    output.write_text(text[:text.rfind(')')]+''.join(blocks)+')\n')
    plan=[]
    for i in range(1,7):
        y=85+(i-1)*5
        points=[f'J1.{i}',[112,y],[138,y],f'J2.{i}']
        if i==3:
            points=[f'J1.{i}',{'x':112,'y':y,'layer':'B.Cu'},{'x':138,'y':y,'layer':'F.Cu'},f'J2.{i}']
        row={'net':f'NET_{i}','width':0.25,'points':points}
        if i==6:
            row.pop('points'); row['paths']=[points,[[125,y], [125,113], 'J3.1']]
        plan.append(row)
    (directory/'plan.json').write_text(json.dumps(plan,indent=2)+'\n')
    return output

if __name__=='__main__':
    import sys
    print(make(sys.argv[1] if len(sys.argv)>1 else Path(__file__).parent/'fixture'))