diff options
author | Samy Pessé <samypesse@gmail.com> | 2015-03-09 10:43:12 +0100 |
---|---|---|
committer | Samy Pessé <samypesse@gmail.com> | 2015-03-09 10:43:12 +0100 |
commit | 34fc2831e0cf0fed01c71cec28d93472d87f455b (patch) | |
tree | a803cc907c20491ba02863b5d3dd5aedf6bfed10 /lib/utils/fs.js | |
parent | e1594cde2c32e4ff48f6c4eff3d3d461743d74e1 (diff) | |
parent | 1bf68a5aa0703b5a1815cfe4ebb731b5fb6ed9d2 (diff) | |
download | gitbook-34fc2831e0cf0fed01c71cec28d93472d87f455b.zip gitbook-34fc2831e0cf0fed01c71cec28d93472d87f455b.tar.gz gitbook-34fc2831e0cf0fed01c71cec28d93472d87f455b.tar.bz2 |
Merge branch 'version/2.0'
Diffstat (limited to 'lib/utils/fs.js')
-rw-r--r-- | lib/utils/fs.js | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/lib/utils/fs.js b/lib/utils/fs.js new file mode 100644 index 0000000..98a3a87 --- /dev/null +++ b/lib/utils/fs.js @@ -0,0 +1,178 @@ +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 fsUtils = { + tmp: { + file: function(opt) { + return Q.nfcall(tmp.file.bind(tmp), opt).get(0) + }, + dir: function() { + return Q.nfcall(tmp.dir.bind(tmp)).get(0) + } + }, + list: listFiles, + stat: Q.denodeify(fs.stat), + readdir: Q.denodeify(fs.readdir), + readFile: Q.denodeify(fs.readFile), + writeFile: writeFile, + writeStream: writeStream, + mkdirp: Q.denodeify(fsExtra.mkdirp), + copy: Q.denodeify(fsExtra.copy), + remove: Q.denodeify(fsExtra.remove), + symlink: Q.denodeify(fsExtra.symlink), + exists: function(path) { + var d = Q.defer(); + fs.exists(path, d.resolve); + return d.promise; + }, + existsSync: fs.existsSync.bind(fs), + readFileSync: fs.readFileSync.bind(fs), + clean: cleanFolder, + getUniqueFilename: getUniqueFilename, +} + +// Write a file +function writeFile(filename, data, options) { + var d = Q.defer(); + + try { + fs.writeFileSync(filename, data, options) + } catch(err) { + d.reject(err); + } + d.resolve(); + + + return d.promise; +} + +// Write a stream to a file +function writeStream(filename, st) { + var d = Q.defer(); + + var wstream = fs.createWriteStream(filename); + + wstream.on('finish', function () { + d.resolve(); + }); + wstream.on('error', function (err) { + d.reject(err); + }); + + st.pipe(wstream); + + return d.promise; +} + +// Find a filename available +function getUniqueFilename(base, filename) { + if (!filename) { + filename = base; + base = "/"; + } + + filename = path.resolve(base, filename); + var ext = path.extname(filename); + filename = path.join(path.dirname(filename), path.basename(filename, ext)); + + var _filename = filename+ext; + + var i = 0; + while (1) { + if (!fs.existsSync(filename)) break; + _filename = filename+"_"+i+ext; + i = i + 1; + } + + return path.relative(base, _filename); +} + + +// 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+1, + 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; |