Socket
Socket
Sign inDemoInstall

fs-jetpack

Package Overview
Dependencies
4
Maintainers
1
Versions
61
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.8.0 to 0.9.0

benchmark/utils.js

120

benchmark/copy.js

@@ -0,1 +1,3 @@

// Benchmark to make sure performance of copy is near 'native' bash command.
/* eslint no-console: 0 */

@@ -9,49 +11,87 @@

var promisedExec = Q.denodeify(childProcess.exec);
var benchUtils = require('./utils');
var jetpack = require('..');
var startTimer = function () {
var start = Date.now();
return function stop() {
return Date.now() - start;
};
};
var testDir = jetpack.dir(os.tmpdir() + '/jetpack-benchmark', { empty: true });
var toCopyDir = testDir.dir('to-copy');
for (var i = 0; i < 10000; i += 1) {
toCopyDir.file(i + '.txt', { content: 'text' });
toCopyDir.file(i + '.md', { content: 'markdown' });
}
var stop;
var timer;
var jetpackTime;
var jetpackFilteredTime;
var nativeTime;
stop = startTimer();
toCopyDir.copyAsync('.', testDir.path('copied-jetpack'))
.then(function () {
jetpackTime = stop();
console.log('Jetpack took ' + jetpackTime + 'ms');
stop = startTimer();
return toCopyDir.copyAsync('.', testDir.path('copied-filtered-jetpack'), {
matching: '*.txt'
var prepareFiles = function (testConfig) {
return new Q.Promise(function (resolve, reject) {
var count = 0;
var content = new Buffer(testConfig.size);
var makeOneFile = function () {
toCopyDir.fileAsync(count + '.txt', { content: content })
.then(function () {
count += 1;
if (count < testConfig.files) {
makeOneFile();
} else {
resolve();
}
}, reject);
};
console.log('Preparing ' + testConfig.files + ' test files (' +
benchUtils.humanFileSize(testConfig.size, true) + ' each)...');
makeOneFile();
});
})
.then(function () {
jetpackFilteredTime = stop();
console.log('Jetpack with *.txt filter took ' + jetpackFilteredTime + 'ms');
stop = startTimer();
return promisedExec('cp -R ' + toCopyDir.path() + ' ' + testDir.path('copied-native'));
})
.then(function () {
nativeTime = stop();
console.log('Native took ' + nativeTime + 'ms');
var times = jetpackTime / nativeTime;
console.log('Jetpack is ' + times.toFixed(1) + ' times slower than native');
testDir.remove('.');
})
.catch(function (err) {
console.log(err);
});
};
var waitAWhile = function () {
return new Q.Promise(function (resolve) {
console.log('Waiting 10s to allow hardware buffers be emptied...');
setTimeout(resolve, 10000);
});
};
var test = function (testConfig) {
console.log('----------------------');
return prepareFiles(testConfig)
.then(waitAWhile)
.then(function () {
timer = benchUtils.startTimer('jetpack.copyAsync()');
return toCopyDir.copyAsync('.', testDir.path('copied-jetpack'));
})
.then(function () {
jetpackTime = timer();
return waitAWhile();
})
.then(function () {
timer = benchUtils.startTimer('Native cp -R');
return promisedExec('cp -R ' + toCopyDir.path() + ' ' + testDir.path('copied-native'));
})
.then(function () {
nativeTime = timer();
console.log('Jetpack is ' + (jetpackTime / nativeTime).toFixed(1) +
' times slower than native');
console.log('Cleaning up after test...');
return testDir.removeAsync();
})
.catch(function (err) {
console.log(err);
});
};
var testConfigs = [{
files: 10000,
size: 100
}, {
files: 1000,
size: 1000 * 100
}, {
files: 100,
size: 1000 * 1000 * 10
}];
var runNext = function () {
if (testConfigs.length > 0) {
test(testConfigs.pop()).then(runNext);
}
};
runNext();

@@ -0,1 +1,6 @@

0.9.0 (2016-05-10)
-------------------
* **(breaking change)** `read()`, `list()`, `inspect()` and `inspectTree()` returns `undefined` instead of `null` if path doesn't exist.
* More sane edge cases for `dir()`, `file()` and `list()`.
0.8.0 (2016-04-09)

@@ -2,0 +7,0 @@ -------------------

@@ -10,14 +10,14 @@ 'use strict';

var matcher = require('./utils/matcher');
var mode = require('./utils/mode');
var inspector = require('./inspector');
var fileOps = require('./file_ops');
var fileMode = require('./utils/mode');
var inspectTree = require('./inspect_tree');
var write = require('./write');
var parseOptions = function (options, from) {
var opts = options || {};
var parsedOptions = {};
options = options || {};
parsedOptions.overwrite = options.overwrite;
parsedOptions.overwrite = opts.overwrite;
if (options.matching) {
parsedOptions.allowedToCopy = matcher.create(options.matching, from);
if (opts.matching) {
parsedOptions.allowedToCopy = matcher.create(opts.matching, from);
} else {

@@ -49,44 +49,59 @@ parsedOptions.allowedToCopy = function () {

var copySync = function (inspectData, to) {
var mod = mode.normalizeFileMode(inspectData.mode);
var checksBeforeCopyingSync = function (from, to, opts) {
if (!exists.sync(from)) {
throw generateNoSourceError(from);
}
if (exists.sync(to) && !opts.overwrite) {
throw generateDestinationExistsError(to);
}
};
var copyFileSync = function (from, to, mode) {
var data = fs.readFileSync(from);
write.sync(to, data, { mode: mode });
};
var copySymlinkSync = function (from, to) {
var symlinkPointsAt = fs.readlinkSync(from);
try {
fs.symlinkSync(symlinkPointsAt, to);
} catch (err) {
// There is already file/symlink with this name on destination location.
// Must erase it manually, otherwise system won't allow us to place symlink there.
if (err.code === 'EEXIST') {
fs.unlinkSync(to);
// Retry...
fs.symlinkSync(symlinkPointsAt, to);
} else {
throw err;
}
}
};
var copyItemSync = function (inspectData, to) {
var mode = fileMode.normalizeFileMode(inspectData.mode);
if (inspectData.type === 'dir') {
mkdirp.sync(to, { mode: mod });
mkdirp.sync(to, { mode: mode });
} else if (inspectData.type === 'file') {
var data = fs.readFileSync(inspectData.absolutePath);
fileOps.write(to, data, { mode: mod });
copyFileSync(inspectData.absolutePath, to, mode);
} else if (inspectData.type === 'symlink') {
var symlinkPointsAt = fs.readlinkSync(inspectData.absolutePath);
try {
fs.symlinkSync(symlinkPointsAt, to);
} catch (err) {
// There is already file/symlink with this name on destination location.
// Must erase it manually, otherwise system won't allow us to place symlink there.
if (err.code === 'EEXIST') {
fs.unlinkSync(to);
// Retry...
fs.symlinkSync(symlinkPointsAt, to);
} else {
throw err;
}
}
copySymlinkSync(inspectData.absolutePath, to);
}
};
var sync = function (from, to, options) {
options = parseOptions(options, from);
var copySync = function (from, to, options) {
var opts = parseOptions(options, from);
var walker;
var inspectData;
var destPath;
if (!exists.sync(from)) {
throw generateNoSourceError(from);
}
checksBeforeCopyingSync(from, to, opts);
if (exists.sync(to) && !options.overwrite) {
throw generateDestinationExistsError(to);
}
var walker = inspector.createTreeWalkerSync(from);
walker = inspectTree.createTreeWalkerSync(from);
while (walker.hasNext()) {
var inspectData = walker.getNext();
var destPath = pathUtil.join(to, inspectData.relativePath);
if (options.allowedToCopy(inspectData.absolutePath)) {
copySync(inspectData, destPath);
inspectData = walker.getNext();
destPath = pathUtil.join(to, inspectData.relativePath);
if (opts.allowedToCopy(inspectData.absolutePath)) {
copyItemSync(inspectData, destPath);
}

@@ -106,81 +121,102 @@ }

var copyAsync = function (inspectData, to) {
var mod = mode.normalizeFileMode(inspectData.mode);
var checksBeforeCopyingAsync = function (from, to, opts) {
return exists.async(from)
.then(function (srcPathExists) {
if (!srcPathExists) {
throw generateNoSourceError(from);
} else {
return exists.async(to);
}
})
.then(function (destPathExists) {
if (destPathExists && !opts.overwrite) {
throw generateDestinationExistsError(to);
}
});
};
var copyFileAsync = function (from, to, mode) {
return promisedReadFile(from)
.then(function (data) {
return write.async(to, data, { mode: mode });
});
};
var copySymlinkAsync = function (from, to) {
return promisedReadlink(from)
.then(function (symlinkPointsAt) {
var deferred = Q.defer();
promisedSymlink(symlinkPointsAt, to)
.then(deferred.resolve)
.catch(function (err) {
if (err.code === 'EEXIST') {
// There is already file/symlink with this name on destination location.
// Must erase it manually, otherwise system won't allow us to place symlink there.
promisedUnlink(to)
.then(function () {
// Retry...
return promisedSymlink(symlinkPointsAt, to);
})
.then(deferred.resolve, deferred.reject);
} else {
deferred.reject(err);
}
});
return deferred.promise;
});
};
var copyItemAsync = function (inspectData, to) {
var mode = fileMode.normalizeFileMode(inspectData.mode);
if (inspectData.type === 'dir') {
return promisedMkdirp(to, { mode: mod });
return promisedMkdirp(to, { mode: mode });
} else if (inspectData.type === 'file') {
return promisedReadFile(inspectData.absolutePath)
.then(function (data) {
return fileOps.writeAsync(to, data, { mode: mod });
});
return copyFileAsync(inspectData.absolutePath, to, mode);
} else if (inspectData.type === 'symlink') {
return promisedReadlink(inspectData.absolutePath)
.then(function (symlinkPointsAt) {
var deferred = Q.defer();
promisedSymlink(symlinkPointsAt, to)
.then(deferred.resolve)
.catch(function (err) {
if (err.code === 'EEXIST') {
// There is already file/symlink with this name on destination location.
// Must erase it manually, otherwise system won't allow us to place symlink there.
promisedUnlink(to)
.then(function () {
// Retry...
return promisedSymlink(symlinkPointsAt, to);
})
.then(deferred.resolve, deferred.reject);
} else {
deferred.reject(err);
}
});
return deferred.promise;
});
return copySymlinkAsync(inspectData.absolutePath, to);
}
// Ha! This is none of supported file system entities. What now?
// Just continuing without actually copying sounds sane.
return new Q();
};
var async = function (from, to, options) {
var runCopyLoop = function (from, to, opts) {
var deferred = Q.defer();
var inspectData;
var destPath;
var startCopying = function () {
var copyNext = function (walker) {
if (walker.hasNext()) {
var inspectData = walker.getNext();
var destPath = pathUtil.join(to, inspectData.relativePath);
if (options.allowedToCopy(inspectData.absolutePath)) {
copyAsync(inspectData, destPath)
.then(function () {
copyNext(walker);
})
.catch(deferred.reject);
} else {
var copyNext = function (walker) {
if (walker.hasNext()) {
inspectData = walker.getNext();
destPath = pathUtil.join(to, inspectData.relativePath);
if (opts.allowedToCopy(inspectData.absolutePath)) {
copyItemAsync(inspectData, destPath)
.then(function () {
copyNext(walker);
}
})
.catch(deferred.reject);
} else {
deferred.resolve();
copyNext(walker);
}
};
inspector.createTreeWalkerAsync(from).then(copyNext);
} else {
deferred.resolve();
}
};
options = parseOptions(options, from);
inspectTree.createTreeWalkerAsync(from).then(copyNext);
// Checks before copying
exists.async(from)
.then(function (srcPathExists) {
if (!srcPathExists) {
throw generateNoSourceError(from);
} else {
return exists.async(to);
}
return deferred.promise;
};
var copyAsync = function (from, to, options) {
var deferred = Q.defer();
var opts = parseOptions(options, from);
checksBeforeCopyingAsync(from, to, opts)
.then(function () {
return runCopyLoop(from, to, opts);
})
.then(function (destPathExists) {
if (destPathExists && !options.overwrite) {
throw generateDestinationExistsError(to);
} else {
startCopying();
}
})
.then(deferred.resolve)
.catch(deferred.reject);

@@ -195,3 +231,3 @@

module.exports.sync = sync;
module.exports.async = async;
exports.sync = copySync;
exports.async = copyAsync;

@@ -11,6 +11,4 @@ 'use strict';

function getCriteriaDefaults(criteria) {
if (criteria === undefined) {
criteria = {};
}
var getCriteriaDefaults = function (passedCriteria) {
var criteria = passedCriteria || {};
if (typeof criteria.empty !== 'boolean') {

@@ -23,4 +21,9 @@ criteria.empty = false;

return criteria;
}
};
var generatePathOccupiedByNotDirectoryError = function (path) {
return new Error('Path ' + path + ' exists but is not a directory.' +
' Halting jetpack.dir() call for safety reasons.');
};
// ---------------------------------------------------------

@@ -30,7 +33,7 @@ // Sync

var sync = function (path, criteria) {
criteria = getCriteriaDefaults(criteria);
var checkWhatAlreadyOccupiesPathSync = function (path) {
var stat;
try {
var stat = fs.statSync(path);
stat = fs.statSync(path);
} catch (err) {

@@ -43,14 +46,26 @@ // Detection if path already exists

if (stat && stat.isFile()) {
// This is file, but should be directory.
fs.unlinkSync(path);
// Clear stat variable to indicate now nothing is there
stat = undefined;
if (stat && !stat.isDirectory()) {
throw generatePathOccupiedByNotDirectoryError(path);
}
if (stat) {
// Ensure existing directory matches criteria
return stat;
};
var createBrandNewDirectorySync = function (path, criteria) {
mkdirp.sync(path, { mode: criteria.mode });
};
var checkExistingDirectoryFulfillsCriteriaSync = function (path, stat, criteria) {
var checkMode = function () {
var mode = modeUtil.normalizeFileMode(stat.mode);
if (criteria.mode !== undefined && criteria.mode !== mode) {
fs.chmodSync(path, criteria.mode);
}
};
var checkEmptiness = function () {
var list;
if (criteria.empty) {
// Delete everything inside this directory
var list = fs.readdirSync(path);
list = fs.readdirSync(path);
list.forEach(function (filename) {

@@ -60,11 +75,15 @@ rimraf.sync(pathUtil.resolve(path, filename));

}
};
var mode = modeUtil.normalizeFileMode(stat.mode);
if (criteria.mode !== undefined && criteria.mode !== mode) {
// Mode is different than specified in criteria, fix that.
fs.chmodSync(path, criteria.mode);
}
checkMode();
checkEmptiness();
};
var dirSync = function (path, passedCriteria) {
var criteria = getCriteriaDefaults(passedCriteria);
var stat = checkWhatAlreadyOccupiesPathSync(path);
if (stat) {
checkExistingDirectoryFulfillsCriteriaSync(path, stat, criteria);
} else {
// Directory doesn't exist now. Create it.
mkdirp.sync(path, { mode: criteria.mode });
createBrandNewDirectorySync(path, criteria);
}

@@ -83,4 +102,28 @@ };

var checkWhatAlreadyOccupiesPathAsync = function (path) {
var deferred = Q.defer();
promisedStat(path)
.then(function (stat) {
if (stat.isDirectory()) {
deferred.resolve(stat);
} else {
deferred.reject(generatePathOccupiedByNotDirectoryError(path));
}
})
.catch(function (err) {
if (err.code === 'ENOENT') {
// Path doesn't exist
deferred.resolve(undefined);
} else {
// This is other error that nonexistent path, so end here.
deferred.reject(err);
}
});
return deferred.promise;
};
// Delete all files and directores inside given directory
var empty = function (path) {
var emptyAsync = function (path) {
var deferred = Q.defer();

@@ -91,6 +134,7 @@

var doOne = function (index) {
var subPath;
if (index === list.length) {
deferred.resolve();
} else {
var subPath = pathUtil.resolve(path, list[index]);
subPath = pathUtil.resolve(path, list[index]);
promisedRimraf(subPath).then(function () {

@@ -109,85 +153,42 @@ doOne(index + 1);

var async = function (path, criteria) {
var checkExistingDirectoryFulfillsCriteriaAsync = function (path, stat, criteria) {
var deferred = Q.defer();
criteria = getCriteriaDefaults(criteria);
var checkMode = function () {
var mode = modeUtil.normalizeFileMode(stat.mode);
if (criteria.mode !== undefined && criteria.mode !== mode) {
return promisedChmod(path, criteria.mode);
}
return new Q();
};
var checkWhatWeHaveNow = function () {
var checkDeferred = Q.defer();
promisedStat(path)
.then(function (stat) {
if (stat.isFile()) {
// This is not a directory, and should be.
promisedRimraf(path)
.then(function () {
// We just deleted that path, so can't
// pass stat further down.
checkDeferred.resolve(undefined);
})
.catch(checkDeferred.reject);
} else {
checkDeferred.resolve(stat);
}
})
.catch(function (err) {
if (err.code === 'ENOENT') {
// Path doesn't exist
checkDeferred.resolve(undefined);
} else {
// This is other error that nonexistent path, so end here.
checkDeferred.reject(err);
}
});
return checkDeferred.promise;
var checkEmptiness = function () {
if (criteria.empty) {
return emptyAsync(path);
}
return new Q();
};
var checkWhatShouldBe = function (stat) {
var checkDeferred = Q.defer();
checkMode()
.then(checkEmptiness)
.then(deferred.resolve, deferred.reject);
var needToCheckMoreCriteria = function () {
var checkEmptiness = function () {
if (criteria.empty) {
// Delete everything inside this directory
empty(path)
.then(checkDeferred.resolve, checkDeferred.reject);
} else {
// Everything done!
checkDeferred.resolve();
}
};
return deferred.promise;
};
var checkMode = function () {
var mode = modeUtil.normalizeFileMode(stat.mode);
if (criteria.mode !== undefined && criteria.mode !== mode) {
// Mode is different than specified in criteria, fix that
promisedChmod(path, criteria.mode)
.then(checkEmptiness, checkDeferred.reject);
} else {
checkEmptiness();
}
};
var createBrandNewDirectoryAsync = function (path, criteria) {
return promisedMkdirp(path, { mode: criteria.mode });
};
checkMode();
};
var dirAsync = function (path, passedCriteria) {
var deferred = Q.defer();
var criteria = getCriteriaDefaults(passedCriteria);
var checkExistence = function () {
if (!stat) {
promisedMkdirp(path, { mode: criteria.mode })
.then(checkDeferred.resolve, checkDeferred.reject);
} else {
// Directory exists, but we still don't
// know if it matches all criteria.
needToCheckMoreCriteria();
}
};
checkExistence();
return checkDeferred.promise;
};
checkWhatWeHaveNow()
.then(checkWhatShouldBe)
checkWhatAlreadyOccupiesPathAsync(path)
.then(function (stat) {
if (stat !== undefined) {
return checkExistingDirectoryFulfillsCriteriaAsync(path, stat, criteria);
}
return createBrandNewDirectoryAsync(path, criteria);
})
.then(deferred.resolve, deferred.reject);

@@ -202,3 +203,3 @@

module.exports.sync = sync;
module.exports.async = async;
module.exports.sync = dirSync;
module.exports.async = dirAsync;

@@ -10,5 +10,6 @@ 'use strict';

var sync = function (path) {
var existsSync = function (path) {
var stat;
try {
var stat = fs.statSync(path);
stat = fs.statSync(path);
if (stat.isDirectory()) {

@@ -33,3 +34,3 @@ return 'dir';

var async = function (path) {
var existsAsync = function (path) {
var deferred = Q.defer();

@@ -60,3 +61,3 @@

module.exports.sync = sync;
module.exports.async = async;
exports.sync = existsSync;
exports.async = existsAsync;

@@ -5,17 +5,19 @@ 'use strict';

var Q = require('q');
var rimraf = require('rimraf');
var modeUtils = require('./utils/mode');
var fileOps = require('./file_ops');
var modeUtil = require('./utils/mode');
var write = require('./write');
function getCriteriaDefaults(criteria) {
if (criteria === undefined) {
criteria = {};
}
var getCriteriaDefaults = function (passedCriteria) {
var criteria = passedCriteria || {};
if (criteria.mode !== undefined) {
criteria.mode = modeUtils.normalizeFileMode(criteria.mode);
criteria.mode = modeUtil.normalizeFileMode(criteria.mode);
}
return criteria;
}
};
var generatePathOccupiedByNotFileError = function (path) {
return new Error('Path ' + path + ' exists but is not a file.' +
' Halting jetpack.file() call for safety reasons.');
};
// ---------------------------------------------------------

@@ -25,7 +27,7 @@ // Sync

var sync = function (path, criteria) {
criteria = getCriteriaDefaults(criteria);
var checkWhatAlreadyOccupiesPathSync = function (path) {
var stat;
try {
var stat = fs.statSync(path);
stat = fs.statSync(path);
} catch (err) {

@@ -39,35 +41,55 @@ // Detection if path exists

if (stat && !stat.isFile()) {
// This have to be file, so if is directory must be removed.
rimraf.sync(path);
// Clear stat variable to indicate now nothing is there.
stat = undefined;
throw generatePathOccupiedByNotFileError(path);
}
if (stat) {
// Ensure file mode
var mode = modeUtils.normalizeFileMode(stat.mode);
if (criteria.mode !== undefined && criteria.mode !== mode) {
fs.chmodSync(path, criteria.mode);
}
return stat;
};
// Ensure file content
var checkExistingFileFulfillsCriteriaSync = function (path, stat, criteria) {
var mode = modeUtil.normalizeFileMode(stat.mode);
var checkContent = function () {
if (criteria.content !== undefined) {
fileOps.write(path, criteria.content, {
write.sync(path, criteria.content, {
mode: mode,
jsonIndent: criteria.jsonIndent
});
return true;
}
} else {
// File doesn't exist. Create it.
var content = '';
if (criteria.content !== undefined) {
content = criteria.content;
return false;
};
var checkMode = function () {
if (criteria.mode !== undefined && criteria.mode !== mode) {
fs.chmodSync(path, criteria.mode);
}
fileOps.write(path, content, {
mode: criteria.mode,
jsonIndent: criteria.jsonIndent
});
};
var contentReplaced = checkContent();
if (!contentReplaced) {
checkMode();
}
};
var createBrandNewFileSync = function (path, criteria) {
var content = '';
if (criteria.content !== undefined) {
content = criteria.content;
}
write.sync(path, content, {
mode: criteria.mode,
jsonIndent: criteria.jsonIndent
});
};
var fileSync = function (path, passedCriteria) {
var criteria = getCriteriaDefaults(passedCriteria);
var stat = checkWhatAlreadyOccupiesPathSync(path);
if (stat !== undefined) {
checkExistingFileFulfillsCriteriaSync(path, stat, criteria);
} else {
createBrandNewFileSync(path, criteria);
}
};
// ---------------------------------------------------------

@@ -79,87 +101,88 @@ // Async

var promisedChmod = Q.denodeify(fs.chmod);
var promisedRimraf = Q.denodeify(rimraf);
var async = function (path, criteria) {
var checkWhatAlreadyOccupiesPathAsync = function (path) {
var deferred = Q.defer();
criteria = getCriteriaDefaults(criteria);
promisedStat(path)
.then(function (stat) {
if (stat.isFile()) {
deferred.resolve(stat);
} else {
deferred.reject(generatePathOccupiedByNotFileError(path));
}
})
.catch(function (err) {
if (err.code === 'ENOENT') {
// Path doesn't exist.
deferred.resolve(undefined);
} else {
// This is other error. Must end here.
deferred.reject(err);
}
});
var checkWhatWeHaveNow = function () {
var checkDeferred = Q.defer();
return deferred.promise;
};
promisedStat(path)
.then(function (stat) {
if (stat.isDirectory()) {
// This is not a file, so remove it.
promisedRimraf(path)
.then(function () {
// Clear stat variable to indicate now nothing is there
checkDeferred.resolve(undefined);
})
.catch(checkDeferred.reject);
} else {
checkDeferred.resolve(stat);
}
})
.catch(function (err) {
if (err.code === 'ENOENT') {
// Path doesn't exist.
checkDeferred.resolve(undefined);
} else {
// This is other error. Must end here.
checkDeferred.reject(err);
}
});
var checkExistingFileFulfillsCriteriaAsync = function (path, stat, criteria) {
var mode = modeUtil.normalizeFileMode(stat.mode);
return checkDeferred.promise;
};
var checkContent = function () {
var deferred = Q.defer();
var checkWhatShouldBe = function (stat) {
var checkDeferred = Q.defer();
if (!stat) {
// Path doesn't exist now. Put file there.
var content = '';
if (criteria.content !== undefined) {
content = criteria.content;
}
fileOps.writeAsync(path, content, {
mode: criteria.mode,
if (criteria.content !== undefined) {
write.async(path, criteria.content, {
mode: mode,
jsonIndent: criteria.jsonIndent
})
.then(checkDeferred.resolve, checkDeferred.reject);
.then(function () {
deferred.resolve(true);
})
.catch(deferred.reject);
} else {
// File already exists. Must do more checking.
deferred.resolve(false);
}
var mode = modeUtils.normalizeFileMode(stat.mode);
return deferred.promise;
};
var checkMode = function () {
if (criteria.mode !== undefined && criteria.mode !== mode) {
promisedChmod(path, criteria.mode)
.then(checkDeferred.resolve, checkDeferred.reject);
} else {
checkDeferred.resolve();
}
};
var checkMode = function () {
if (criteria.mode !== undefined && criteria.mode !== mode) {
return promisedChmod(path, criteria.mode);
}
return undefined;
};
var checkContent = function () {
if (criteria.content !== undefined) {
fileOps.writeAsync(path, criteria.content, {
mode: mode,
jsonIndent: criteria.jsonIndent
})
.then(checkDeferred.resolve, checkDeferred.reject);
} else {
checkMode();
}
};
checkContent();
return checkContent()
.then(function (contentReplaced) {
if (!contentReplaced) {
return checkMode();
}
return undefined;
});
};
return checkDeferred.promise;
};
var createBrandNewFileAsync = function (path, criteria) {
var content = '';
if (criteria.content !== undefined) {
content = criteria.content;
}
checkWhatWeHaveNow()
.then(checkWhatShouldBe)
return write.async(path, content, {
mode: criteria.mode,
jsonIndent: criteria.jsonIndent
});
};
var fileAsync = function (path, passedCriteria) {
var deferred = Q.defer();
var criteria = getCriteriaDefaults(passedCriteria);
checkWhatAlreadyOccupiesPathAsync(path)
.then(function (stat) {
if (stat !== undefined) {
return checkExistingFileFulfillsCriteriaAsync(path, stat, criteria);
}
return createBrandNewFileAsync(path, criteria);
})
.then(deferred.resolve, deferred.reject);

@@ -174,3 +197,3 @@

module.exports.sync = sync;
module.exports.async = async;
exports.sync = fileSync;
exports.async = fileAsync;

@@ -5,3 +5,3 @@ 'use strict';

var Q = require('q');
var inspector = require('./inspector');
var inspectTree = require('./inspect_tree');
var matcher = require('./utils/matcher');

@@ -24,3 +24,3 @@

return inspector.utils.flattenTree(tree)
return inspectTree.utils.flattenTree(tree)
.filter(function (inspectObj) {

@@ -62,11 +62,11 @@ return matchesAnyOfGlobs(inspectObj.absolutePath);

var sync = function (path, options) {
var findSync = function (path, options) {
var foundInspectObjects;
var tree;
tree = inspector.tree(path, {
tree = inspectTree.sync(path, {
absolutePath: true
});
if (tree === null) {
if (tree === undefined) {
throw generatePathDoesntExistError(path);

@@ -85,6 +85,6 @@ } else if (tree.type !== 'dir') {

var async = function (path, options) {
var findAsync = function (path, options) {
var deferred = Q.defer();
inspector.treeAsync(path, {
inspectTree.async(path, {
relativePath: true,

@@ -97,3 +97,3 @@ absolutePath: true

if (tree === null) {
if (tree === undefined) {
throw generatePathDoesntExistError(path);

@@ -117,3 +117,3 @@ } else if (tree.type !== 'dir') {

module.exports.sync = sync;
module.exports.async = async;
exports.sync = findSync;
exports.async = findAsync;

@@ -8,13 +8,17 @@ /* eslint no-param-reassign:0 */

var fileOps = require('./file_ops');
var inspector = require('./inspector');
var append = require('./append');
var dir = require('./dir');
var file = require('./file');
var find = require('./find');
var inspect = require('./inspect');
var inspectTree = require('./inspect_tree');
var copy = require('./copy');
var exists = require('./exists');
var list = require('./list');
var move = require('./move');
var read = require('./read');
var remove = require('./remove');
var symlink = require('./symlink');
var streams = require('./streams');
var write = require('./write');

@@ -68,6 +72,6 @@ // The Jetpack Context object.

append: function (path, data, options) {
fileOps.append(resolvePath(path), data, options);
append.sync(resolvePath(path), data, options);
},
appendAsync: function (path, data, options) {
return fileOps.appendAsync(resolvePath(path), data, options);
return append.async(resolvePath(path), data, options);
},

@@ -147,20 +151,20 @@

inspect: function (path, fieldsToInclude) {
return inspector.inspect(resolvePath(path), fieldsToInclude);
return inspect.sync(resolvePath(path), fieldsToInclude);
},
inspectAsync: function (path, fieldsToInclude) {
return inspector.inspectAsync(resolvePath(path), fieldsToInclude);
return inspect.async(resolvePath(path), fieldsToInclude);
},
inspectTree: function (path, options) {
return inspector.tree(resolvePath(path), options);
return inspectTree.sync(resolvePath(path), options);
},
inspectTreeAsync: function (path, options) {
return inspector.treeAsync(resolvePath(path), options);
return inspectTree.async(resolvePath(path), options);
},
list: function (path) {
return inspector.list(resolvePath(path || '.'));
return list.sync(resolvePath(path || '.'));
},
listAsync: function (path) {
return inspector.listAsync(resolvePath(path || '.'));
return list.async(resolvePath(path || '.'));
},

@@ -176,6 +180,6 @@

read: function (path, returnAs) {
return fileOps.read(resolvePath(path), returnAs);
return read.sync(resolvePath(path), returnAs);
},
readAsync: function (path, returnAs) {
return fileOps.readAsync(resolvePath(path), returnAs);
return read.async(resolvePath(path), returnAs);
},

@@ -211,6 +215,6 @@

write: function (path, data, options) {
fileOps.write(resolvePath(path), data, options);
write.sync(resolvePath(path), data, options);
},
writeAsync: function (path, data, options) {
return fileOps.writeAsync(resolvePath(path), data, options);
return write.async(resolvePath(path), data, options);
}

@@ -217,0 +221,0 @@ };

@@ -19,3 +19,3 @@ 'use strict';

var sync = function (from, to) {
var moveSync = function (from, to) {
try {

@@ -34,4 +34,4 @@ fs.renameSync(from, to);

if (!exists.sync(to)) {
var destDir = pathUtil.dirname(to);
mkdirp.sync(destDir);
// Some parent directory doesn't exist. Create it.
mkdirp.sync(pathUtil.dirname(to));
// Retry the attempt

@@ -70,3 +70,3 @@ fs.renameSync(from, to);

var async = function (from, to) {
var moveAsync = function (from, to) {
var deferred = Q.defer();

@@ -107,3 +107,3 @@

module.exports.sync = sync;
module.exports.async = async;
exports.sync = moveSync;
exports.async = moveAsync;

@@ -10,3 +10,3 @@ 'use strict';

var sync = function (path) {
var removeSync = function (path) {
rimraf.sync(path);

@@ -21,3 +21,3 @@ };

var async = function (path) {
var removeAsync = function (path) {
return qRimraf(path);

@@ -30,3 +30,3 @@ };

module.exports.sync = sync;
module.exports.async = async;
exports.sync = removeSync;
exports.async = removeAsync;

@@ -5,3 +5,3 @@ 'use strict';

module.exports.createWriteStream = fs.createWriteStream;
module.exports.createReadStream = fs.createReadStream;
exports.createWriteStream = fs.createWriteStream;
exports.createReadStream = fs.createReadStream;

@@ -12,3 +12,3 @@ 'use strict';

var sync = function (symlinkValue, path) {
var symlinkSync = function (symlinkValue, path) {
try {

@@ -34,3 +34,3 @@ fs.symlinkSync(symlinkValue, path);

var async = function (symlinkValue, path) {
var symlinkAsync = function (symlinkValue, path) {
var deferred = Q.defer();

@@ -60,3 +60,3 @@

module.exports.sync = sync;
module.exports.async = async;
exports.sync = symlinkSync;
exports.async = symlinkAsync;

@@ -7,40 +7,57 @@ // Matcher for glob patterns (e.g. *.txt, /a/b/**/z)

var create = function (patterns, basePath) {
if (typeof patterns === 'string') {
patterns = [patterns];
}
var convertPatternToAbsolutePath = function (passedPattern, basePath) {
// All patterns without slash are left as they are, if pattern contain
// any slash we need to turn it into absolute path.
var pattern = passedPattern;
var hasSlash = (pattern.indexOf('/') !== -1);
var isAbsolute;
var isNegated;
// Convert patterns to absolute paths
patterns = patterns.map(function (pattern) {
var hasSlash = (pattern.indexOf('/') !== -1);
// All patterns without slash are left as they are
if (hasSlash) {
// Maybe already is in the format we wanted
var isAbsolute = /^!?\//.test(pattern); // Starts with '/' or '!/'
if (!isAbsolute) {
var isNegated = (pattern[0] === '!');
if (hasSlash) {
// Maybe already is in the format we wanted
isAbsolute = /^!?\//.test(pattern); // Starts with '/' or '!/'
if (!isAbsolute) {
isNegated = (pattern[0] === '!');
// Remove starting characters which have meaning '!' and '.'
// and first slash to normalize the path.
if (isNegated) {
pattern = pattern.substring(1);
}
if (pattern[0] === '.') {
pattern = pattern.substring(1);
}
if (pattern[0] === '/') {
pattern = pattern.substring(1);
}
// Remove starting characters which have meaning '!' and '.'
// and first slash to normalize the path.
if (isNegated) {
pattern = pattern.substring(1);
}
if (pattern[0] === '.') {
pattern = pattern.substring(1);
}
if (pattern[0] === '/') {
pattern = pattern.substring(1);
}
// Finally construct ready pattern
if (isNegated) {
pattern = '!' + basePath + '/' + pattern;
} else {
pattern = basePath + '/' + pattern;
}
// Finally construct ready pattern
if (isNegated) {
pattern = '!' + basePath + '/' + pattern;
} else {
pattern = basePath + '/' + pattern;
}
}
return pattern;
}
return pattern;
};
var normalizePatterns = function (passedPatterns, basePath) {
var patterns;
if (typeof passedPatterns === 'string') {
// Patterns must be an Array
patterns = [passedPatterns];
} else {
patterns = passedPatterns;
}
return patterns.map(function (pattern) {
return convertPatternToAbsolutePath(pattern, basePath);
});
};
exports.create = function (passedPatterns, basePath) {
var patterns = normalizePatterns(passedPatterns, basePath);
var matchers = patterns.map(function (pattern) {

@@ -54,10 +71,12 @@ return new Minimatch(pattern, {

var doMatch = function (path) {
return function performMatch(path) {
var mode = 'matching';
var weHaveMatch = false;
var currentMatcher;
var i;
for (var i = 0; i < matchers.length; i += 1) {
var ma = matchers[i];
for (i = 0; i < matchers.length; i += 1) {
currentMatcher = matchers[i];
if (ma.negate) {
if (currentMatcher.negate) {
mode = 'negation';

@@ -72,3 +91,3 @@ if (i === 0) {

if (mode === 'negation' && weHaveMatch && !ma.match(path)) {
if (mode === 'negation' && weHaveMatch && !currentMatcher.match(path)) {
// One negation match is enought to know we can reject this one.

@@ -79,3 +98,3 @@ return false;

if (mode === 'matching' && !weHaveMatch) {
weHaveMatch = ma.match(path);
weHaveMatch = currentMatcher.match(path);
}

@@ -86,6 +105,2 @@ }

};
return doMatch;
};
module.exports.create = create;

@@ -6,7 +6,10 @@ // Logic for unix file mode operations.

// Converts mode to string 3 characters long.
module.exports.normalizeFileMode = function (rawMode) {
if (typeof rawMode === 'number') {
rawMode = rawMode.toString(8);
exports.normalizeFileMode = function (mode) {
var modeAsString;
if (typeof mode === 'number') {
modeAsString = mode.toString(8);
} else {
modeAsString = mode;
}
return rawMode.substring(rawMode.length - 3);
return modeAsString.substring(modeAsString.length - 3);
};
{
"name": "fs-jetpack",
"description": "Better file system API",
"version": "0.8.0",
"version": "0.9.0",
"author": "Jakub Szwacz <jakub@szwacz.com>",

@@ -6,0 +6,0 @@ "dependencies": {

fs-jetpack [![Build Status](https://travis-ci.org/szwacz/fs-jetpack.svg?branch=master)](https://travis-ci.org/szwacz/fs-jetpack) [![Build status](https://ci.appveyor.com/api/projects/status/er206e91fpuuqf58?svg=true)](https://ci.appveyor.com/project/szwacz/fs-jetpack)
==========
Node's [fs library](http://nodejs.org/api/fs.html) is very low level and because of that often painful to use. *fs-jetpack* wants to fix that by giving you completely rethought, much more conveninet API to work with file system.
Node's [fs library](http://nodejs.org/api/fs.html) is very low level and because of that often painful to use. *fs-jetpack* wants to fix that by giving you completely rethought, much more convenient API to work with file system.

@@ -32,3 +32,3 @@ #### [Jump to API Docs](#api)

// Want to make that call asnychronous? Just add the word "Async"
// Want to make that call asynchronous? Just add the word "Async"
// and it will give you promise instead of ready value.

@@ -62,7 +62,6 @@ jetpack.readAsync('file.txt')

Everyone who did something with files for sure seen (and probably hates) *"ENOENT, no such file or directory"* error. Jetpack tries to recover from that error if possible.
1. For wrte/creation operations, if any of parent directories doesn't exist jetpack will just create them as well.
2. For read/inspect operations, if file or directory doesn't exist `null` is returned instead of throwing.
1. For write/creation operations, if any of parent directories doesn't exist jetpack will just create lacking directories.
2. For read/inspect operations, if file or directory doesn't exist `undefined` is returned instead of throwing.
## Jetpack can do more in less code (examples)
All methods play nicely with each other. Here are few examples what it gives you.
## All methods play nicely with each other (examples)
**Note:** All examples are synchronous. Unfortunately asynchronous equivalents won't be that pretty.

@@ -137,24 +136,23 @@

**Methods:**
* [append](#append)
* [copy](#copy)
* [createReadStream](#create-read-stream)
* [createWriteStream](#create-write-stream)
* [cwd](#cwd)
* [dir](#dir)
* [exists](#exists)
* [file](#file)
* [find](#find)
* [inspect](#inspect)
* [inspectTree](#inspect-tree)
* [list](#list)
* [move](#move)
* [path](#path)
* [read](#read)
* [remove](#remove)
* [rename](#rename)
* [symlink](#symlink)
* [write](#write)
- [append](#appendpath-data-options)
- [copy](#copyfrom-to-options)
- [createReadStream](#createreadstreampath-options)
- [createWriteStream](#createwritestreampath-options)
- [cwd](#cwdpath)
- [dir](#dirpath-criteria)
- [exists](#existspath)
- [file](#filepath-criteria)
- [find](#findpath-searchoptions)
- [inspect](#inspectpath-options)
- [inspectTree](#inspecttreepath-options)
- [list](#listpath)
- [move](#movefrom-to)
- [path](#pathparts)
- [read](#readpath-returnas)
- [remove](#removepath)
- [rename](#renamepath-newname)
- [symlink](#symlinksymlinkvalue-path)
- [write](#writepath-data-options)
## <a name="append"></a> append(path, data, [options])
## append(path, data, [options])
asynchronous: **appendAsync(path, data, [options])**

@@ -174,3 +172,3 @@

## <a name="copy"></a> copy(from, to, [options])
## copy(from, to, [options])
asynchronous: **copyAsync(from, to, [options])**

@@ -192,3 +190,3 @@

```javascript
// Copies a file (and replaces it if one already exists in 'copied' direcotry)
// Copies a file (and replaces it if one already exists in 'copied' directory)
jetpack.copy('file.txt', 'copied/file.txt', { overwrite: true });

@@ -214,3 +212,3 @@

## <a name="create-read-stream"></a> createReadStream(path, [options])
## createReadStream(path, [options])

@@ -220,3 +218,3 @@ Just an alias to vanilla [fs.createReadStream](http://nodejs.org/api/fs.html#fs_fs_createreadstream_path_options).

## <a name="create-write-stream"></a> createWriteStream(path, [options])
## createWriteStream(path, [options])

@@ -227,3 +225,3 @@ Just an alias to vanilla [fs.createWriteStream](http://nodejs.org/api/fs.html#fs_fs_createwritestream_path_options).

## <a name="cwd"></a> cwd([path...])
## cwd([path...])
Returns Current Working Directory (CWD) for this instance of jetpack, or creates new jetpack object with given path as its internal CWD.

@@ -262,3 +260,3 @@ **Note:** fs-jetpack never changes value of `process.cwd()`, the CWD we are talking about here is internal value inside every jetpack instance.

## <a name="dir"></a> dir(path, [criteria])
## dir(path, [criteria])
asynchronous: **dirAsync(path, [criteria])**

@@ -293,6 +291,6 @@

## <a name="exists"></a> exists(path)
## exists(path)
asynchronous: **existsAsync(path)**
Checks whether something exists on given `path`. This method returns values more specyfic than `true/false` to protect from errors like "I was expecting directory, but it was a file".
Checks whether something exists on given `path`. This method returns values more specific than `true/false` to protect from errors like "I was expecting directory, but it was a file".

@@ -306,3 +304,3 @@ **returns:**

## <a name="file"></a> file(path, [criteria])
## file(path, [criteria])
asynchronous: **fileAsync(path, [criteria])**

@@ -332,3 +330,3 @@

## <a name="find"></a> find([path], searchOptions)
## find([path], searchOptions)
asynchronous: **findAsync([path], searchOptions)**

@@ -364,3 +362,3 @@

## <a name="inspect"></a> inspect(path, [options])
## inspect(path, [options])
asynchronous: **inspectAsync(path, [options])**

@@ -376,7 +374,7 @@

* `times` (default `false`) if set to `true` will add atime, mtime and ctime fields (here called `accessTime`, `modifyTime` and `changeTime`).
* `absolutePath` (dafault `false`) if set to `true` will add absolute path to this resource.
* `symlinks` (dafault `false`) if set to `true` will just inspect symlink itself and not follow it.
* `absolutePath` (default `false`) if set to `true` will add absolute path to this resource.
* `symlinks` (default `false`) if set to `true` will just inspect symlink itself and not follow it.
**returns:**
`null` if given path doens't exist.
`undefined` if given path doens't exist.
Otherwise `Object` of structure:

@@ -400,3 +398,3 @@ ```javascript

## <a name="inspect-tree"></a> inspectTree(path, [options])
## inspectTree(path, [options])
asynchronous: **inspectTreeAsync(path, [options])**

@@ -413,3 +411,3 @@

**returns:**
`null` if given path doesn't exist.
`undefined` if given path doesn't exist.
Otherwise tree of inspect objects like:

@@ -429,5 +427,5 @@ ```javascript

type: 'dir',
size: 0, // the directory is empty
size: 0,
relativePath: './dir',
md5: null, // can't calculate checksum of empty directory
md5: 'd41d8cd98f00b204e9800998ecf8427e',
children: []

@@ -446,3 +444,3 @@ },{

## <a name="list"></a> list([path])
## list([path])
asynchronous: **listAsync(path, [useInspect])**

@@ -456,6 +454,6 @@

**returns:**
Array of file names inside given path, or `null` if given path doesn't exist.
Array of file names inside given path, or `undefined` if given path doesn't exist.
## <a name="move"></a> move(from, to)
## move(from, to)
asynchronous: **moveAsync(from, to)**

@@ -473,3 +471,3 @@

## <a name="path"></a> path(parts...)
## path(parts...)
Returns path resolved to internal CWD of this jetpack object.

@@ -492,6 +490,6 @@

## <a name="read"></a> read(path, [returnAs])
## read(path, [returnAs])
asynchronous: **readAsync(path, [returnAs])**
Reads content of file. If file on given path doesn't exist returns `null` instead of throwing error.
Reads content of file.

@@ -508,6 +506,6 @@ **parameters:**

**returns:**
File content in specified format, or `null` if file doesn't exist.
File content in specified format, or `undefined` if file doesn't exist.
## <a name="remove"></a> remove([path])
## remove([path])
asynchronous: **removeAsync([path])**

@@ -538,10 +536,10 @@

## <a name="symlink"></a> symlink(symlinkValue, path)
asynchronous: **symlinkAsync(symlinkValue, path)**
## rename(path, newName)
asynchronous: **renameAsync(path, newName)**
Creates symbolic link.
Renames given file or directory.
**parameters:**
`symlinkValue` path where symbolic link should point.
`path` path where symbolic link should be put.
`path` path to thing you want to change name.
`newName` new name for this thing (not full path, just a name).

@@ -552,10 +550,10 @@ **returns:**

## <a name="rename"></a> rename(path, newName)
asynchronous: **renameAsync(path, newName)**
## symlink(symlinkValue, path)
asynchronous: **symlinkAsync(symlinkValue, path)**
Renames given file or directory.
Creates symbolic link.
**parameters:**
`path` path to thing you want to change name.
`newName` new name for this thing (not full path, just a name).
`symlinkValue` path where symbolic link should point.
`path` path where symbolic link should be put.

@@ -566,3 +564,3 @@ **returns:**

## <a name="write"></a> write(path, data, [options])
## write(path, data, [options])
asynchronous: **writeAsync(path, data, [options])**

@@ -569,0 +567,0 @@

@@ -132,21 +132,21 @@ /* eslint-env jasmine */

it('if given path is file, deletes it and places dir instead', function (done) {
var preparations = function () {
helper.clearWorkingDir();
fse.outputFileSync('a', 'abc');
it('halts if given path is something other than directory', function (done) {
var expectations = function (err) {
expect(err.message).toContain('exists but is not a directory.');
};
var expectations = function () {
expect('a').toBeDirectory();
};
fse.outputFileSync('a', 'abc');
// SYNC
preparations();
jetpack.dir('a');
expectations();
try {
jetpack.dir('a');
throw new Error('to make sure this code throws');
} catch (err) {
expectations(err);
}
// ASYNC
preparations();
jetpack.dirAsync('a')
.then(function () {
expectations();
.catch(function (err) {
expectations(err);
done();

@@ -153,0 +153,0 @@ });

@@ -199,22 +199,20 @@ /* eslint-env jasmine */

it('if given path is directory, should delete it and place file instead', function (done) {
var preparations = function () {
helper.clearWorkingDir();
// Create nested directories to be sure we can delete non-empty dir.
fse.outputFileSync('a/b/c.txt', 'abc');
it('halts if given path is not a file', function (done) {
var expectations = function (err) {
expect(err.message).toContain('exists but is not a file.');
};
var expectations = function () {
expect('a').toBeFileWithContent('');
};
fse.mkdirsSync('a');
// SYNC
preparations();
jetpack.file('a');
expectations();
try {
jetpack.file('a');
} catch (err) {
expectations(err);
}
// ASYNC
preparations();
jetpack.fileAsync('a')
.then(function () {
expectations();
.catch(function (err) {
expectations(err);
done();

@@ -221,0 +219,0 @@ });

@@ -177,3 +177,3 @@ /* eslint-env jasmine */

expect(err.code).toBe('ENOENT');
expect(err.message).toMatch(/^Path you want to find stuff in doesn't exist/);
expect(err.message).toContain("Path you want to find stuff in doesn't exist");
};

@@ -184,2 +184,3 @@

jetpack.find('a', { matching: '*.txt' });
throw new Error('to make sure this code throws');
} catch (err) {

@@ -222,3 +223,4 @@ expectations(err);

var expectations = function (found) {
expect(found).toEqual(['b/c/d.txt']); // NOT a/b/c/d.txt
var normalizedFound = helper.convertToUnixPathSeparators(found);
expect(normalizedFound).toEqual(['b/c/d.txt']); // NOT a/b/c/d.txt
};

@@ -225,0 +227,0 @@

@@ -86,54 +86,2 @@ /* eslint-env jasmine */

it('can compute checksum of a whole tree', function (done) {
var expectations = function (data) {
// md5 of
// 'a.txt' + '900150983cd24fb0d6963f7d28e17f72' +
// 'b.txt' + '025e4da7edac35ede583f5e8d51aa7ec'
expect(data.md5).toBe('b0ff9df854172efe752cb36b96c8bccd');
// md5 of 'abc'
expect(data.children[0].md5).toBe('900150983cd24fb0d6963f7d28e17f72');
// md5 of 'defg'
expect(data.children[1].md5).toBe('025e4da7edac35ede583f5e8d51aa7ec');
};
fse.outputFileSync('dir/a.txt', 'abc');
fse.outputFileSync('dir/b.txt', 'defg');
// SYNC
expectations(jetpack.inspectTree('dir', { checksum: 'md5' }));
// ASYNC
jetpack.inspectTreeAsync('dir', { checksum: 'md5' })
.then(function (tree) {
expectations(tree);
done();
});
});
it('can deal with empty directories while computing checksum', function (done) {
var expectations = function (data) {
// md5 of
// 'empty_dir' + 'd41d8cd98f00b204e9800998ecf8427e' +
// 'file.txt' + '900150983cd24fb0d6963f7d28e17f72'
expect(data.md5).toBe('4715a354a7871a1db629b379e6267b95');
// md5 of empty directory -> md5 of empty string
expect(data.children[0].md5).toBe('d41d8cd98f00b204e9800998ecf8427e');
// md5 of 'abc'
expect(data.children[1].md5).toBe('900150983cd24fb0d6963f7d28e17f72');
};
fse.mkdirsSync('dir/empty_dir');
fse.outputFileSync('dir/file.txt', 'abc');
// SYNC
expectations(jetpack.inspectTree('dir', { checksum: 'md5' }));
// ASYNC
jetpack.inspectTreeAsync('dir', { checksum: 'md5' })
.then(function (tree) {
expectations(tree);
done();
});
});
it('can output relative path for every tree node', function (done) {

@@ -221,5 +169,5 @@ var expectations = function (data) {

it("returns null if path doesn't exist", function (done) {
it("returns undefined if path doesn't exist", function (done) {
var expectations = function (data) {
expect(data).toBe(null);
expect(data).toBe(undefined);
};

@@ -226,0 +174,0 @@

@@ -56,5 +56,5 @@ /* eslint-env jasmine */

it("returns null if path doesn't exist", function (done) {
it("returns undefined if path doesn't exist", function (done) {
var expectations = function (data) {
expect(data).toBe(null);
expect(data).toBe(undefined);
};

@@ -131,45 +131,2 @@

describe('checksums |', function () {
[
{
name: 'md5',
content: 'abc',
expected: '900150983cd24fb0d6963f7d28e17f72'
},
{
name: 'sha1',
content: 'abc',
expected: 'a9993e364706816aba3e25717850c26c9cd0d89d'
},
{
name: 'sha256',
content: 'abc',
expected: 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad'
},
{
name: 'md5',
content: '', // just to check if we are counting checksums of empty file correctly
expected: 'd41d8cd98f00b204e9800998ecf8427e'
}
].forEach(function (test) {
it(test.name, function (done) {
var expectations = function (data) {
expect(data[test.name]).toBe(test.expected);
};
fse.outputFileSync('file.txt', test.content);
// SYNC
expectations(jetpack.inspect('file.txt', { checksum: test.name }));
// ASYNC
jetpack.inspectAsync('file.txt', { checksum: test.name })
.then(function (data) {
expectations(data);
done();
});
});
});
});
describe('*nix specific', function () {

@@ -176,0 +133,0 @@ if (process.platform === 'win32') {

@@ -55,5 +55,5 @@ /* eslint-env jasmine */

it("returns null if path doesn't exist", function (done) {
it("returns undefined if path doesn't exist", function (done) {
var expectations = function (data) {
expect(data).toBe(null);
expect(data).toBe(undefined);
};

@@ -72,5 +72,5 @@

it('returns null if given path is a file', function (done) {
var expectations = function (list) {
expect(list).toBe(null);
it('throws if given path is not a directory', function (done) {
var expectations = function (err) {
expect(err.code).toBe('ENOTDIR');
};

@@ -81,8 +81,13 @@

// SYNC
expectations(jetpack.list('file.txt'));
try {
jetpack.list('file.txt');
throw new Error('to make sure this code throws');
} catch (err) {
expectations(err);
}
// ASYNC
jetpack.listAsync('file.txt')
.then(function (list) {
expectations(list);
.catch(function (err) {
expectations(err);
done();

@@ -89,0 +94,0 @@ });

@@ -143,5 +143,5 @@ /* eslint-env jasmine */

it("returns null if file doesn't exist", function (done) {
it("returns undefined if file doesn't exist", function (done) {
var expectations = function (content) {
expect(content).toBe(null);
expect(content).toBe(undefined);
};

@@ -148,0 +148,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc