From ec093b0b70d18c833c1e5f31176f79f85a072a6b Mon Sep 17 00:00:00 2001 From: Remy Sharp Date: Fri, 21 Feb 2014 14:01:57 +0000 Subject: [PATCH] Don't destroy existing outputPath on fail Compile writes out to os.tmpdir, and if successful, it then moves the directory to the user defined output path and cleans up after itself. This allows for a compile to fail, but won't blow away the existing directory. I was using Harp for our dev and was thrown off by it destroying the contents of www when it errored. So I fixed that. Hopefully useful to others and PR-mergable. --- lib/index.js | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/lib/index.js b/lib/index.js index 47ff6b49..278cbbea 100644 --- a/lib/index.js +++ b/lib/index.js @@ -11,6 +11,7 @@ var async = require("async") var connect = require("connect") var middleware = require("./middleware") var mime = require('mime') +var tmp = require("os").tmpdir() /** @@ -160,17 +161,37 @@ exports.compile = function(projectPath, outputPath, callback){ outputPath = "www" } + // harp will write the project out here first, and if successul, it'll get + // moved across to the real outputPath - to allow for compile to fail, without + // blowing away the previous version. + var tmpOutputPath = path.join(tmp, "www" + (Math.random() * 1000 | 0)) + outputPath = path.resolve(projectPath, outputPath) + + // if the compile was successful, move across the outputPath then call callback + var complete = function (err, config) { + if (!err) { + fs.copy(tmpOutputPath, outputPath, function () { + fs.remove(tmpOutputPath, function () { + callback(err, config) + }) + }) + } else { + // blow away the old directory + fs.remove(tmpOutputPath, function () { + callback(err, config) + }) + } + } /** * Setup all the paths and collect all the data */ try{ - outputPath = path.resolve(projectPath, outputPath) var setup = helpers.setup(projectPath, "production") var poly = polymer.root(setup.publicPath, setup.config.globals) }catch(err){ - return callback(err) + return complete(err) } @@ -180,7 +201,7 @@ exports.compile = function(projectPath, outputPath, callback){ */ if(!helpers.willAllow(projectPath, outputPath)){ - return callback({ + return complete({ type: "Invalid Output Path", message: "Output path cannot be greater then one level up from project path and must be in directory starting with `_` (underscore).", projectPath: projectPath, @@ -199,7 +220,7 @@ exports.compile = function(projectPath, outputPath, callback){ done(error) }else{ if(body){ - var dest = path.resolve(outputPath, polymer.helpers.outputPath(file)) + var dest = path.resolve(tmpOutputPath, polymer.helpers.outputPath(file)) fs.mkdirp(path.dirname(dest), function(err){ fs.writeFile(dest, body, done) }) @@ -220,7 +241,7 @@ exports.compile = function(projectPath, outputPath, callback){ var copyFile = function(file, done){ var ext = path.extname(file) if(!polymer.helpers.shouldIgnore(file) && [".jade", ".ejs", ".md", ".styl", ".less", ".scss", ".coffee"].indexOf(ext) === -1){ - var localPath = path.resolve(outputPath, file) + var localPath = path.resolve(tmpOutputPath, file) fs.mkdirp(path.dirname(localPath), function(err){ fs.copy(path.resolve(setup.publicPath, file), localPath, done) }) @@ -233,18 +254,18 @@ exports.compile = function(projectPath, outputPath, callback){ * Scan dir, Compile Less and Jade, Copy the others */ - helpers.prime(outputPath, { ignore: projectPath }, function(err){ + helpers.prime(tmpOutputPath, { ignore: projectPath }, function(err){ if(err) console.log(err) helpers.ls(setup.publicPath, function(err, results){ async.eachLimit(results, 72, compileFile, function(err){ if(err){ - callback(err) + complete(err) }else{ async.eachLimit(results, 72, copyFile, function(err){ setup.config['harp_version'] = pkg.version delete setup.config.globals - callback(null, setup.config) + complete(null, setup.config) }) } })