Skip to content
Merged
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
2 changes: 1 addition & 1 deletion logic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ function parseKeeplist(text: string): KeeplistConfig {
continue;
}

if (line.startsWith("!rename")) {
if (/^!rename(\s|$)/.test(line)) {
const directive = parseRenameDirective(line, lineNumber);

if (seenFrom.has(directive.from)) {
Expand Down
41 changes: 41 additions & 0 deletions logic_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1139,6 +1139,47 @@ Deno.test("scanForRemoval rejects malformed !rename without arrow", async () =>
}
});

Deno.test("scanForRemoval treats !rename-prefixed literals as keep rules", async () => {
const root = await Deno.makeTempDir();
try {
await Deno.writeTextFile(
join(root, KEEPLIST_FILE),
["mods/**", "!rename_backup.dll"].join("\n"),
);

await Deno.mkdir(join(root, "mods"), { recursive: true });
await Deno.writeTextFile(join(root, "mods", "keep.txt"), "keep");
await Deno.mkdir(join(root, "trash"), { recursive: true });
await Deno.writeTextFile(join(root, "trash", "remove.txt"), "remove");

const removable = await scanForRemoval(root);
assertEquals(removable, ["trash/remove.txt"]);

const keepRules = await readKeeplist(root);
assertEquals(keepRules, ["mods/**", "!rename_backup.dll"]);
} finally {
await Deno.remove(root, { recursive: true });
}
});

Deno.test("scanForRemoval rejects malformed !rename directives with tab after token", async () => {
const root = await Deno.makeTempDir();
try {
await Deno.writeTextFile(
join(root, KEEPLIST_FILE),
["mods/**", "!rename\tfrom.txt to.txt"].join("\n"),
);

await assertRejects(
() => scanForRemoval(root),
Error,
"expected '!rename <from> -> <to>'",
);
} finally {
await Deno.remove(root, { recursive: true });
}
});

Deno.test("scanForRemoval rejects !rename with missing from path", async () => {
const root = await Deno.makeTempDir();
try {
Expand Down