Skip to content

Instantly share code, notes, and snippets.

@JLChnToZ
Created October 12, 2017 18:01
Show Gist options
  • Select an option

  • Save JLChnToZ/fb11b86ba6150eb3c5a5a1e52c41ebe8 to your computer and use it in GitHub Desktop.

Select an option

Save JLChnToZ/fb11b86ba6150eb3c5a5a1e52c41ebe8 to your computer and use it in GitHub Desktop.
Simple Node.js script which simplify nested directory tree
'use strict';
const fs = require('fs');
const path = require('path');
let directories = process.argv.slice(2).map(resolveDir);
while(directories.length) {
const subDir = [];
for(const dir of directories) {
if(!ensureFolder(dir)) continue;
console.log('Scanning %s...', dir);
const files = fs.readdirSync(dir);
if(!files.length) {
console.log('Empty folder detected, trying to delete it...');
try {
fs.rmdirSync(dir);
} catch(e) {
console.error(e.message || e);
}
continue;
}
const dirs = files.map(resolveDir, dir).filter(ensureFolder);
if(dirs.length === 1 && files.length === 1) {
console.log('Found 1 subfolder inside, trying to flatten it.');
try {
const tempDir = path.resolve(dir, '__temp_' + Date.now()); // Prevent same name
fs.renameSync(dirs[0], tempDir);
fs.readdirSync(tempDir).forEach(moveFile, {
from: tempDir,
to: dir
});
fs.rmdirSync(tempDir);
subDir.push(dir); // Rescan it later
} catch(e) {
console.error(e.message || e);
}
continue;
}
if(dirs.length) {
console.log('Found %d subfolder(s) inside, which will be scanned later.', dirs.length);
Array.prototype.push.apply(subDir, dirs);
}
}
directories = subDir;
}
function resolveDir(cd) {
return cd && path.resolve(this || process.cwd, cd);
}
function ensureFolder(cd) {
return cd && fs.existsSync(cd) && fs.statSync(cd).isDirectory();
}
function moveFile(filePath) {
return fs.renameSync(path.resolve(this.from, filePath), path.resolve(this.to, filePath));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment