-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial checkin (implicitly tested with thoughtful-release)
- Loading branch information
Showing
3 changed files
with
135 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
/*! | ||
* promise-io <https://github.com/nknapp/promise-io> | ||
* | ||
* Copyright (c) 2016 Nils Knappmeier. | ||
* Released under the MIT license. | ||
*/ | ||
|
||
'use strict' | ||
|
||
var fs = require('fs') | ||
var Q = require('q') | ||
var path = require('path') | ||
|
||
module.exports = { | ||
/** | ||
* Custom implementation of [q-io/fs#listTree](http://documentup.com/kriskowal/q-io#listtreepath-guardpath-stat) | ||
* to avoid dependency on q-io | ||
* @param {string} directoryPath the base path | ||
* @param {function(string,fs.Stats):boolean} filter a function that returns true, false or null to show that a file | ||
* should be included or ignored and that a directory should be ignored completely (null) | ||
* @returns {Promise<string[]>} a promise for the collector, that is fulfilled after traversal | ||
*/ | ||
listTree: function listTree (directoryPath, filter) { | ||
return walk(directoryPath, filter, []) | ||
}, | ||
/** | ||
* Replacement for [q-io/fs#makeTree](http://documentup.com/kriskowal/q-io#maketreepath-mode) | ||
* @param {string} aPath the directory to be created | ||
* @param {number} mode (e.g. 0644) | ||
*/ | ||
makeTree: function makeTree (aPath, mode) { | ||
return Q.nfcall(require('mkdirp'), aPath, {mode: mode}) | ||
}, | ||
removeTree: function removeTree (aPath) { | ||
return Q.nfcall(require('rimraf'), aPath) | ||
}, | ||
/** | ||
* Replacement for [q-io/fs#read](http://documentup.com/kriskowal/q-io#readpath-options) | ||
* @param aPath | ||
*/ | ||
read: function read (aPath, options) { | ||
const flags = optionsFrom(options).flags | ||
return Q.ninvoke(fs, 'readFile', aPath, { | ||
encoding: flags === 'b' ? null : 'utf-8' | ||
}) | ||
}, | ||
|
||
write: function write (aPath, content) { | ||
return Q.ninvoke(fs, 'writeFile', aPath, content) | ||
}, | ||
|
||
copy: function copy (source, target) { | ||
var defer = Q.defer() | ||
fs.createReadStream(source) | ||
.on('error', defer.reject.bind(defer)) | ||
.pipe(fs.createWriteStream(target)) | ||
.on('error', defer.reject.bind(defer)) | ||
.on('finish', defer.fulfill.bind(defer)) | ||
|
||
return defer.promise | ||
}, | ||
|
||
stat: function stat (aPath) { | ||
return Q.ninvoke(fs, 'stat', aPath) | ||
} | ||
|
||
} | ||
|
||
/** | ||
* Coerce a flag-string `b` into an options-object `{ flags: 'ba' }` if necessary. | ||
* @param optionsOrFlags | ||
* @returns {*} | ||
*/ | ||
function optionsFrom (optionsOrFlags) { | ||
if (!optionsOrFlags) { | ||
return {} | ||
} | ||
if (optionsOrFlags instanceof String) { | ||
return { | ||
flags: optionsOrFlags | ||
} | ||
} | ||
return optionsOrFlags | ||
} | ||
|
||
/** | ||
* Walk a directory tree, collect paths of files in an Array and return a Promise for the fulfilled action | ||
* @param {string} directoryPath the base path | ||
* @param {function(string,fs.Stats):boolean} filter a function that returns true, false or null to show that a file | ||
* should be included or ignored and that a directory should be ignored completely (null) | ||
* @param {string[]} collector array to collect the filenames into | ||
* @returns {Promise<string[]>} a promise for the collector, that is fulfilled after traversal | ||
*/ | ||
function walk (directoryPath, filter, collector) { | ||
var defer = Q.defer() | ||
fs.stat(directoryPath, function (err, stat) { | ||
if (err) { | ||
return defer.reject(err) | ||
} | ||
var filterResult = filter(directoryPath, stat) | ||
if (filterResult) { | ||
collector.push(directoryPath) | ||
} | ||
if (stat.isDirectory()) { | ||
// false/true => iterate directory | ||
if (filterResult !== null) { | ||
fs.readdir(directoryPath, function (err, filenames) { | ||
if (err) { | ||
return defer.reject(err) | ||
} | ||
var paths = filenames.map(function (name) { | ||
return path.join(directoryPath, name) | ||
}) | ||
// Walk all files/subdirs | ||
Q.all(paths.map(function (filepath) { | ||
return walk(filepath, filter, collector) | ||
})) | ||
.then(function () { | ||
defer.fulfill(collector) | ||
}) | ||
}) | ||
} | ||
} else { | ||
// No recursive call with a file | ||
defer.fulfill(collector) | ||
} | ||
}) | ||
return defer.promise | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,4 +16,5 @@ var mIo = require('../') | |
|
||
describe('m-io:', function () { | ||
// body | ||
mIo | ||
}) |