Repository navigation
fix(pcb): write mounting holes under the footprint names KiCad ships - #512
Conversation
neusse
left a comment
There was a problem hiding this comment.
Please correct the inline fallback/readback path and supply the missing live-KiCad evidence before this can close #462.
- The inline branch appends
H1directly and thenwritten_footprint_lib_idreturns the first matching Reference. IfH1already exists, the write can create a duplicate and the response can report the old footprint's lib_id rather than the one just written. Route inline geometry through the same duplicate-reference-checked insertion path as library placement, or bind/read back the inserted footprint by unique identity. Add a duplicate-reference test proving byte-identical refusal and correct result-derived readback. - Exercise the changed IPC success path with KiCad live, then read the saved board and show the placed lib_id/geometry agrees. The current E2E explicitly used an unreachable IPC endpoint, so the changed live path is core behavior without observation. Keep an unavailable GUI/library-warning check as named validation debt if necessary; the original "board fails to load" symptom was not reproduced by
kicad-cliand should be corrected in #462 rather than asserted. - Tighten the new internal contract: use unit-bearing names (
drill_diameter_mm) and preferably a small namedMountingHoleSpecinstead of(f64, &str). Also hide the deeppcb_componentspipeline behind one cohesive shared operation rather than making several placement internalspub(crate)to be orchestrated frompcb_board.
The exact KiCad 10 name table, unsupported-size refusal, migration text, fixture/conformance checks, and negative controls are otherwise strong. After these changes, push one refreshed head, rerun all ten checks, and update the evidence/closure text; #511 remains ahead of this independent PR only because it is already exact-head approved.
|
Queue refresh — the existing three-item correction request remains unchanged on head Please: (1) route inline mounting-hole placement through duplicate-reference-safe insertion with identity-bound readback and a byte-identical refusal regression; (2) supply live-KiCad IPC success/readback evidence and correct #462's unreproduced board-load claim; and (3) tighten the internal contract behind one cohesive shared operation using unit-bearing/named inputs such as Make the code corrections without repeatedly rebasing. When this PR reaches its queue turn after #485, reconstruct once onto current |
add_mounting_hole formatted its lib_id as MountingHole:MountingHole_{drill:.1}mm.
KiCad 10 ships no plain MountingHole_3.2mm — 3.2 mm exists only as the M3
family — and spells round sizes without a decimal (MountingHole_3mm), so the
default call and every integer size wrote a name no stock KiCad resolves.
The lib_id now comes from a table of the unplated mounting holes KiCad 10
ships, spelled as the library spells them, and a drill with no shipped
footprint is refused with a structured invalid_argument before anything is
written. A conformance test checks the table against the installed library
when one is present, and that the names the old formatter produced do not
exist there.
When MountingHole.pretty resolves from the machine, the hole placed is KiCad's
own library footprint through the same pipeline place_component uses, so the
name and the geometry are KiCad's. Otherwise Konnect's unplated-hole geometry
is written under the shipped name, with the pad equal to the drill as KiCad's
plain footprints have it (the old +0.5 annulus matched no library footprint),
and the response says which geometry landed. The footprint field is read back
from the saved board rather than repeated from the request.
Closes #462
449002d to
817f5e7
Compare
neusse
left a comment
There was a problem hiding this comment.
The refreshed exact head satisfies the requested duplicate-reference safety, identity-bound readback, cohesive internal contract, and live KiCad IPC evidence. Hosted checks are still required before merge.
Summary
add_mounting_holeformatted its lib_id asMountingHole:MountingHole_{drill:.1}mm. Checked against the installed KiCad 10MountingHole.pretty(167 footprints): there is no plainMountingHole_3.2mm— 3.2 mm exists only as the M3 family — and KiCad spells round sizes without a decimal (MountingHole_3mm, never3.0mm). So the default call and every integer size wrote a name no stock KiCad resolves.Closes #462
Approach
MOUNTING_HOLE_NAMESlists the 19 unplated mounting holes KiCad 10 ships (plain sizes 2 … 6.5 mm, metric-clearance sizes2.2mm_M2,3.2mm_M3,4.3mm_M4,5.3mm_M5,6.4mm_M6,8.4mm_M8).mounting_hole_lib_idreturnsNonefor anything else, and the handler refuses before writing withinvalid_argumentondrill_diameterlisting the shipped sizes. A conformance test checks every table entry against the installed library when one is present (and that the old formatter's names do not exist there), skipping silently otherwise — the same pattern as the guidance library-ID check.MountingHole.prettyresolves from the machine (project or globalfp-lib-table, or a discovered install), the hole placed is that library footprint, through the sameprepare_footprint_source/extract_*/board_footprint_sexppipelineplace_componentuses (three of those madepub(crate)). Name and geometry are then KiCad's, solib_footprint_mismatchhas nothing to say.MountingHole_*footprints have it (the olddrill + 0.5annulus matched no library footprint). The response carriesgeometry: "library" | "inline"and, for inline,geometry_note.footprintfield is read back from the saved board (written_footprint_lib_id), not repeated from the request.Branch and dependencies
Base branch:
mainat2fbc5f5.Depends on: nothing. Independent of #511 (different files).
Series order: none — single PR, one commit.
Overlap: none with any open PR.
Next PR to promote after this one: none in this chain.
Compatibility and safety
drill_diameterkeeps its default of 3.2 and its type; its description now lists the shipped sizes.geometry,geometry_note.footprintkeeps its name and meaning but is now derived from the file on the file path.insert_into_board(consistent read, duplicate-reference refusal, parse-before-write, atomic write); the inline path is unchanged apart from the name and pad size. Refusals write nothing (asserted byte-identical).attempt_ipc_writegate as before; a reachable KiCad that rejects never touches the file (existing test, kept).docs/API_MIGRATIONS.mdand thetool-directory.mdrow carry the change. No tool added or removed.Validation
Run on commit
449002d(Windows, KiCad 10.0 installed), exit codes captured directly:cargo fmt --all -- --checkcargo test --workspace --locked --lib --testscargo test --workspace --locked --doccargo clippy --workspace --locked --all-targets -- -D warningsevery_shipped_name_exists_in_the_installed_libraryran against the installed KiCad 10 here (19/19 present;MountingHole_3.2mm/_3.0mm/_4.0mmconfirmed absent), and the E2E below. Linux/macOS not run here; hosted CI covers the matrix, and the conformance test skips where no KiCad is installed.Reproduced first, on
mainwith a release binary: placing 3.2 / 3.0 / 4.0 mm holes wroteMountingHole_3.2mm,MountingHole_3.0mm,MountingHole_4.0mm— none of which exist in the installedMountingHole.pretty. Headlesskicad-cli pcb upgrade/drcstill load such a board (the footprint is embedded), so the "fails to load" symptom in the issue is the GUI's library-resolution path; the wrong names are the defect either way and are reproduced exactly.Negative controls (each neutered, then restored):
{drill:.1}mmformatter restored inmounting_hole_lib_idshipped_drills_get_the_library_spelling,the_default_drill_writes_a_name_stock_kicad_resolvesan_unshipped_drill_has_no_name,an_unshipped_drill_refuses_before_writing, plus the two aboveRestored tree: 8/8 green.
E2E on this branch's release binary over MCP (fresh project, KiCad IPC unreachable so the guarded file path runs):
add_mounting_hole3.2MountingHole:MountingHole_3.2mm_M3,geometry: "library"add_mounting_hole3.0MountingHole:MountingHole_3mm,geometry: "library"add_mounting_hole4.0MountingHole:MountingHole_4mm,geometry: "library"add_mounting_hole3.3invalid_argumentondrill_diameter, shipped sizes listed, nothing writtenAll three names verified present as
.kicad_modfiles in the installedMountingHole.pretty;kicad-cli pcb drcon the result reports nolib_footprint_mismatch. It does reportlib_footprint_issues: library not enabled in the current configurationfor each hole — a headless-CLI limitation, not the board: this machine's globalfp-lib-tableis KiCad's standard nested(type "Table")entry for the stock libraries, and the same headless run flags every footprint of KiCad's own ecc83 demo identically. The GUI resolves them. So the one check I cannot make headlessly is the GUI open with no library warning; the names are now the ones the GUI's own library browser lists.Review checklist
upstream/main, has no merge conflicts, and CI passed on this exact head.upstream/main, not a release tag.docs/NAMING_CONVENTIONS.md(geometry,geometry_note); no public renames.cargo xtask fix-doc-counts --checkunchanged.Maintainer merge state
status:*workflow label.status:ready-to-mergeapplies to this exact head SHA.mainruleset.gh pr merge N --mergeafter final verification.Maintainer refresh on current
mainReconstructed onto
upstream/mainatfbebd991e668aa8396bb4ec2893ae4b86db337cf; current head is817f5e75687fec53f1522060100c60bac8181a44.The requested corrections are now included:
PreparedFootprintPlacementoperation backed by the existing atomic, duplicate-reference-safe insertion path.MountingHoleSpeccarriesdrill_diameter_mm, reference, and resolved lib_id together; the low-level preparation/serialization helpers are private again.H1refusal leaves the board byte-identical.Observed live on Windows / KiCad 10.0.6:
The call returned
source: "ipc", live KiCad read backMountingHole:MountingHole_3.2mm_M3, and KiCad save persisted that exact id with a 3.2 mmnp_thru_holedrill.Duplicate-safety negative control: temporarily disabling reference rejection made
inline_file_placement_refuses_a_duplicate_reference_without_writingfail because the duplicate was committed and readback became ambiguous. The restored guard passes.Exact-head local gate:
Issue #462's title/evidence has been corrected: the invalid library names are reproduced; a board-load failure is not. Headless KiCad loads the embedded geometry. A GUI warning across every library-table configuration remains validation debt, not a claimed pass.