mem-fs-editor
Advanced tools
Comparing version 1.0.1 to 1.1.0
@@ -11,3 +11,6 @@ 'use strict'; | ||
function write(file) { | ||
mkdirp.sync(path.dirname(file.path)); | ||
var dir = path.dirname(file.path); | ||
if (!fs.existsSync(dir)) { | ||
mkdirp.sync(dir); | ||
} | ||
fs.writeFileSync(file.path, file.contents, { | ||
@@ -14,0 +17,0 @@ mode: file.stat ? file.stat.mode : null |
@@ -7,2 +7,3 @@ 'use strict'; | ||
var glob = require('glob'); | ||
var _ = require('lodash'); | ||
var File = require('vinyl'); | ||
@@ -16,21 +17,21 @@ var util = require('../util/util'); | ||
function isFile(filepath) { | ||
return fs.existsSync(filepath) && fs.statSync(filepath).isFile(); | ||
}; | ||
exports.copy = function(from, to, options) { | ||
from = util.globify(from); | ||
to = path.resolve(to); | ||
options = options || { globOptions : {} }; | ||
exports.copy = function (from, to, options) { | ||
to = path.resolve(to); | ||
if (from.indexOf('*') === -1) { | ||
return this._copySingle(from, to, options) | ||
if (!glob.hasMagic(from)) { | ||
return this._copySingle(from, to, options); | ||
} | ||
assert( | ||
path.extname(to) === '', | ||
!this.exists(to) || fs.statSync(to).isDirectory(), | ||
'When copying with glob patterns, provide a directory as destination' | ||
); | ||
var files = glob.sync(from).filter(isFile); | ||
var root = util.getCommonPath(files); | ||
var globOptions = _.extend(options.globOptions, { nodir: true }); | ||
var files = glob.sync(from, globOptions); | ||
var root = util.getCommonPath(from); | ||
files.forEach(function (file, index) { | ||
files.forEach(function (file) { | ||
var toFile = path.relative(root, file); | ||
@@ -37,0 +38,0 @@ toFile = path.join(to, toFile); |
'use strict'; | ||
var assert = require('assert'); | ||
var _ = require('lodash'); | ||
var glob = require('glob'); | ||
var util = require('../util/util'); | ||
function deleteFile(file, store) { | ||
function deleteFile(path, store) { | ||
var file = store.get(path); | ||
file.state = 'deleted'; | ||
@@ -11,10 +15,18 @@ file.contents = new Buffer(''); | ||
module.exports = function (path) { | ||
var deletedPath = this.store.get(path).path; | ||
module.exports = function (path, options) { | ||
path = util.globify(path); | ||
options = options || { globOptions : {} }; | ||
var globOptions = _.extend(options.globOptions, { sync: true }); | ||
var g = new glob.Glob(path, globOptions); | ||
var files = g.found; | ||
files.forEach(function (file) { | ||
deleteFile(file, this.store) | ||
}.bind(this)); | ||
this.store.each(function (file) { | ||
if (file.path.indexOf(deletedPath) === 0) { | ||
deleteFile(file, this.store); | ||
if (g.minimatch.match(file.path)) { | ||
deleteFile(file.path, this.store); | ||
} | ||
}.bind(this)); | ||
}; |
'use strict'; | ||
module.exports = function (path) { | ||
return JSON.parse(this.read(path)); | ||
module.exports = function (path, defaults) { | ||
if (this.exists(path)) { | ||
return JSON.parse(this.read(path)); | ||
} else { | ||
return defaults; | ||
} | ||
}; |
@@ -9,2 +9,4 @@ 'use strict'; | ||
file.contents = file.contents || new Buffer(options.defaults); | ||
assert(file.contents !== null && file.state !== 'deleted', path + ' doesn\'t exist'); | ||
@@ -11,0 +13,0 @@ |
@@ -9,3 +9,5 @@ 'use strict'; | ||
EditionInterface.prototype.readJSON = require('./actions/read-json.js'); | ||
EditionInterface.prototype.exists = require( './actions/exists' ); | ||
EditionInterface.prototype.write = require('./actions/write.js'); | ||
EditionInterface.prototype.writeJSON = require('./actions/write-json.js'); | ||
EditionInterface.prototype.delete = require('./actions/delete.js'); | ||
@@ -12,0 +14,0 @@ EditionInterface.prototype.copy = require('./actions/copy.js').copy; |
{ | ||
"name": "mem-fs-editor", | ||
"version": "1.0.1", | ||
"version": "1.1.0", | ||
"description": "File edition helpers working on top of mem-fs", | ||
@@ -24,2 +24,3 @@ "main": "index.js", | ||
"rimraf": "^2.2.8", | ||
"sinon": "^1.12.2", | ||
"through2": "^0.6.3", | ||
@@ -26,0 +27,0 @@ "vinyl": "^0.4.3" |
@@ -25,6 +25,10 @@ mem-fs-editor [![Build Status](https://travis-ci.org/SBoudrias/mem-fs-editor.svg?branch=master)](https://travis-ci.org/SBoudrias/mem-fs-editor) | ||
### `#readJSON(filepath)` | ||
By default, calling `read()` on a file path that does not exist throws error. You can, however, pass `options.defaults = 'your default content'` to get a default content you pass in, if you prefer to not deal with try/catch. | ||
### `#readJSON(filepath, [defaults])` | ||
Read a file and parse its contents as JSON. | ||
`readJSON()` internally calls `read()` and will throw error if the file path you pass in does not exist. But if you pass in an optional `defaults`, the `defaults` content will be returned in case of the target file is missing, instead of throwing error (error would still be thrown if JSON.parse failed to parse your target file). | ||
### `#write(filepath, contents)` | ||
@@ -34,6 +38,18 @@ | ||
### `#delete(filepath)` | ||
### `#writeJSON(filepath, contents[, replacer [, space]])` | ||
Replace the content of a file (existing or new) with an object that is to be converted by calling `JSON.stringify()`. | ||
`contents` should usually be a JSON object, but it can technically be anything that is acceptable by [JSON.stringify](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). | ||
Optionally pass `replacer` and `space` as the last two arguments, as defined by [JSON.stringify](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). `spacer` is used to format the output string (prettify). | ||
Default value for `space` is `2`, when not specified. | ||
### `#delete(filepath, [options])` | ||
Delete a file or a directory. | ||
`filePath` can also be a `glob`. If `filePath` is glob, you can optionally pass in an `options.globOptions` object to change its pattern matching behavior. The full list of options are being described [here](https://github.com/isaacs/node-glob#options). The `sync` flag is forced to be `true` in `globOptions`. | ||
### `#copy(from, to, [options])` | ||
@@ -45,3 +61,3 @@ | ||
`from` can be a glob pattern that'll be match against the file system. If that's the case, then `to` must be an output directory. | ||
`from` can be a glob pattern that'll be match against the file system. If that's the case, then `to` must be an output directory. For a globified `from`, you can optionally pass in an `options.globOptions` object to change its pattern matching behavior. The full list of options are being described [here](https://github.com/isaacs/node-glob#options). The `nodir` flag is forced to be `true` in `globOptions` to ensure a vinyl object representing each matching directory is marked as `deleted` in the `mem-fs` store. | ||
@@ -54,2 +70,6 @@ ### `#copyTpl(from, to, context, [settings])` | ||
### `#exists(filepath)` | ||
Returns `true` if a file exists. Returns `false` if the file is not found or deleted. | ||
### `#commit([filters,] callback)` | ||
@@ -56,0 +76,0 @@ |
@@ -40,2 +40,8 @@ 'use strict'; | ||
it('copy by directory', function () { | ||
this.fs.copy(__dirname + '/fixtures', '/output'); | ||
assert.equal(this.fs.read('/output/file-a.txt'), 'foo\n'); | ||
assert.equal(this.fs.read('/output/nested/file.txt'), 'nested\n'); | ||
}); | ||
it('copy by globbing', function () { | ||
@@ -47,5 +53,11 @@ this.fs.copy(__dirname + '/fixtures/**', '/output'); | ||
it('accepts directory name with "."', function () { | ||
this.fs.copy(__dirname + '/fixtures/**', '/out.put'); | ||
assert.equal(this.fs.read('/out.put/file-a.txt'), 'foo\n'); | ||
assert.equal(this.fs.read('/out.put/nested/file.txt'), 'nested\n'); | ||
}); | ||
it('requires destination directory when globbing', function () { | ||
assert.throws( | ||
this.fs.copy.bind(this.fs, __dirname + '/fixtures/**', '/output/file.a') | ||
this.fs.copy.bind(this.fs, __dirname + '/fixtures/**', __dirname + '/fixtures/file-a.txt') | ||
); | ||
@@ -52,0 +64,0 @@ }); |
@@ -24,3 +24,2 @@ 'use strict'; | ||
var nestedFile = path.join(dirpath, 'file.txt'); | ||
this.fs.read(nestedFile) | ||
this.fs.delete(dirpath); | ||
@@ -27,0 +26,0 @@ assert.equal(this.fs.store.get(dirpath).state, 'deleted'); |
@@ -5,2 +5,3 @@ 'use strict'; | ||
var path = require('path'); | ||
var sinon = require('sinon'); | ||
var editor = require('..'); | ||
@@ -19,2 +20,20 @@ var memFs = require('mem-fs'); | ||
}); | ||
it('calls read() with path', function () { | ||
var read = sinon.spy(this.fs, 'read'); | ||
var file = path.join(__dirname, 'fixtures/file.json'); | ||
this.fs.readJSON(file); | ||
sinon.assert.calledOnce(read); | ||
sinon.assert.calledWith(read, file); | ||
read.restore(); | ||
}); | ||
it('return defaults if file does not exist and defaults is provided', function () { | ||
var obj = this.fs.readJSON(path.join(__dirname, 'no-such-file.json'), { foo: 'bar' }); | ||
assert.equal(obj.foo, 'bar'); | ||
}); | ||
it('throw error if file could not be parsed as JSON, even if defaults is provided', function () { | ||
assert.throws(this.fs.readJSON.bind(this.fs, path.join(__dirname, 'fixtures/file-tpl.txt'), { foo: 'bar' })); | ||
}) | ||
}); |
@@ -30,2 +30,16 @@ 'use strict'; | ||
}); | ||
it('return defaults as String if file does not exsit and defaults is provided', function () { | ||
var content = this.fs.read('file-who-does-not-exist.txt', { defaults: 'foo\n' }); | ||
assert.equal(content, 'foo\n'); | ||
}); | ||
it('return defaults as Buffer if file does not exsit and defaults is provided', function () { | ||
var content = this.fs.read('file-who-does-not-exist.txt', { | ||
defaults: new Buffer('foo\n'), | ||
raw: true | ||
}); | ||
assert(content instanceof Buffer); | ||
assert.equal(content.toString(), 'foo\n'); | ||
}); | ||
}); |
'use strict'; | ||
var path = require('path'); | ||
var assert = require('assert'); | ||
@@ -7,22 +8,49 @@ var util = require('../util/util'); | ||
describe('util.getCommonPath()', function () { | ||
it('find the common root of files in same directory', function () { | ||
assert.equal( | ||
util.getCommonPath(['/a/b/c.js', '/a/b/d.js', '/a/b/e.js']), | ||
'/a/b' | ||
); | ||
it('find the common root of /a/b/c, where /a/b/c is an existing directory', function () { | ||
var filePath = path.resolve(__dirname, 'fixtures'); | ||
assert.equal(util.getCommonPath(filePath), filePath); | ||
}); | ||
it('find the common root of files in differents directory', function () { | ||
assert.equal( | ||
util.getCommonPath(['/a/b/c.js', '/a/c/d.js', '/a/b/e.js']), | ||
'/a' | ||
); | ||
it('find the common root of /a/b/c, where /a/b/c is an existing file', function () { | ||
var filePath = path.resolve(__dirname, 'fixtures'); | ||
assert.equal(util.getCommonPath(path.join(filePath, 'file-a.txt')), filePath); | ||
}); | ||
it('find the common root of files sharing no common root', function () { | ||
assert.equal( | ||
util.getCommonPath(['/a/b/c.js', '/b/d.js', '/c/e.js']), | ||
'/' | ||
); | ||
it('find the common root of glob /a/b/**', function () { | ||
assert.equal(util.getCommonPath('/a/b/**'), '/a/b'); | ||
}); | ||
it('find the common root of glob /a/b*/c', function () { | ||
assert.equal(util.getCommonPath('/a/b*/c'), '/a'); | ||
}); | ||
it('find the common root of glob /a/b/*.ext', function () { | ||
assert.equal(util.getCommonPath('/a/b/*.ext'), '/a/b'); | ||
}); | ||
}); | ||
describe('util.globify()', function () { | ||
it('returns path for file path', function () { | ||
var filePath = path.resolve(__dirname, 'fixtures/file-a.txt'); | ||
assert.equal(util.globify(filePath), filePath); | ||
}); | ||
it('returns path for nonexisting path', function () { | ||
var filePath = '/nonexisting.file'; | ||
assert.equal(util.globify(filePath), filePath); | ||
}); | ||
it('returns glob for glob path', function () { | ||
var filePath = path.resolve(__dirname, 'fixtures/*.txt'); | ||
assert.equal(util.globify(filePath), filePath); | ||
var filePath2 = path.resolve(__dirname, 'fixtures/file-{a,b}.txt'); | ||
assert.equal(util.globify(filePath2), filePath2); | ||
}); | ||
it('returns globified path for directory path', function () { | ||
var filePath = path.resolve(__dirname, 'fixtures/nested'); | ||
assert.equal(util.globify(filePath), path.join(filePath, '**')); | ||
}); | ||
}); |
'use strict'; | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
var glob = require('glob'); | ||
exports.getCommonPath = function (files) { | ||
var dirs = files.map(path.dirname); | ||
var root = dirs.reduce(function (prev, current) { | ||
var keep = []; | ||
prev = prev.split('/'); | ||
current = current.split('/'); | ||
prev.forEach(function (part, index) { | ||
if (part === current[index]) { | ||
keep.push(part); | ||
} | ||
}); | ||
return keep.join('/'); | ||
}, dirs[0]); | ||
exports.getCommonPath = function (filePath) { | ||
filePath = this.globify(filePath); | ||
var globStartIndex = filePath.indexOf('*'); | ||
if (globStartIndex !== -1) { | ||
filePath = filePath.substring(0, globStartIndex + 1); | ||
} | ||
return root || '/'; | ||
return path.dirname(filePath); | ||
}; | ||
exports.globify = function (filePath) { | ||
if (glob.hasMagic(filePath) || !fs.existsSync(filePath)) { | ||
return filePath; | ||
} | ||
var fsStats = fs.statSync(filePath); | ||
if (fsStats.isFile()) { | ||
return filePath; | ||
} else if (fsStats.isDirectory()) { | ||
return path.join(filePath, '**'); | ||
} else { | ||
throw new Error('Only file path or directory path are supported.'); | ||
} | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
29206
33
628
78
7
5
+ Addedsinon@^1.12.2
+ Addedavailable-typed-arrays@1.0.7(transitive)
+ Addedcall-bind@1.0.7(transitive)
+ Addeddefine-data-property@1.1.4(transitive)
+ Addedes-define-property@1.0.0(transitive)
+ Addedes-errors@1.3.0(transitive)
+ Addedfor-each@0.3.3(transitive)
+ Addedformatio@1.1.1(transitive)
+ Addedfunction-bind@1.1.2(transitive)
+ Addedget-intrinsic@1.2.4(transitive)
+ Addedgopd@1.0.1(transitive)
+ Addedhas-property-descriptors@1.0.2(transitive)
+ Addedhas-proto@1.0.3(transitive)
+ Addedhas-symbols@1.0.3(transitive)
+ Addedhas-tostringtag@1.0.2(transitive)
+ Addedhasown@2.0.2(transitive)
+ Addedis-arguments@1.1.1(transitive)
+ Addedis-callable@1.2.7(transitive)
+ Addedis-generator-function@1.0.10(transitive)
+ Addedis-typed-array@1.1.13(transitive)
+ Addedlolex@1.3.2(transitive)
+ Addedpossible-typed-array-names@1.0.0(transitive)
+ Addedsamsam@1.1.2(transitive)
+ Addedset-function-length@1.2.2(transitive)
+ Addedsinon@1.17.7(transitive)
+ Addedutil@0.12.5(transitive)
+ Addedwhich-typed-array@1.1.15(transitive)