Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions src/drift/__tests__/path-false-positives.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,20 @@ describe("MISSING_PATH false positives", () => {
).toEqual([]);
});

// Not part of #143. A trailing version number reads as a file extension to
// the guard above, so `release/2.1.0` never reaches the unrooted check and is
// reported as a missing path. Tracked separately; unskip with the fix.
it.skip("does not claim a version-shaped branch name", () => {
it("does not claim a version-shaped branch name", () => {
expect(
missingPaths("# Release\n\n- Work landed on `release/2.1.0` and `python/3.11`\n")
missingPaths(
"# Release\n\n- Work landed on `release/2.1.0`, `python/3.11`, and `node/20.11`\n"
)
).toEqual([]);
});

it("still claims a missing file with an alphabetic extension", () => {
// Tightening the extension check must not treat `docs/foo.bar` as unrooted
// prose: `.bar` is a file type, so the claim stays a missing path.
expect(missingPaths("# Docs\n\n- See `docs/foo.bar`\n")).toEqual(["docs/foo.bar"]);
});

it("does not claim a pseudo-path pair such as overall/overall", () => {
expect(missingPaths("# Stats\n\n- Rating shown as `overall/overall`\n")).toEqual([]);
});
Expand Down
5 changes: 4 additions & 1 deletion src/drift/checkers/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,10 @@ function isUnrootedReference(
const trimmed = value.replace(/\/+$/, "");
const isDirectoryRef = trimmed !== value;
if (!trimmed.includes("/") && !isDirectoryRef) return false;
if (/\.[A-Za-z0-9]+$/.test(trimmed)) return false;
// A trailing numeric-only segment is a version (`release/2.1.0`,
// `python/3.11`), not a file type. Require an alphabetic character so
// `.ts` still counts as an extension and those tokens reach the prose check.
if (/\.[A-Za-z0-9]*[A-Za-z][A-Za-z0-9]*$/.test(trimmed)) return false;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Preserve missing files with numeric extensions

A numeric extension does not necessarily make the complete filename a version. For example, when manuals/ exists at neither the project nor scaffold root, a documented manuals/mex.1 now reaches the unrooted-reference check and is silently discarded. The base commit correctly reports MISSING_PATH. The same regression occurs for manuals/admin.8 and logs/server.log.1.

Reproduction to add to path-false-positives.test.ts, using its existing helper:

expect(missingPaths("# Docs\n\n- See `manuals/mex.1`\n"))
  .toEqual(["manuals/mex.1"]); // actual on this PR: []

Please recognize a complete version-shaped final component before applying the exemption, and retain ordinary numeric-extension filenames. Keep the existing-parent and explicitly relative path behavior intact.


const first = trimmed.split("/")[0];
if (!first || first.startsWith("@") || first === "." || first === "..") return false;
Expand Down