broccoli-caching-writer
Advanced tools
Comparing version 0.3.1 to 0.4.0
101
index.js
@@ -8,3 +8,3 @@ var fs = require('fs'); | ||
var Writer = require('broccoli-writer'); | ||
var helpers = require('broccoli-kitchen-sink-helpers') | ||
var helpers = require('broccoli-kitchen-sink-helpers'); | ||
@@ -22,17 +22,18 @@ CachingWriter.prototype = Object.create(Writer.prototype); | ||
if (options.hasOwnProperty(key)) { | ||
this[key] = options[key] | ||
this[key] = options[key]; | ||
} | ||
} | ||
this.canLink = testCanLink(); | ||
}; | ||
CachingWriter.prototype.getCacheDir = function () { | ||
return quickTemp.makeOrReuse(this, 'tmpCacheDir') | ||
} | ||
return quickTemp.makeOrReuse(this, 'tmpCacheDir'); | ||
}; | ||
CachingWriter.prototype.getCleanCacheDir = function () { | ||
return quickTemp.makeOrRemake(this, 'tmpCacheDir') | ||
} | ||
return quickTemp.makeOrRemake(this, 'tmpCacheDir'); | ||
}; | ||
CachingWriter.prototype.write = function (readTree, destDir) { | ||
var self = this | ||
var self = this; | ||
@@ -59,13 +60,13 @@ return readTree(this.inputTree).then(function (srcDir) { | ||
}); | ||
}) | ||
}); | ||
}; | ||
CachingWriter.prototype.cleanup = function () { | ||
quickTemp.remove(this, 'tmpCacheDir') | ||
Writer.prototype.cleanup.call(this) | ||
} | ||
quickTemp.remove(this, 'tmpCacheDir'); | ||
Writer.prototype.cleanup.call(this); | ||
}; | ||
CachingWriter.prototype.updateCache = function (srcDir, destDir) { | ||
throw new Error('You must implement updateCache.'); | ||
} | ||
}; | ||
@@ -91,3 +92,8 @@ module.exports = CachingWriter; | ||
mkdirp.sync(path.dirname(destFile)); | ||
fs.linkSync(srcFile, destFile); | ||
if (this.canLink) { | ||
fs.linkSync(srcFile, destFile); | ||
} | ||
else { | ||
fs.writeFileSync(destFile, fs.readFileSync(srcFile)); | ||
} | ||
} | ||
@@ -99,38 +105,38 @@ } | ||
var _stack = options._stack | ||
var _followSymlink = options._followSymlink | ||
var relativePath = options.relativePath || '.' | ||
var stats | ||
var statKeys | ||
var _stack = options._stack; | ||
var _followSymlink = options._followSymlink; | ||
var relativePath = options.relativePath || '.'; | ||
var stats; | ||
var statKeys; | ||
try { | ||
if (_followSymlink) { | ||
stats = fs.statSync(fullPath) | ||
stats = fs.statSync(fullPath); | ||
} else { | ||
stats = fs.lstatSync(fullPath) | ||
stats = fs.lstatSync(fullPath); | ||
} | ||
} catch (err) { | ||
console.warn('Warning: failed to stat ' + fullPath) | ||
console.warn('Warning: failed to stat ' + fullPath); | ||
// fullPath has probably ceased to exist. Leave `stats` undefined and | ||
// proceed hashing. | ||
} | ||
var childKeys = [] | ||
var childKeys = []; | ||
if (stats) { | ||
statKeys = ['stats', stats.mode, stats.size] | ||
statKeys = ['stats', stats.mode, stats.size]; | ||
} else { | ||
statKeys = ['stat failed'] | ||
statKeys = ['stat failed']; | ||
} | ||
if (stats && stats.isDirectory()) { | ||
var fileIdentity = stats.dev + '\x00' + stats.ino | ||
var fileIdentity = stats.dev + '\x00' + stats.ino; | ||
if (_stack != null && _stack.indexOf(fileIdentity) !== -1) { | ||
console.warn('Symlink directory loop detected at ' + fullPath + ' (note: loop detection may have false positives on Windows)') | ||
console.warn('Symlink directory loop detected at ' + fullPath + ' (note: loop detection may have false positives on Windows)'); | ||
} else { | ||
if (_stack != null) _stack = _stack.concat([fileIdentity]) | ||
var entries | ||
if (_stack != null) _stack = _stack.concat([fileIdentity]); | ||
var entries; | ||
try { | ||
entries = fs.readdirSync(fullPath).sort() | ||
entries = fs.readdirSync(fullPath).sort(); | ||
} catch (err) { | ||
console.warn('Warning: Failed to read directory ' + fullPath) | ||
console.warn(err.stack) | ||
childKeys = ['readdir failed'] | ||
console.warn('Warning: Failed to read directory ' + fullPath); | ||
console.warn(err.stack); | ||
childKeys = ['readdir failed']; | ||
// That's all there is to say about this directory. | ||
@@ -144,4 +150,4 @@ } | ||
relativePath: path.join(relativePath, entries[i]) | ||
}) | ||
childKeys = childKeys.concat(keys) | ||
}); | ||
childKeys = childKeys.concat(keys); | ||
} | ||
@@ -156,8 +162,8 @@ } | ||
// symlinks. | ||
_stack = [] | ||
_stack = []; | ||
} | ||
childKeys = keysForTree(fullPath, {_stack: _stack, relativePath: relativePath, _followSymlink: true}) // follow symlink | ||
statKeys.push(stats.mtime.getTime()) | ||
childKeys = keysForTree(fullPath, {_stack: _stack, relativePath: relativePath, _followSymlink: true}); // follow symlink | ||
statKeys.push(stats.mtime.getTime()); | ||
} else if (stats && stats.isFile()) { | ||
statKeys.push(stats.mtime.getTime()) | ||
statKeys.push(stats.mtime.getTime()); | ||
} | ||
@@ -168,3 +174,20 @@ | ||
.concat(statKeys) | ||
.concat(childKeys) | ||
.concat(childKeys); | ||
} | ||
function testCanLink () { | ||
var canLink = false; | ||
var canLinkSrc = path.join(__dirname, "canLinkSrc.tmp"); | ||
var canLinkDest = path.join(__dirname, "canLinkDest.tmp"); | ||
try { | ||
fs.writeFileSync(canLinkSrc) | ||
fs.linkSync(canLinkSrc, canLinkDest); | ||
canLink = true; | ||
} | ||
finally { | ||
fs.unlinkSync(canLinkDest); | ||
fs.unlinkSync(canLinkSrc); | ||
} | ||
return canLink; | ||
} |
{ | ||
"name": "broccoli-caching-writer", | ||
"version": "0.3.1", | ||
"version": "0.4.0", | ||
"description": "Broccoli plugin that allows simple caching (while still allowing N:N) based on the input tree hash.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -9,3 +9,3 @@ # Broccoli Caching Writer | ||
If you would prefer to preform your plugins work in a non-synchronous way, simply return a promise from `updateCache`. | ||
If you would prefer to perform your plugins work in a non-synchronous way, simply return a promise from `updateCache`. | ||
@@ -12,0 +12,0 @@ ## ZOMG!!! TESTS?!?!!? |
12071
280