From 22bae559db876600b3a417bd2070ee695f526edc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Mon, 26 Jan 2015 22:19:17 +0100 Subject: [PATCH] Fix #273: clean the output without removing .git and .svn --- lib/book.js | 12 +++-- lib/utils/fs.js | 136 +++++++++++++++++++++++++++++++----------------- 2 files changed, 97 insertions(+), 51 deletions(-) diff --git a/lib/book.js b/lib/book.js index 6a61753b0..481ca12a9 100644 --- a/lib/book.js +++ b/lib/book.js @@ -175,11 +175,15 @@ Book.prototype.generate = function(generator) { // Clean output folder .then(function() { - return fs.remove(that.options.output); + that.log.info("clean", that.options.generator, "generator"); + return fs.clean(that.options.output) + .progress(function(p) { + that.log.debug.ln("remove", p.file, "("+p.i+"/"+p.count+")"); + }) + .then(function() { + that.log.info.ok(); + }); }) - .then(function() { - return fs.mkdirp(that.options.output); - }) // Create generator .then(function() { diff --git a/lib/utils/fs.js b/lib/utils/fs.js index 352f57ae3..8d8c18998 100644 --- a/lib/utils/fs.js +++ b/lib/utils/fs.js @@ -1,56 +1,12 @@ var _ = require("lodash"); var Q = require("q"); var tmp = require("tmp"); +var path = require("path"); var fs = require("graceful-fs"); var fsExtra = require("fs-extra"); var Ignore = require("fstream-ignore"); -var listFiles = function(path, options) { - options = _.defaults(options || {}, { - ignoreFiles: [], - ignoreRules: [] - }); - - var d = Q.defer(); - - // Our list of files - var files = []; - - var ig = Ignore({ - path: path, - ignoreFiles: options.ignoreFiles - }); - - // Add extra rules to ignore common folders - ig.addIgnoreRules(options.ignoreRules, '__custom_stuff'); - - // Push each file to our list - ig.on('child', function (c) { - files.push( - c.path.substr(c.root.path.length + 1) + (c.props.Directory === true ? '/' : '') - ); - }); - - ig.on('end', function() { - // Normalize paths on Windows - if(process.platform === 'win32') { - return d.resolve(files.map(function(file) { - return file.replace(/\\/g, '/'); - })); - } - - // Simply return paths otherwise - return d.resolve(files); - }); - - ig.on('error', d.reject); - - return d.promise; -}; - - - -module.exports = { +var fsUtils = { tmp: { file: function() { return Q.nfcall(tmp.file.bind(tmp)).get(0) @@ -86,5 +42,91 @@ module.exports = { return d.promise; }, existsSync: fs.existsSync.bind(fs), - readFileSync: fs.readFileSync.bind(fs) + readFileSync: fs.readFileSync.bind(fs), + clean: cleanFolder +} + + +// List files in a directory +function listFiles(root, options) { + options = _.defaults(options || {}, { + ignoreFiles: [], + ignoreRules: [] + }); + + var d = Q.defer(); + + // Our list of files + var files = []; + + var ig = Ignore({ + path: root, + ignoreFiles: options.ignoreFiles + }); + + // Add extra rules to ignore common folders + ig.addIgnoreRules(options.ignoreRules, '__custom_stuff'); + + // Push each file to our list + ig.on('child', function (c) { + files.push( + c.path.substr(c.root.path.length + 1) + (c.props.Directory === true ? '/' : '') + ); + }); + + ig.on('end', function() { + // Normalize paths on Windows + if(process.platform === 'win32') { + return d.resolve(files.map(function(file) { + return file.replace(/\\/g, '/'); + })); + } + + // Simply return paths otherwise + return d.resolve(files); + }); + + ig.on('error', d.reject); + + return d.promise; +} + +// Clean a folder without removing .git and .svn +// Creates it if non existant +function cleanFolder(root) { + if (!fs.existsSync(root)) return fsUtils.mkdirp(root); + + return listFiles(root, { + ignoreFiles: [], + ignoreRules: [ + // Skip Git and SVN stuff + '.git/', + '.svn/' + ] + }) + .then(function(files) { + var d = Q.defer(); + + _.reduce(files, function(prev, file, i) { + return prev.then(function() { + var _file = path.join(root, file); + + d.notify({ + i: i, + count: files.length, + file: _file + }); + return fsUtils.remove(_file); + }); + }, Q()) + .then(function() { + d.resolve(); + }, function(err) { + d.reject(err); + }); + + return d.promise; + }); }; + +module.exports = fsUtils;