Skip to content

Instantly share code, notes, and snippets.

@edygar
Last active October 30, 2020 09:09
Show Gist options
  • Save edygar/01f1f5cce52d348b4eaa07fd0286bcc2 to your computer and use it in GitHub Desktop.
Save edygar/01f1f5cce52d348b4eaa07fd0286bcc2 to your computer and use it in GitHub Desktop.
Move files to their kebab-version
import * as path from "https://deno.land/std@0.75.0/path/mod.ts";
import * as fs from "https://deno.land/std@0.75.0/fs/mod.ts";
import { paramCase } from "https://deno.land/x/case@v2.1.0/mod.ts";
const cwd = Deno.cwd();
// Files to be excluded during the walk
const skip = (await Deno.readTextFile(path.join(cwd, ".gitignore")))
.replace(/#.*/g, "")
.replace(/\s*\n/g, "\n")
.split(/\n/)
.filter(Boolean)
.concat([".DS_Store","/terraform", "/Dockerfile", "/.git"])
.map(pattern => path.globToRegExp(pattern.replace(/^\//, cwd + "/"), { extended: true, globstar: true }));
// walk the tree recursively
for await (const { name } of Deno.readDir(cwd)) {
await renameDir(path.join(cwd, name))
}
// walks through every fil updating the import statement
for await (const { path: target } of listImportingFiles()) {
const content = await Deno.readTextFile(target)
let newContent = content
const matches = [...content.matchAll(/(?:(?:^(?:#?(?:import|export))(?:.|[\n])*?)|(?:(?:require|mock)\())"((?:\.|(?:(?:screens|utils|hooks|locales)\/)).*?)"/gm)]
for (const [match, originalImport] of matches) {
if (originalImport.match(/\bnode_modules\b/))
continue;
const updatedImport = originalImport.split("/").map(getDestination)
newContent = newContent.replace(match, match.replace(originalImport, updatedImport.join("/")))
}
if (content !== newContent) {
console.log(target)
await Deno.writeTextFile(target, newContent);
}
}
// Move files and then the containing directory
async function renameDir(origin: string) {
if (skip.some(rule => origin.match(rule))) {
return;
}
const { isDirectory } = await Deno.lstat(origin)
if (isDirectory) {
for await (const { name } of Deno.readDir(origin)) {
await renameDir(path.join(origin, name))
}
}
const destination = getDestination(origin)
const random = '-' + parseInt((Math.random() * 100000).toString(10), 10);
await fs.move(origin, destination + random, { overwrite: true })
await fs.move(destination + random, destination, { overwrite: true })
console.log(origin, '->', destination)
}
// Apply naming rules to a file name on a given file path
function getDestination(filePath: string): string {
const fileName = path.basename(filePath)
if (fileName.match(/^_/) || fileName.match(/[\[\]]/)) {
return filePath
}
const [, prefix, ext = ""] = fileName.match(/^([^/]*?)(\..*)?$/) || [
"",
"",
"",
];
const destinationName =
filePath.slice(0, -fileName.length) +
paramCase(prefix) +
ext;
return destinationName
}
async function *listImportingFiles() {
for await (const file of fs.expandGlob("*.{js,graphql,mdx}", { exclude: ["node_modules/**"], globstar: true, extended: true }))
yield file;
for await (const file of fs.expandGlob("**/*.{js,graphql,mdx}", { exclude: ["node_modules/**"], globstar: true, extended: true }))
yield file;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment