feat: add line numbers, fix utility/ path mapping, improve verbose output

- Add utility/ to direct path mapping (was incorrectly falling through
  to src/modules/utility/)
- Show line numbers for broken references in markdown files
- Show YAML key path for broken references in YAML files
- Print file headers in verbose mode for all files with refs
This commit is contained in:
Michael Pursifull 2026-01-31 14:17:47 -06:00
parent 1b863ee9c7
commit 961a892578
No known key found for this signature in database
1 changed files with 21 additions and 5 deletions

View File

@ -145,8 +145,8 @@ function mapInstalledToSource(refPath) {
// Skip install-only paths (generated at install time, not in source) // Skip install-only paths (generated at install time, not in source)
if (isInstallOnly(cleaned)) return null; if (isInstallOnly(cleaned)) return null;
// core/ and bmm/ are directly under src/ // core/, bmm/, and utility/ are directly under src/
if (cleaned.startsWith('core/') || cleaned.startsWith('bmm/')) { if (cleaned.startsWith('core/') || cleaned.startsWith('bmm/') || cleaned.startsWith('utility/')) {
return path.join(SRC_DIR, cleaned); return path.join(SRC_DIR, cleaned);
} }
@ -222,6 +222,14 @@ function extractYamlRefs(filePath, content) {
return refs; return refs;
} }
function offsetToLine(content, offset) {
let line = 1;
for (let i = 0; i < offset && i < content.length; i++) {
if (content[i] === '\n') line++;
}
return line;
}
function extractMarkdownRefs(filePath, content) { function extractMarkdownRefs(filePath, content) {
const refs = []; const refs = [];
const stripped = stripJsonExampleBlocks(stripCodeBlocks(content)); const stripped = stripJsonExampleBlocks(stripCodeBlocks(content));
@ -232,7 +240,7 @@ function extractMarkdownRefs(filePath, content) {
while ((match = regex.exec(stripped)) !== null) { while ((match = regex.exec(stripped)) !== null) {
const raw = match[1]; const raw = match[1];
if (!isResolvable(raw)) continue; if (!isResolvable(raw)) continue;
refs.push({ file: filePath, raw, type }); refs.push({ file: filePath, raw, type, line: offsetToLine(stripped, match.index) });
} }
} }
@ -342,6 +350,11 @@ for (const filePath of files) {
// Resolve and check // Resolve and check
const broken = []; const broken = [];
if (VERBOSE && refs.length > 0) {
console.log(`\n${relativePath}`);
}
for (const ref of refs) { for (const ref of refs) {
totalRefs++; totalRefs++;
const resolved = resolveRef(ref); const resolved = resolveRef(ref);
@ -369,10 +382,13 @@ for (const filePath of files) {
// Report issues for this file // Report issues for this file
if (broken.length > 0 || leaks.length > 0) { if (broken.length > 0 || leaks.length > 0) {
filesWithIssues++; filesWithIssues++;
console.log(`\n${relativePath}`); if (!VERBOSE) {
console.log(`\n${relativePath}`);
}
for (const { ref, resolved } of broken) { for (const { ref, resolved } of broken) {
console.log(` [BROKEN] ${ref.raw}`); const location = ref.line ? `line ${ref.line}` : ref.key ? `key: ${ref.key}` : '';
console.log(` [BROKEN] ${ref.raw}${location ? ` (${location})` : ''}`);
console.log(` Target not found: ${resolved}`); console.log(` Target not found: ${resolved}`);
} }