Skip to content

Instantly share code, notes, and snippets.

@fatso83
Last active February 4, 2021 21:18
Show Gist options
  • Save fatso83/80bba191905b91f8f7f59ea94aa949a0 to your computer and use it in GitHub Desktop.
Save fatso83/80bba191905b91f8f7f59ea94aa949a0 to your computer and use it in GitHub Desktop.
Rename kebab-case files to PascalCase and vice versa
----------------------------------------------------
- Check the `require()` calls for what to `npm install`
- If you need to modify something else than `*.js` files, just modify the `find` command somewhat
#!/usr/bin/env node
/*
* Rename kebab-case files into PascalCase files and update references
*
* Basic working:
* 1. Find all kebab case files
* 2. Rename them
* 3. Use the `git grep` to get all filenames with indexed hits of the old file name
* 4. Loop through the hits and update
*/
const argv = require('yargs').argv
const { isEmpty, flowRight } = require('lodash')
const { promisify } = require('util')
const fs = require('fs')
const cp = require('child_process')
const { basename } = require('path')
const exec = promisify(cp.exec)
const readFile = promisify(fs.readFile)
const writeFile = promisify(fs.writeFile)
const moveFile = promisify(fs.rename)
const info = require('debug')('info')
const usage = `
USAGE: rename-kebab --dir src --dir test --dir some-other
Will rename all kebab-case files to PascalCase and update references in the mentioned directories
`
let dirs = ''
if (isEmpty(argv.dir)) {
// eslint-disable-next-line no-console
console.error(usage)
process.exit(1)
}
if (!Array.isArray(argv.dir)) {
dirs = [argv.dir]
} else {
dirs = argv.dir
}
async function main() {
const kebabs = await execAndParseList(`find ${dirs.join(' ')} -name '*-*.js' -type f `)
const nonPascals = await execAndParseList(`find test/ src/ -regex '.*/[a-z]\\w*\\.js' -type f`)
const filesToRename = kebabs.concat(nonPascals)
const pascalify = flowRight(fromKebabToCamel, fromCamelToPascal)
for (const fullKebabPath of filesToRename) {
const oldNameWithoutExtension = '/' + basename(fullKebabPath, '.js') + "'"
const newName = pascalify(basename(fullKebabPath))
const newNameWithoutExtension = '/' + basename(newName, '.js') + "'"
const filesWithReferences = await execAndParseList(`grep -r -l "${oldNameWithoutExtension}" ${dirs.join(' ')}`)
info(`${oldNameWithoutExtension} is referenced by:\n${filesWithReferences.join('\n')}`)
await moveFile(fullKebabPath, fullKebabPath.replace(oldNameWithoutExtension, newNameWithoutExtension))
for (const file of filesWithReferences) {
info(`replacing contents of ${file}`)
const buffer = await readFile(file)
const newFileContent = buffer
.toString()
.replace(new RegExp(oldNameWithoutExtension, 'm'), newNameWithoutExtension)
await writeFile(file, newFileContent)
}
}
}
function fromCamelToPascal(camel) {
return camel.replace(/^(.)/, (_, char) => char.toUpperCase())
}
function fromKebabToCamel(kebab) {
return kebab.replace(/\b-([a-z])/g, (_, char) => char.toUpperCase())
}
async function execAndParseList(cmd) {
const tmp = await exec(cmd).catch((_) => ({ stdout: '' }))
return tmp.stdout.split('\n').filter((e) => e)
}
main()
#!/usr/bin/env node
/*
* Rename kebab-case files into PascalCase files and update references
*
* Basic working:
* 1. Find all kebab case files
* 2. Rename them
* 3. Use the `git grep` to get all filenames with indexed hits of the old file name
* 4. Loop through the hits and update
*/
const { argv } = require('yargs')
const { isEmpty } = require('lodash')
const { promisify } = require('util')
const fs = require('fs')
const cp = require('child_process')
const { basename } = require('path')
const exec = promisify(cp.exec)
const readFile = promisify(fs.readFile)
const writeFile = promisify(fs.writeFile)
const moveFile = promisify(fs.rename)
const info = require('debug')('info')
const test = require('debug')('test')
const usage = `
USAGE: rename-pascals --dir src --dir test --dir some-other
Will rename all PascalCase to kebab-case and update references in the mentioned directories
`
let dirs = ''
if (isEmpty(argv.dir)) {
// eslint-disable-next-line no-console
console.error(usage)
process.exit(1)
}
if (!Array.isArray(argv.dir)) {
dirs = [argv.dir]
} else {
dirs = argv.dir
}
const excludeRegex = argv.exclude
async function main() {
const pascals = await execAndParseList(`find ${dirs.join(' ')} -regex '.*/[A-Z]\\w*\\.\\(test\\.\\)?js' -type f `)
const filesToRename = excludeRegex ? pascals.filter((f) => !f.match(excludeRegex)) : pascals
for (const fullPath of filesToRename) {
const oldNameWithoutExtension = basename(fullPath, '.js')
const tmp = basename(fullPath)
info(tmp)
const newNameWithoutExtension = fromPascalToKebab(basename(tmp, '.js'))
info(newNameWithoutExtension)
const oldRegExp = '/' + oldNameWithoutExtension
const newReplacement = '/' + newNameWithoutExtension
const filesWithReferences = await execAndParseList(`grep -r -l "${oldRegExp}" ${dirs.join(' ')}`)
info(`${oldNameWithoutExtension} is referenced by:\n${filesWithReferences.join('\n')}`)
info(`moveFile(${fullPath}, ${fullPath.replace(oldNameWithoutExtension, newNameWithoutExtension)}`)
await moveFile(fullPath, fullPath.replace(oldNameWithoutExtension, newNameWithoutExtension))
for (const file of filesWithReferences) {
info(`replacing contents of ${file}`)
const buffer = await readFile(file)
const newFileContent = buffer.toString().replace(new RegExp(oldRegExp, 'm'), newReplacement)
await writeFile(file, newFileContent)
}
}
}
async function execAndParseList(cmd) {
const tmp = await exec(cmd).catch((_) => ({ stdout: '' }))
return tmp.stdout.split('\n').filter((e) => e)
}
function fromPascalToKebab(pascal) {
const matches = pascal.match(/[A-Z][a-z]+/g)
if (!matches) {
return pascal
}
let first = true
let kebab = ''
for (const part of matches) {
if (first) {
first = false
kebab = part.toLowerCase()
continue
}
kebab += `-${part.toLowerCase()}`
}
if (pascal.match('\\.test')) {
kebab += '.test'
}
return kebab
}
test(fromPascalToKebab('App'))
test(fromPascalToKebab('MyApp'))
test(fromPascalToKebab('MyLargeApp'))
test(fromPascalToKebab('MyLargeApp'))
test(fromPascalToKebab('MyLargeApp.test'))
test(fromPascalToKebab('foo.test'))
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment