Skip to content

Instantly share code, notes, and snippets.

@imaman
Last active January 14, 2020 13:14
Show Gist options
  • Save imaman/e08029f26d599ef8a25f0bf02a1cc36a to your computer and use it in GitHub Desktop.
Save imaman/e08029f26d599ef8a25f0bf02a1cc36a to your computer and use it in GitHub Desktop.
kebab-case
const fs = require('fs')
const path = require('path')
const dirs = [
'src/misc',
'src/cimonorepo',
'src/fingerprinting',
'src/graphs',
'__tests__/unit-tests/misc',
'__tests__/unit-tests/cimonorepo',
'__tests__/unit-tests/fingerprinting',
'__tests__/unit-tests/graphs',
]
function replaceLast(s, searchFor, replaceWith) {
const index = s.lastIndexOf(searchFor)
if (index < 0) {
return s
}
const prefix = s.substring(0, index)
const suffix = s.substring(index).replace(searchFor, replaceWith)
return prefix + suffix
}
function scan(dir, baseDir, acc) {
const absDir = path.join(baseDir, dir)
fs.readdirSync(absDir).forEach(x => {
const relX = path.join(dir, x)
const absX = path.join(baseDir, relX)
const isDir = fs.lstatSync(absX).isDirectory()
if (isDir) {
scan(relX, baseDir, acc)
} else {
acc.push({ rel: relX, abs: absX })
}
})
}
function scanRoots(dirsToScan) {
const acc = []
dirsToScan.forEach(d => scan(d, __dirname, acc))
return acc
}
function isUpperCase(s, index = 0) {
const x = s[index]
if (x === '.') {
return false
}
return x.toUpperCase() === x
}
function renamer(input) {
const rel = input.rel
const filename = path.basename(rel)
if (!isUpperCase(filename, 0)) {
console.log(`renamer(${JSON.stringify(input)}) --> null`)
return null
}
const acc = []
for (let i = 0; i < filename.length; ++i) {
if (!isUpperCase(filename, i)) {
acc.push(filename[i])
continue
}
if (acc.length) {
acc.push('-')
}
acc.push(filename[i].toLowerCase())
}
const ret = acc.join('').replace('-a.', '.')
console.log(`renamer(${JSON.stringify(input)}) --> ${JSON.stringify(ret)}`)
return ret
}
const myFiles = scanRoots(dirs)
console.log('myfiles.length=' + myFiles.length)
const temp = myFiles.map(f => ({ rel: f.rel, abs: f.abs, renamed: renamer(f) }))
console.log('temp=' + JSON.stringify(temp))
const renamedFiles = temp.filter(x => Boolean(x.renamed))
console.log('renamedFiles.length=' + renamedFiles.length)
const allFiles = scanRoots(['src', '__tests__'])
function dropExtension(fileName) {
return fileName
.split('.')
.slice(0, -1)
.join('.')
}
function fixImport(contnet, abs, renamedFiles) {
const dirOfFile = path.dirname(abs)
const lines = contnet.split('\n')
let changed = false
for (let i = 0; i < lines.length; ++i) {
const line = lines[i]
if (!line.includes('import') || !line.includes('from')) {
continue
}
const candidates = []
for (let j = 0; j < renamedFiles.length; ++j) {
const rf = renamedFiles[j]
const fromHere = dropExtension(path.relative(dirOfFile, rf.abs))
if (line.includes(fromHere)) {
const dir = path.dirname(rf.abs)
const fullPathRenamed = path.join(dir, rf.renamed)
const replacement = dropExtension(path.relative(dirOfFile, fullPathRenamed))
candidates.push(s => replaceLast(s, fromHere, replacement))
}
}
if (!candidates.length) {
continue
}
if (candidates.length > 1) {
throw new Error(`More than one candidate for ${abs}: ${JSON.stringify(candidates)}`)
}
lines[i] = candidates[0](line)
changed = true
}
if (!changed) {
return ''
}
return lines.join('\n')
}
let numWritten = 0
allFiles.forEach(f => {
const content = fs.readFileSync(f.abs, 'utf-8')
const newContent = fixImport(content, f.abs, renamedFiles)
if (newContent) {
console.log(`updating ${f.abs}`)
fs.writeFileSync(f.abs, newContent, 'utf-8')
++numWritten
}
})
renamedFiles.forEach(curr => {
const from = curr.abs
const dir = path.dirname(from)
const to = path.join(dir, curr.renamed)
fs.renameSync(from, to)
console.log(`${from} -> ${to}`)
})
console.log('numWritten=', numWritten)
// console.log(JSON.stringify({myFiles, allFiles}, null, 2))
// console.log('renamed=' , JSON.stringify(renamedFiles, null, 2))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment