Skip to content

Commit

Permalink
Write to temp outfile until success, fixes #899
Browse files Browse the repository at this point in the history
Write browserify command output to a temporary file, overwriting the target file atomically upon success (and simply cleaning up the tempfile on error).

This has two benefits:

* user won't be left with an empty file if compilation fails (which can break toolchains that rely on destination files/timestamps to indicate build status, Make or django-pipeline for just two examples)
* output file can never end up in a half-written state during even a successful compilation
  • Loading branch information
natevw authored Jan 6, 2017
1 parent 6efcd65 commit ea6c299
Showing 1 changed file with 14 additions and 1 deletion.
15 changes: 14 additions & 1 deletion bin/cmd.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,23 @@ if (b.argv.list) {

var bundle = b.bundle();
bundle.on('error', errorExit);
bundle.on('end', successExit);

var tmpfile;
var outfile = b.argv.o || b.argv.outfile;
if (outfile) {
bundle.pipe(fs.createWriteStream(outfile));
// we'll output to a temp file within same filesystem, then atomically overwrite outfile once successful
tmpfile = outfile + ".tmp-browserify-" + Math.random().toFixed(20).slice(2)
bundle.pipe(fs.createWriteStream(tmpfile));
}
else {
bundle.pipe(process.stdout);
}

function errorExit(err) {
if (tmpfile) fs.unlink(tmpfile, function (err) {
if (err) /* no-op, we're already exiting unhappily… */;
});
if (err.stack) {
console.error(err.stack);
}
Expand All @@ -72,3 +79,9 @@ function errorExit(err) {
}
process.exit(1);
}

function successExit() {
if (tmpfile && outfile) fs.rename(tmpfile, outfile, function (err) {
if (err) errorExit(err);
});
}

0 comments on commit ea6c299

Please sign in to comment.