rename function

This commit is contained in:
Rikuoh Tsujitani 2025-02-17 22:57:20 +09:00
parent 84b12de330
commit b07badacb1
Signed by: riq0h
GPG key ID: 010F09DEA298C717
2 changed files with 107 additions and 0 deletions
src
commands
utils

73
src/commands/rename.ts Normal file
View file

@ -0,0 +1,73 @@
import * as fs from "fs";
import * as path from "path";
import { openEditor } from "../utils/editor";
export interface RenameOperation {
oldName: string;
newName: string;
path: string;
newPath: string;
}
export async function renameFiles(): Promise<void> {
try {
const files = fs
.readdirSync(process.cwd())
.filter((file) => !file.startsWith("."));
const fileContent = files.join("\n");
const editedContent = await openEditor(fileContent);
const newNames = editedContent.trim().split("\n");
if (newNames.length !== files.length) {
throw new Error(
"the number of files and lines do not match. renaming was not performed.",
);
}
const uniqueNames = new Set(newNames);
if (uniqueNames.size !== newNames.length) {
throw new Error("file names are duplicated. renaming was not performed.");
}
if (newNames.some((name) => /[\s ]/.test(name))) {
throw new Error(
"file names cannot contain whitespace characters. renaming was not performed.",
);
}
newNames.forEach((name) => {
if (name.includes("/") || name.includes("\\")) {
throw new Error(
"file names cannot contain paths. renaming was not performed.",
);
}
});
const operations = files.map((oldName, index) => ({
oldName,
newName: newNames[index],
path: path.join(process.cwd(), oldName),
newPath: path.join(process.cwd(), newNames[index]),
}));
if (!operations.some((op) => op.oldName !== op.newName)) {
console.log("no changes were made. renaming was not performed.");
return;
}
for (const op of operations) {
if (op.oldName !== op.newName) {
fs.renameSync(op.path, op.newPath);
}
}
console.log("renaming completed successfully.");
} catch (error: unknown) {
if (error instanceof Error) {
console.error("error:", error.message);
} else {
console.log("unknown error.");
process.exit(1);
}
}
}

34
src/utils/editor.ts Normal file
View file

@ -0,0 +1,34 @@
import * as fs from "fs";
import * as os from "os";
import * as path from "path";
import { spawn } from "child_process";
export function openEditor(content: string): Promise<string> {
return new Promise((resolve, reject) => {
const editor: string = process.env.EDITOR || "vim";
const tmpFile: string = path.join(
os.tmpdir(),
`mtt-rename-${Date.now()}.txt`,
);
fs.writeFileSync(tmpFile, content);
const child = spawn(editor, [tmpFile], {
stdio: "inherit",
});
child.on("exit", (code: number) => {
if (code === 0) {
const editedContent: string = fs.readFileSync(tmpFile, "utf8");
fs.unlinkSync(tmpFile);
resolve(editedContent);
} else {
fs.unlinkSync(tmpFile);
reject(new Error(`editor exited with code ${code}`));
}
});
child.on("error", (err: Error) => {
fs.unlinkSync(tmpFile);
reject(err);
});
});
}