kebab-ify-files icon indicating copy to clipboard operation
kebab-ify-files copied to clipboard

Getting error when running the script

Open jisuo opened this issue 1 year ago • 3 comments

Getting this error after a while:

node:child_process:929
    throw err;
    ^

<ref *1> Error: spawnSync /Users/jisuo/Code/pwa/git-rename-commands.sh Unknown system error -8
    at Object.spawnSync (node:internal/child_process:1124:20)
    at spawnSync (node:child_process:876:24)
    at execFileSync (node:child_process:919:15)
    at /Users/jisuo/.npm/_npx/faf6fa9f064ad02f/node_modules/kebab-ify-files/cli.js:152:19
    at /Users/jisuo/.npm/_npx/faf6fa9f064ad02f/node_modules/recursive-readdir/index.js:81:22
    at /Users/jisuo/.npm/_npx/faf6fa9f064ad02f/node_modules/recursive-readdir/index.js:81:22
    at /Users/jisuo/.npm/_npx/faf6fa9f064ad02f/node_modules/recursive-readdir/index.js:81:22
    at /Users/jisuo/.npm/_npx/faf6fa9f064ad02f/node_modules/recursive-readdir/index.js:81:22
    at /Users/jisuo/.npm/_npx/faf6fa9f064ad02f/node_modules/recursive-readdir/index.js:81:22
    at /Users/jisuo/.npm/_npx/faf6fa9f064ad02f/node_modules/recursive-readdir/index.js:81:22 {
  errno: -8,
  code: 'Unknown system error -8',
  syscall: 'spawnSync /Users/jisuo/Code/pwa/git-rename-commands.sh',
  path: '/Users/jisuo/Code/pwa/git-rename-commands.sh',
  spawnargs: [],
  error: [Circular *1],
  status: null,
  signal: null,
  output: null,
  pid: 0,
  stdout: null,
  stderr: null
}

Node.js v20.16.0

git-rename-commands.sh has been created with a bunch of git mv commands but no kebab-ify.log exist.

Any idea what could be the issue? Trying to search for these error messages.

jisuo avatar Nov 15 '24 15:11 jisuo

So the first errors was that first line of git-rename-commands.sh was git #!/bin/bash which is an error. The code needs prepend that to gitcommands array after adding all the files.

After that the script ran but I encountered a lot of git mv problems and they happened because it tried to move files in a folder that was not renamed, but it tried to move them to the renamed folder.

I tried to hand over the task to chat gpt and after some trial and error I got something working where I go depth first. It is MUCH slower since it does not batch updates, instead doing them in a loop. I think I also got a bunch of other problems, but I did a lot of manual problem solving as well, so the script is not 100% working, but here it is:

import fs from "fs";
import path from "path";
import { execSync } from "child_process";

function toKebabCase(str: string): string {
    return str
        .replace(/([a-z])([A-Z])/g, "$1-$2") // Handle camelCase or PascalCase
        .replace(/([A-Z])([A-Z][a-z])/g, "$1-$2") // Handle edge cases with two capitals
        .toLowerCase();
}

function renameWithGitMv(oldPath: string, newPath: string): void {
    try {
        execSync(`git mv "${oldPath}" "${newPath}"`);
    } catch (error) {
        console.error(`Error: git mv failed for ${oldPath} -> ${newPath}`);
        process.exit(1);
    }
}

function processFolder(dir: string): void {
    const entries = fs.readdirSync(dir, { withFileTypes: true });
    const folders: fs.Dirent[] = [];
    const files: fs.Dirent[] = [];

    // Separate folders and files
    for (const entry of entries) {
        if (entry.name === ".DS_Store") continue; // Ignore .DS_Store
        if (entry.isDirectory()) {
            folders.push(entry);
        } else {
            files.push(entry);
        }
    }

    // Process subfolders (deepest-first)
    for (const folder of folders) {
        const folderPath = path.join(dir, folder.name);
        processFolder(folderPath); // Recurse into the folder
    }

    // Rename files in the current folder
    for (const file of files) {
        const oldFilePath = path.join(dir, file.name);
        const kebabCaseName = toKebabCase(file.name);
        const ext = path.extname(file.name);
        const base = path.basename(file.name, ext);
        const tempFilePath = path.join(dir, `${base}.temp${ext}`);
        const finalFilePath = path.join(dir, kebabCaseName);

        // Step 1: Rename to temp
        renameWithGitMv(oldFilePath, tempFilePath);

        // Step 2: Rename to final name
        renameWithGitMv(tempFilePath, finalFilePath);
    }

    // Rename the current folder after processing its contents
    const currentFolderName = path.basename(dir);
    const parentDir = path.dirname(dir);
    const kebabCaseName = toKebabCase(currentFolderName);
    const tempFolderPath = path.join(parentDir, kebabCaseName + "-temp");
    const finalFolderPath = path.join(parentDir, kebabCaseName);

    if (currentFolderName !== kebabCaseName) {
        // Step 1: Rename to temp
        renameWithGitMv(dir, tempFolderPath);

        // Step 2: Rename to final name
        renameWithGitMv(tempFolderPath, finalFolderPath);
    }
}

function updateImportsWithGit(dir: string): void {
    const entries = fs.readdirSync(dir, { withFileTypes: true });

    for (const entry of entries) {
        const fullPath = path.join(dir, entry.name);

        if (entry.name === ".DS_Store") continue; // Ignore .DS_Store

        if (entry.isDirectory()) {
            updateImportsWithGit(fullPath);
        } else if (entry.isFile() && (entry.name.endsWith(".ts") || entry.name.endsWith(".tsx"))) {
            let content = fs.readFileSync(fullPath, "utf-8");

            // Regular `import` or `require`
            const importRegex = /from\s+['"]([^'"]+)['"]/g;

            // Lazy imports like `import(...)`, supports multiline
            const lazyImportRegex = /import\s*\(\s*(['"])(.*?)\1\s*\)/gs;

            let hasChanges = false;

            // Update standard imports
            content = content.replace(importRegex, (_, importPath) => {
                const kebabCasePath = toKebabCase(importPath);
                hasChanges = true;
                return `from '${kebabCasePath}'`;
            });

            // Update lazy imports
            content = content.replace(lazyImportRegex, (_, quote, importPath) => {
                const kebabCasePath = toKebabCase(importPath);
                hasChanges = true;
                return `import(${quote}${kebabCasePath}${quote})`;
            });

            if (hasChanges) {
                fs.writeFileSync(fullPath, content); // Apply changes locally
                execSync(`git add "${fullPath}"`); // Stage changes in Git
            }
        }
    }
}

function main() {
    const targetDir = process.argv[2];
    if (!targetDir) {
        console.error("Usage: ts-node script.ts <target-directory>");
        process.exit(1);
    }

    const absolutePath = path.resolve(targetDir);
    processFolder(absolutePath);
    updateImportsWithGit(absolutePath);
}

main();

jisuo avatar Nov 29 '24 16:11 jisuo

The problem seems to be related to the Node.js version — v20.16.0 didn't work for me.

Switched to v14.18.0 and it worked. @jisuo

dunckr avatar Apr 10 '25 08:04 dunckr

NVM fails to install node 14 for me now, but the kebabify script worked with node 16.

Note: I opened a PR addressing this

NickRawls avatar Oct 16 '25 20:10 NickRawls