From 2813655e80ff4dcb837b30f67153a9b8483df5fb Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Mon, 26 Jul 2021 23:34:40 +0800 Subject: [PATCH] refactor: extract common logic for directory traversal --- directoryTraverse.js | 29 ++++++++++++++++++ emptyDir.js | 18 ------------ index.js | 70 +++++++++++++++++++++----------------------- 3 files changed, 63 insertions(+), 54 deletions(-) create mode 100644 directoryTraverse.js delete mode 100644 emptyDir.js diff --git a/directoryTraverse.js b/directoryTraverse.js new file mode 100644 index 00000000..645d43c8 --- /dev/null +++ b/directoryTraverse.js @@ -0,0 +1,29 @@ +import fs from 'fs'; +import path from 'path'; + +export function preOrderDirectoryTraverse(dir, dirCallback, fileCallback) { + for (const filename of fs.readdirSync(dir)) { + const fullpath = path.resolve(dir, filename); + if (fs.lstatSync(fullpath).isDirectory()) { + dirCallback(fullpath) + // in case the dirCallback removes the directory entirely + if (fs.existsSync(fullpath)) { + preOrderDirectoryTraverse(fullpath, dirCallback, fileCallback) + } + continue + } + fileCallback(fullpath); + } +} + +export function postOrderDirectoryTraverse(dir, dirCallback, fileCallback) { + for (const filename of fs.readdirSync(dir)) { + const fullpath = path.resolve(dir, filename) + if (fs.lstatSync(fullpath).isDirectory()) { + postOrderDirectoryTraverse(fullpath, dirCallback, fileCallback) + dirCallback(fullpath) + continue; + } + fileCallback(fullpath) + } +} diff --git a/emptyDir.js b/emptyDir.js deleted file mode 100644 index 204f66b3..00000000 --- a/emptyDir.js +++ /dev/null @@ -1,18 +0,0 @@ -import fs from 'fs' -import path from 'path' - -export default function emptyDir(dir) { - if (!fs.existsSync(dir)) { - return - } - for (const file of fs.readdirSync(dir)) { - const abs = path.resolve(dir, file) - // baseline is Node 12 so can't use rmSync :( - if (fs.lstatSync(abs).isDirectory()) { - emptyDir(abs) - fs.rmdirSync(abs) - } else { - fs.unlinkSync(abs) - } - } -} diff --git a/index.js b/index.js index dd0a5942..8bd47050 100755 --- a/index.js +++ b/index.js @@ -2,13 +2,17 @@ // @ts-check import fs from 'fs' +import path from 'path' + import minimist from 'minimist' import prompts from 'prompts' import { red, green, bold } from 'kolorist' -import emptyDir from './emptyDir.js' import renderTemplate from './renderTemplate.js' -import path from 'path' +import { + postOrderDirectoryTraverse, + preOrderDirectoryTraverse +} from './directoryTraverse.js' function isValidPackageName(projectName) { return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test( @@ -29,6 +33,14 @@ function canSafelyOverwrite(dir) { return !fs.existsSync(dir) || fs.readdirSync(dir).length === 0 } +function emptyDir (dir) { + postOrderDirectoryTraverse( + dir, + (dir) => fs.rmdirSync(dir), + (file) => fs.unlinkSync(file) + ) +} + async function init() { const cwd = process.cwd() const argv = minimist(process.argv.slice(2)) @@ -153,25 +165,17 @@ async function init() { // rename all `.js` files to `.ts` // rename jsconfig.json to tsconfig.json - function traverseAndRename(dir) { - for (const filename of fs.readdirSync(dir)) { - const fullpath = path.resolve(dir, filename) - if (fs.lstatSync(fullpath).isDirectory()) { - traverseAndRename(fullpath) - continue - } - - if (filename.endsWith('.js')) { - fs.renameSync(fullpath, fullpath.replace(/\.js$/, '.ts')) - } - - if (filename === 'jsconfig.json') { - fs.renameSync(fullpath, fullpath.replace(/jsconfig\.json$/, 'tsconfig.json')) + preOrderDirectoryTraverse( + root, + () => {}, + (filepath) => { + if (filepath.endsWith('.js')) { + fs.renameSync(filepath, filepath.replace(/\.js$/, '.ts')) + } else if (path.basename(filepath) === 'jsconfig.json') { + fs.renameSync(filepath, filepath.replace(/jsconfig\.json$/, 'tsconfig.json')) } } - } - - traverseAndRename(root) + ) } // Render code template. @@ -188,24 +192,18 @@ async function init() { // All templates assumes the need of tests. // If the user doesn't need it: // rm -rf cypress **/__tests__/ - function removeTestDirectories (dir) { - for (const filename of fs.readdirSync(dir)) { - const subdir = path.resolve(dir, filename) - const stats = fs.lstatSync(subdir) - - if (!stats.isDirectory()) { continue } - - if (filename === 'cypress' || filename === '__tests__') { - emptyDir(subdir) - fs.rmdirSync(subdir) - continue + preOrderDirectoryTraverse( + root, + (dirpath) => { + const dirname = path.basename(dirpath) + + if (dirname === 'cypress' || dirname === '__tests__') { + emptyDir(dirpath) + fs.rmdirSync(dirpath) } - - removeTestDirectories(subdir) - } - } - - removeTestDirectories(root) + }, + () => {} + ) } // Instructions: -- 2.39.5