feat: promote extensionless unresolved paths from silent skip to [UNRESOLVED]

Paths without file extensions that don't exist as files or directories
are now flagged as [UNRESOLVED] — a distinct tag from [BROKEN] (which
means a file with a known extension wasn't found). Both count toward
the broken reference total and appear in CI annotations.

This catches real bugs like wrong directory names in installed_path
metadata and dead invoke-workflow references to removed workflows.
Extensionless paths that DO exist as directories are still [OK-DIR].
This commit is contained in:
Michael Pursifull 2026-02-07 14:17:35 -06:00
parent 3f5d059c42
commit 1ac25c2a7a
No known key found for this signature in database
1 changed files with 15 additions and 7 deletions

View File

@ -444,11 +444,14 @@ if (require.main === module) {
if (fs.existsSync(resolved)) { if (fs.existsSync(resolved)) {
ok.push({ ref, tag: 'OK-DIR' }); ok.push({ ref, tag: 'OK-DIR' });
} else { } else {
ok.push({ ref, tag: 'SKIP', note: 'no extension, target not found' }); // No extension and nothing exists — not a file, not a directory.
// Flag as UNRESOLVED (distinct from BROKEN which means "file with extension not found").
broken.push({ ref, resolved: path.relative(PROJECT_ROOT, resolved), kind: 'unresolved' });
brokenRefs++;
} }
continue; continue;
} }
broken.push({ ref, resolved: path.relative(PROJECT_ROOT, resolved) }); broken.push({ ref, resolved: path.relative(PROJECT_ROOT, resolved), kind: 'broken' });
brokenRefs++; brokenRefs++;
continue; continue;
} }
@ -476,14 +479,19 @@ if (require.main === module) {
} }
} }
for (const { ref, resolved } of broken) { for (const { ref, resolved, kind } of broken) {
const location = ref.line ? `line ${ref.line}` : ref.key ? `key: ${ref.key}` : ''; const location = ref.line ? `line ${ref.line}` : ref.key ? `key: ${ref.key}` : '';
console.log(` [BROKEN] ${ref.raw}${location ? ` (${location})` : ''}`); const tag = kind === 'unresolved' ? 'UNRESOLVED' : 'BROKEN';
console.log(` Target not found: ${resolved}`); const detail = kind === 'unresolved' ? 'Not found as file or directory' : 'Target not found';
allIssues.push({ file: relativePath, line: ref.line || 1, ref: ref.raw, issue: 'broken ref' }); const issueType = kind === 'unresolved' ? 'unresolved path' : 'broken ref';
console.log(` [${tag}] ${ref.raw}${location ? ` (${location})` : ''}`);
console.log(` ${detail}: ${resolved}`);
allIssues.push({ file: relativePath, line: ref.line || 1, ref: ref.raw, issue: issueType });
if (process.env.GITHUB_ACTIONS) { if (process.env.GITHUB_ACTIONS) {
const line = ref.line || 1; const line = ref.line || 1;
console.log(`::warning file=${relativePath},line=${line}::${escapeAnnotation(`Broken reference: ${ref.raw}${resolved}`)}`); console.log(
`::warning file=${relativePath},line=${line}::${escapeAnnotation(`${tag === 'UNRESOLVED' ? 'Unresolved path' : 'Broken reference'}: ${ref.raw}${resolved}`)}`,
);
} }
} }