#!/usr/bin/env bash set -euo pipefail cd "$(dirname "$0")" # LinuxCNC source basis: this guard keeps the kinematics source map aligned # with linuxcnc-kinematics-source-files.txt, which enumerates LinuxCNC # kinematics, posemath, switchkins INI/HAL/remap/tooldata/assets, and adjacent # build metadata. It validates source coverage documentation only; it does not # add CNC behavior, expand smoke parsing, or interpret G-code. linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc} linuxcnc_root=$(cd "$linuxcnc_root" && pwd) grep -F 'GENSERKINSSRCS := emc/kinematics/ugenserkins.c' \ "$linuxcnc_root/src/emc/kinematics/Submakefile" >/dev/null grep -F 'extern int kinematicsInverse(const struct EmcPose * world,' \ "$linuxcnc_root/src/emc/kinematics/kinematics.h" >/dev/null grep -F 'extern int kinematicsSwitch(int switchkins_type);' \ "$linuxcnc_root/src/emc/kinematics/kinematics.h" >/dev/null grep -F 'motion.switchkins-type' \ "$linuxcnc_root/configs/sim/axis/vismach/5axis/bridgemill/5axis.ini" >/dev/null grep -F '#' \ "$linuxcnc_root/configs/sim/axis/vismach/5axis/bridgemill/remap_subs/428remap.ngc" >/dev/null python3 - <<'PY' from pathlib import Path import re manifest = Path("linuxcnc-kinematics-source-files.txt").read_text(encoding="utf-8").splitlines() source_map = Path("docs/linuxcnc-kinematics-source-map.md").read_text(encoding="utf-8") expected_groups = [ "core", "config", "remap", "component", "generated", "header", "metadata", "asset", "tooldata", ] counts = {group: 0 for group in expected_groups} for line in manifest: if not line or line.startswith("#"): continue group = line.split(":", 1)[0] if group not in counts: raise SystemExit(f"unexpected kinematics manifest group in source map guard: {group}") counts[group] += 1 for group, count in counts.items(): pattern = rf"\| `{re.escape(group)}` \| {count} \|" if not re.search(pattern, source_map): raise SystemExit( f"docs/linuxcnc-kinematics-source-map.md {group} count no longer matches linuxcnc-kinematics-source-files.txt" ) for group in expected_groups: if f"`{group}`" not in source_map: raise SystemExit( f"docs/linuxcnc-kinematics-source-map.md is missing kinematics manifest group {group}" ) required_phrases = [ "LinuxCNC Source Anchors", "must not add CNC behavior", "must not", "expand the temporary smoke parser", "`src/emc/kinematics/Submakefile`", "`src/emc/kinematics/kinematics.h`", "motion.switchkins-type", "`#` remap assignment", "not browser API surface", "OPFS-only", "derive M428/M429/M430 cases from", "RTCP and five-axis coverage", "./check-linuxcnc-kinematics-source-map.sh", "./check-linuxcnc-inputs.sh linuxcnc-kinematics-source-files.txt --require-kinematics-complete", "./check-linuxcnc-switchkins-remap-table.sh linuxcnc-kinematics-source-files.txt", "does not interpret G-code", ] for phrase in required_phrases: if phrase not in source_map: raise SystemExit( f"docs/linuxcnc-kinematics-source-map.md is missing source-coverage boundary phrase: {phrase}" ) for entry in [ "test-native.sh", "test-linuxcnc-source-link.sh", "build-wasm.sh", ]: text = Path(entry).read_text(encoding="utf-8") if "./check-linuxcnc-kinematics-source-map.sh" not in text: raise SystemExit(f"{entry} must run ./check-linuxcnc-kinematics-source-map.sh") PY