]> git.ipfire.org Git - thirdparty/vuejs/create-vue.git/commitdiff
refactor: extract common logic for directory traversal
authorHaoqun Jiang <haoqunjiang@gmail.com>
Mon, 26 Jul 2021 15:34:40 +0000 (23:34 +0800)
committerHaoqun Jiang <haoqunjiang@gmail.com>
Mon, 26 Jul 2021 15:34:40 +0000 (23:34 +0800)
directoryTraverse.js [new file with mode: 0644]
emptyDir.js [deleted file]
index.js

diff --git a/directoryTraverse.js b/directoryTraverse.js
new file mode 100644 (file)
index 0000000..645d43c
--- /dev/null
@@ -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 (file)
index 204f66b..0000000
+++ /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)
-    }
-  }
-}
index dd0a59429c91c3f0a3032c554f6cb9b5042c1caf..8bd4705010ee3056172d3d1a09b224fb5263746d 100755 (executable)
--- 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: