Skip to content

Commit e739f6c

Browse files
erikkempermanphated
authored andcommitted
Breaking: Replace flag option with append option
1 parent d6a56d0 commit e739f6c

File tree

11 files changed

+187
-41
lines changed

11 files changed

+187
-41
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,14 @@ Type: `Boolean`
181181

182182
Default: `true` (always overwrite existing files)
183183

184+
##### `options.append`
185+
186+
Whether or not new data should be appended after existing file contents (if any).
187+
188+
Type: `Boolean`
189+
190+
Default: `false` (always replace existing contents, if any)
191+
184192
##### `options.sourcemaps`
185193

186194
Enables sourcemap support on files passed through the stream. Will write inline soucemaps if specified as `true`.

lib/dest/options.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,9 @@ var config = {
1818
type: 'boolean',
1919
default: true,
2020
},
21-
flag: {
22-
type: 'string',
23-
default: function(file) {
24-
var overwrite = this.resolve('overwrite', file);
25-
return (overwrite ? 'w': 'wx');
26-
},
21+
append: {
22+
type: 'boolean',
23+
default: false,
2724
},
2825
sourcemaps: {
2926
type: ['string', 'boolean'],

lib/dest/write-contents/index.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,11 @@ function writeContents(optResolver) {
4040
// This is invoked by the various writeXxx modules when they've finished
4141
// writing the contents.
4242
function onWritten(writeErr) {
43-
var flag = optResolver.resolve('flag', file);
44-
if (fo.isFatalOverwriteError(writeErr, flag)) {
43+
var flags = fo.getFlags({
44+
overwrite: optResolver.resolve('overwrite', file),
45+
append: optResolver.resolve('append', file),
46+
});
47+
if (fo.isFatalOverwriteError(writeErr, flags)) {
4548
return callback(writeErr);
4649
}
4750

lib/dest/write-contents/write-buffer.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@
33
var fo = require('../../file-operations');
44

55
function writeBuffer(file, optResolver, onWritten) {
6+
var flags = fo.getFlags({
7+
overwrite: optResolver.resolve('overwrite', file),
8+
append: optResolver.resolve('append', file),
9+
});
610
var opt = {
711
mode: file.stat.mode,
8-
flag: optResolver.resolve('flag', file),
12+
flags: flags,
913
};
1014

1115
fo.writeFile(file.path, file.contents, opt, onWriteFile);

lib/dest/write-contents/write-stream.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@ var fo = require('../../file-operations');
44
var readStream = require('../../src/read-contents/read-stream');
55

66
function writeStream(file, optResolver, onWritten) {
7+
var flags = fo.getFlags({
8+
overwrite: optResolver.resolve('overwrite', file),
9+
append: optResolver.resolve('append', file),
10+
});
711
var opt = {
812
mode: file.stat.mode,
9-
// TODO: need to test this (node calls this `flags` property)
10-
flag: optResolver.resolve('flag', file),
13+
// TODO: need to test this
14+
flags: flags,
1115
};
1216

1317
// TODO: is this the best API?

lib/dest/write-contents/write-symbolic-link.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ function writeSymbolicLink(file, optResolver, onWritten) {
1313
}
1414

1515
var isRelative = optResolver.resolve('relativeSymlinks', file);
16-
var flag = optResolver.resolve('flag', file);
16+
var flags = fo.getFlags({
17+
overwrite: optResolver.resolve('overwrite', file),
18+
append: optResolver.resolve('append', file),
19+
});
1720

1821
if (!isWindows) {
1922
// On non-Windows, just use 'file'
@@ -56,7 +59,7 @@ function writeSymbolicLink(file, optResolver, onWritten) {
5659
}
5760

5861
var opts = {
59-
flag: flag,
62+
flags: flags,
6063
type: type,
6164
};
6265
fo.symlink(file.symlink, file.path, opts, onSymlink);

lib/file-operations.js

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,20 @@ function isValidUnixId(id) {
3939
return true;
4040
}
4141

42-
function isFatalOverwriteError(err, flag) {
42+
function getFlags(options) {
43+
var flags = !options.append ? 'w' : 'a';
44+
if (!options.overwrite) {
45+
flags += 'x';
46+
}
47+
return flags;
48+
}
49+
50+
function isFatalOverwriteError(err, flags) {
4351
if (!err) {
4452
return false;
4553
}
4654

47-
if (err.code === 'EEXIST' && flag === 'wx') {
55+
if (err.code === 'EEXIST' && flags[1] === 'x') {
4856
// Handle scenario for file overwrite failures.
4957
return false;
5058
}
@@ -274,7 +282,7 @@ function updateMetadata(fd, file, callback) {
274282
function symlink(srcPath, destPath, opts, callback) {
275283
// Because fs.symlink does not allow atomic overwrite option with flags, we
276284
// delete and recreate if the link already exists and overwrite is true.
277-
if (opts.flag === 'w') {
285+
if (opts.flags === 'w') {
278286
// TODO What happens when we call unlink with windows junctions?
279287
fs.unlink(destPath, onUnlink);
280288
} else {
@@ -289,7 +297,7 @@ function symlink(srcPath, destPath, opts, callback) {
289297
}
290298

291299
function onSymlink(symlinkErr) {
292-
if (isFatalOverwriteError(symlinkErr, opts.flag)) {
300+
if (isFatalOverwriteError(symlinkErr, opts.flags)) {
293301
return callback(symlinkErr);
294302
}
295303
callback();
@@ -317,10 +325,10 @@ function writeFile(filepath, data, options, callback) {
317325

318326
// Default the same as node
319327
var mode = options.mode || constants.DEFAULT_FILE_MODE;
320-
var flag = options.flag || 'w';
321-
var position = APPEND_MODE_REGEXP.test(flag) ? null : 0;
328+
var flags = options.flags || 'w';
329+
var position = APPEND_MODE_REGEXP.test(flags) ? null : 0;
322330

323-
fs.open(filepath, flag, mode, onOpen);
331+
fs.open(filepath, flags, mode, onOpen);
324332

325333
function onOpen(openErr, fd) {
326334
if (openErr) {
@@ -357,7 +365,7 @@ function WriteStream(path, options, flush) {
357365
this.path = path;
358366

359367
this.mode = options.mode || constants.DEFAULT_FILE_MODE;
360-
this.flag = options.flag || 'w';
368+
this.flags = options.flags || 'w';
361369

362370
// Used by node's `fs.WriteStream`
363371
this.fd = null;
@@ -374,7 +382,7 @@ util.inherits(WriteStream, FlushWriteStream);
374382
WriteStream.prototype.open = function() {
375383
var self = this;
376384

377-
fs.open(this.path, this.flag, this.mode, onOpen);
385+
fs.open(this.path, this.flags, this.mode, onOpen);
378386

379387
function onOpen(openErr, fd) {
380388
if (openErr) {
@@ -435,6 +443,7 @@ function cleanup(callback) {
435443
module.exports = {
436444
closeFd: closeFd,
437445
isValidUnixId: isValidUnixId,
446+
getFlags: getFlags,
438447
isFatalOverwriteError: isFatalOverwriteError,
439448
isFatalUnlinkError: isFatalUnlinkError,
440449
getModeDiff: getModeDiff,

lib/symlink/link-file.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ function linkStream(optResolver) {
1313

1414
function linkFile(file, enc, callback) {
1515
var isRelative = optResolver.resolve('relativeSymlinks', file);
16-
var flag = optResolver.resolve('flag', file);
16+
var flags = fo.getFlags({
17+
overwrite: optResolver.resolve('overwrite', file),
18+
append: false,
19+
});
1720

1821
if (!isWindows) {
1922
// On non-Windows, just use 'file'
@@ -57,7 +60,7 @@ function linkStream(optResolver) {
5760
}
5861

5962
var opts = {
60-
flag: flag,
63+
flags: flags,
6164
type: type,
6265
};
6366
fo.symlink(file.symlink, file.path, opts, onSymlink);

lib/symlink/options.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,6 @@ var config = {
2121
type: 'boolean',
2222
default: true,
2323
},
24-
flag: {
25-
type: 'string',
26-
default: function(file) {
27-
var overwrite = this.resolve('overwrite', file);
28-
return (overwrite ? 'w': 'wx');
29-
},
30-
},
3124
};
3225

3326
module.exports = config;

test/dest.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,65 @@ describe('.dest()', function() {
606606
], done);
607607
});
608608

609+
it('appends content with append option set to true', function(done) {
610+
var existingContents = 'Lorem Ipsum';
611+
612+
var file = new File({
613+
base: inputBase,
614+
path: inputPath,
615+
contents: new Buffer(contents),
616+
});
617+
618+
function assert(files) {
619+
var outputContents = fs.readFileSync(outputPath, 'utf8');
620+
621+
expect(files.length).toEqual(1);
622+
expect(outputContents).toEqual(existingContents + contents);
623+
}
624+
625+
// This should be overwritten
626+
fs.mkdirSync(outputBase);
627+
fs.writeFileSync(outputPath, existingContents);
628+
629+
pipe([
630+
from.obj([file]),
631+
vfs.dest(outputBase, { append: true }),
632+
concat(assert),
633+
], done);
634+
});
635+
636+
it('appends content with append option set to a function that returns true', function(done) {
637+
var existingContents = 'Lorem Ipsum';
638+
639+
var file = new File({
640+
base: inputBase,
641+
path: inputPath,
642+
contents: new Buffer(contents),
643+
});
644+
645+
function append(f) {
646+
expect(f).toEqual(file);
647+
return true;
648+
}
649+
650+
function assert(files) {
651+
var outputContents = fs.readFileSync(outputPath, 'utf8');
652+
653+
expect(files.length).toEqual(1);
654+
expect(outputContents).toEqual(existingContents + contents);
655+
}
656+
657+
// This should be overwritten
658+
fs.mkdirSync(outputBase);
659+
fs.writeFileSync(outputPath, existingContents);
660+
661+
pipe([
662+
from.obj([file]),
663+
vfs.dest(outputBase, { append: append }),
664+
concat(assert),
665+
], done);
666+
});
667+
609668
it('emits a finish event', function(done) {
610669
var destStream = vfs.dest(outputBase);
611670

0 commit comments

Comments
 (0)