fs-jetpack
Advanced tools
Comparing version 0.4.0 to 0.4.1
@@ -0,3 +1,9 @@ | ||
0.4.1 (2014-07-16) | ||
------------------- | ||
* `copy()` now copies also file permissions on unix systems. | ||
* `append()` can specify file mode if file doesn't exist. | ||
* Can indent saved JSON data. | ||
0.4.0 (2014-07-14) | ||
------------------- | ||
* Changelog starts here. |
@@ -10,2 +10,3 @@ "use strict"; | ||
var matcher = require('./utils/matcher'); | ||
var mode = require('./utils/mode'); | ||
var inspector = require('./inspector'); | ||
@@ -30,3 +31,3 @@ var fileOps = require('./fileOps'); | ||
if (stat.isDirectory()) { | ||
mkdirp.sync(to); | ||
mkdirp.sync(to, { mode: mode.normalizeFileMode(stat.mode) }); | ||
var list = fs.readdirSync(from); | ||
@@ -38,3 +39,3 @@ list.forEach(function (filename) { | ||
var data = fs.readFileSync(from); | ||
fileOps.write(to, data); | ||
fileOps.write(to, data, { mode: mode.normalizeFileMode(stat.mode) }); | ||
} | ||
@@ -92,3 +93,3 @@ }; | ||
// Prepare destination directory | ||
qMkdirp(to) | ||
qMkdirp(to, { mode: mode.normalizeFileMode(stat.mode) }) | ||
.then(function () { | ||
@@ -110,3 +111,3 @@ // Read all things to copy... | ||
.then(function (data) { | ||
return fileOps.writeAsync(to, data); | ||
return fileOps.writeAsync(to, data, { mode: mode.normalizeFileMode(stat.mode) }); | ||
}) | ||
@@ -113,0 +114,0 @@ .then(deferred.resolve, deferred.reject); |
@@ -27,12 +27,2 @@ "use strict"; | ||
function normalizeContent(content) { | ||
if (typeof content === 'string' || Buffer.isBuffer(content)) { | ||
return content; | ||
} | ||
if (content !== null && typeof content === 'object') { | ||
return JSON.stringify(content, null, 2); | ||
} | ||
return content || ''; | ||
} | ||
//--------------------------------------------------------- | ||
@@ -85,3 +75,3 @@ // Sync | ||
if (criteria.empty === false && criteria.content !== undefined) { | ||
fileOps.write(path, criteria.content, { mode: mode }); | ||
fileOps.write(path, criteria.content, { mode: mode, jsonIndent: criteria.jsonIndent }); | ||
} | ||
@@ -91,3 +81,3 @@ | ||
// Create new file. | ||
fileOps.write(path, criteria.content || '', { mode: criteria.mode }); | ||
fileOps.write(path, criteria.content || '', { mode: criteria.mode, jsonIndent: criteria.jsonIndent }); | ||
} | ||
@@ -171,3 +161,3 @@ }; | ||
if (criteria.empty === false && criteria.content !== undefined) { | ||
fileOps.writeAsync(path, criteria.content, { mode: mode }) | ||
fileOps.writeAsync(path, criteria.content, { mode: mode, jsonIndent: criteria.jsonIndent }) | ||
.then(deferred.resolve, deferred.reject); | ||
@@ -183,3 +173,3 @@ } else { | ||
} else if (criteria.exists === true) { | ||
fileOps.writeAsync(path, criteria.content || '', { mode: criteria.mode }) | ||
fileOps.writeAsync(path, criteria.content || '', { mode: criteria.mode, jsonIndent: criteria.jsonIndent }) | ||
.then(deferred.resolve, deferred.reject); | ||
@@ -186,0 +176,0 @@ } else { |
@@ -29,3 +29,3 @@ // Simple operations on a file: read, write, append. | ||
function normalizeDataToWrite(data) { | ||
function normalizeDataToWrite(data, options) { | ||
// if this crazy "if" is true we are sure the passed thing is simple object | ||
@@ -35,3 +35,3 @@ if (Buffer.isBuffer(data) === false && | ||
data != null) { | ||
data = JSON.stringify(data); | ||
data = JSON.stringify(data, null, options.jsonIndent || 0); | ||
} | ||
@@ -154,4 +154,4 @@ | ||
function write(path, data, options) { | ||
data = normalizeDataToWrite(data); | ||
options = normalizeOptions(options); | ||
data = normalizeDataToWrite(data, options); | ||
@@ -165,9 +165,9 @@ if (options.safe === true) { | ||
function append(path, data) { | ||
function append(path, data, options) { | ||
try { | ||
fs.appendFileSync(path, data); | ||
fs.appendFileSync(path, data, options); | ||
} catch (err) { | ||
if (err.code === 'ENOENT') { | ||
// parent directory doesn't exist, so just create it and write the file | ||
writeFileSync(path, data); | ||
writeFileSync(path, data, options); | ||
} else { | ||
@@ -321,4 +321,4 @@ throw err; | ||
data = normalizeDataToWrite(data); | ||
options = normalizeOptions(options); | ||
data = normalizeDataToWrite(data, options); | ||
@@ -336,6 +336,6 @@ if (options.safe === true) { | ||
function appendAsync(path, data) { | ||
function appendAsync(path, data, options) { | ||
var deferred = Q.defer(); | ||
qAppendFile(path, data) | ||
qAppendFile(path, data, options) | ||
.then(deferred.resolve, function (err) { | ||
@@ -351,3 +351,3 @@ | ||
// retry | ||
appendAsync(path, data) | ||
appendAsync(path, data, options) | ||
.then(deferred.resolve, deferred.reject); | ||
@@ -354,0 +354,0 @@ } |
@@ -57,7 +57,7 @@ // The main thing. Here everything starts. | ||
append: function (path, data) { | ||
fileOps.append(resolvePath(path), data); | ||
append: function (path, data, options) { | ||
fileOps.append(resolvePath(path), data, options); | ||
}, | ||
appendAsync: function (path, data) { | ||
return fileOps.appendAsync(resolvePath(path), data); | ||
appendAsync: function (path, data, options) { | ||
return fileOps.appendAsync(resolvePath(path), data, options); | ||
}, | ||
@@ -64,0 +64,0 @@ |
{ | ||
"name": "fs-jetpack", | ||
"description": "Higher level API for 'fs' library", | ||
"version": "0.4.0", | ||
"version": "0.4.1", | ||
"author": "Jakub Szwacz <jakub@szwacz.com>", | ||
@@ -6,0 +6,0 @@ "dependencies": { |
@@ -39,3 +39,3 @@ fs-jetpack | ||
**Methods:** | ||
* [append(path, data)](#append) | ||
* [append(path, data, [options])](#append) | ||
* [copy(from, to, [options])](#copy) | ||
@@ -54,7 +54,7 @@ * [cwd([path])](#cwd) | ||
* [tree(path)](#tree) | ||
* [write(path, data)](#write) | ||
* [write(path, data, [options])](#write) | ||
## <a name="append"></a> append(path, data) | ||
also **appendAsync(path, data)** | ||
## <a name="append"></a> append(path, data, [options]) | ||
also **appendAsync(path, data, [options])** | ||
@@ -65,3 +65,5 @@ Appends given data to the end of file. If file (or any parent directory) doesn't exist, creates it (or them). | ||
`path` the path to file. | ||
`data` data to append (could be `String` or `Buffer`). | ||
`data` data to append (could be `String` or `Buffer`). | ||
`options` (optional) `Object` with possible fields: | ||
* `mode` if the file doesn't exist yet, will be created with given mode. Value could be number (eg. `0700`) or string (eg. `'700'`). | ||
@@ -189,2 +191,3 @@ **returns:** | ||
* `content` (`String`, `Buffer`, `Object` or `Array`) sets file content. If `Object` or `Array` given to this parameter the output will be JSON. If `exists = false`, or `empty = true` this field is ignored. | ||
* `jsonIndent` (defaults to 0) if writing JSON data this tells how many spaces should one indentation have. | ||
* `mode` ensures file has specified mode. If not set and file already exists, current mode will be preserved. Value could be number (eg. `0700`) or string (eg. `'700'`). | ||
@@ -371,4 +374,4 @@ | ||
## <a name="write"></a> write(path, data) | ||
also **writeAsync(path, data)** | ||
## <a name="write"></a> write(path, data, [options]) | ||
also **writeAsync(path, data, [options])** | ||
@@ -379,3 +382,5 @@ Writes data to file. | ||
`path` path to file. | ||
`content` data to be written. This could be `String`, `Buffer`, `Object` or `Array` (if last two used, the data will be outputed into file as JSON). | ||
`content` data to be written. This could be `String`, `Buffer`, `Object` or `Array` (if last two used, the data will be outputed into file as JSON). | ||
`options` (optional) `Object` with possible fields: | ||
* `jsonIndent` (defaults to 0) if writing JSON data this tells how many spaces should one indentation have. | ||
@@ -425,4 +430,4 @@ **returns:** | ||
### Hides ENOENT from you as much as possible | ||
*"ENOENT, no such file or directory"* is the most annoying error when working with file system, and fs-jetpack does 2 things to save you the hassle: | ||
1. For wrte/creation operations, if any of parent directories doesn't exist, jetpack will just create them as well. | ||
*"ENOENT, no such file or directory"* is the most annoying error when working with file system, and fs-jetpack does 2 things to save you the hassle: | ||
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. | ||
@@ -463,7 +468,7 @@ | ||
``` | ||
Above line will perform tasks as follows: | ||
1. Write `Hello universe!` to `file.txt.__new__` (so we didn't owerwrite the original file). | ||
2. Move `file.txt` (with `Hello world!`) to `file.txt.__bak__`, so it can serve as a backup. | ||
3. Move `file.txt.__new__` to `file.txt`, where we wanted it to be on the first place. | ||
4. Delete `file.txt.__bak__`, because it is no longer needed. | ||
Above line will perform tasks as follows: | ||
1. Write `Hello universe!` to `file.txt.__new__` (so we didn't owerwrite the original file). | ||
2. Move `file.txt` (with `Hello world!`) to `file.txt.__bak__`, so it can serve as a backup. | ||
3. Move `file.txt.__new__` to `file.txt`, where we wanted it to be on the first place. | ||
4. Delete `file.txt.__bak__`, because it is no longer needed. | ||
Thanks to that the backup of old data is reachable all the time, until we are 100% sure the new data has been successfuly written to disk. | ||
@@ -475,7 +480,7 @@ | ||
``` | ||
Above read will do: | ||
1. Read `file.txt` | ||
2. If step 1 failed, try to read `file.txt.__bak__`. | ||
Above read will do: | ||
1. Read `file.txt` | ||
2. If step 1 failed, try to read `file.txt.__bak__`. | ||
3. If step 2 failed as well, we are sure there is no such file. | ||
The whole process is performed automatically for you by simply adding `safe: true` to call options of [write](#write) and [read](#read) methods. | ||
The whole process is performed automatically for you by simply adding `safe: true` to call options of [write](#write) and [read](#read) methods. |
@@ -15,4 +15,2 @@ "use strict"; | ||
// TODO append should also allow to specify file mode | ||
it('appends String to file', function (done) { | ||
@@ -130,2 +128,30 @@ | ||
if (process.platform !== 'win32') { | ||
describe('*nix specyfic |', function () { | ||
it('sets file mode on created file', function (done) { | ||
var expectations = function () { | ||
expect(fse.statSync('file.txt').mode.toString(8)).toBe('100711'); | ||
}; | ||
// SYNC | ||
jetpack.append('file.txt', 'abc', { mode: '711' }); | ||
expectations(); | ||
helper.clearWorkingDir(); | ||
// AYNC | ||
jetpack.appendAsync('file.txt', 'abc', { mode: '711' }) | ||
.then(function () { | ||
expectations(); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
} | ||
}); |
@@ -355,2 +355,39 @@ "use strict"; | ||
if (process.platform !== 'win32') { | ||
describe('*nix specyfic |', function () { | ||
it('copies also file permissions', function (done) { | ||
var preparations = function () { | ||
fse.outputFileSync('a/b/c.txt', 'abc'); | ||
fse.chmodSync('a/b', '700'); | ||
fse.chmodSync('a/b/c.txt', '711'); | ||
}; | ||
var expectations = function () { | ||
expect(fse.statSync('a1/b').mode.toString(8)).toBe('40700'); | ||
expect(fse.statSync('a1/b/c.txt').mode.toString(8)).toBe('100711'); | ||
}; | ||
// SYNC | ||
preparations(); | ||
jetpack.copy('a', 'a1'); | ||
expectations(); | ||
helper.clearWorkingDir(); | ||
// AYNC | ||
preparations(); | ||
jetpack.copyAsync('a', 'a1') | ||
.then(function () { | ||
expectations(); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
} | ||
}); |
@@ -224,2 +224,30 @@ "use strict"; | ||
it('written JSON data can be indented', function (done) { | ||
var obj = { a: "abc", b: 123 }; | ||
var expectations = function (content) { | ||
var sizeA = fse.statSync('a.json').size; | ||
var sizeB = fse.statSync('b.json').size; | ||
expect(sizeB).toBeGreaterThan(sizeA); | ||
}; | ||
// SYNC | ||
jetpack.file('a.json', { content: obj }); | ||
jetpack.file('b.json', { content: obj, jsonIndent: 4 }); | ||
expectations(); | ||
helper.clearWorkingDir(); | ||
// ASYNC | ||
jetpack.fileAsync('a.json', { content: obj }) | ||
.then(function () { | ||
return jetpack.fileAsync('b.json', { content: obj, jsonIndent: 4 }); | ||
}) | ||
.then(function () { | ||
expectations(); | ||
done(); | ||
}); | ||
}); | ||
it("replaces content of already existing file", function (done) { | ||
@@ -226,0 +254,0 @@ |
@@ -28,2 +28,4 @@ "use strict"; | ||
helper.clearWorkingDir(); | ||
// ASYNC | ||
@@ -61,2 +63,4 @@ jetpack.writeAsync(path, 'ąbć') | ||
helper.clearWorkingDir(); | ||
// ASYNC | ||
@@ -79,6 +83,2 @@ jetpack.writeAsync(path, buf) | ||
var expectations = function (content) { | ||
expect(content).toEqual(obj); | ||
}; | ||
// SYNC | ||
@@ -89,2 +89,4 @@ jetpack.write(path, obj); | ||
helper.clearWorkingDir(); | ||
// ASYNC | ||
@@ -96,3 +98,3 @@ jetpack.writeAsync(path, obj) | ||
.then(function (content) { | ||
expectations(content); | ||
expect(content).toEqual(obj); | ||
done(); | ||
@@ -102,2 +104,32 @@ }); | ||
it('written JSON data can be indented', function (done) { | ||
var obj = { | ||
utf8: "ąćłźż" | ||
}; | ||
var expectations = function (content) { | ||
var sizeA = fse.statSync('a.json').size; | ||
var sizeB = fse.statSync('b.json').size; | ||
expect(sizeB).toBeGreaterThan(sizeA); | ||
}; | ||
// SYNC | ||
jetpack.write('a.json', obj); | ||
jetpack.write('b.json', obj, { jsonIndent: 4 }); | ||
expectations(); | ||
helper.clearWorkingDir(); | ||
// ASYNC | ||
jetpack.writeAsync('a.json', obj) | ||
.then(function () { | ||
return jetpack.writeAsync('b.json', obj, { jsonIndent: 4 }); | ||
}) | ||
.then(function () { | ||
expectations(); | ||
done(); | ||
}); | ||
}); | ||
it('writes and reads file as JSON with Date parsing', function (done) { | ||
@@ -104,0 +136,0 @@ |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
158376
3597
478
0