Comparing version 0.11.0 to 0.12.0
# master | ||
# 0.12.0 | ||
* Add `willReadStringTree` callback argument to `Builder::build` and retire | ||
`Builder::treesRead` | ||
* Update `Watcher` and `Builder` interaction to prevent double builds. | ||
* Avoid unhandled rejected promise | ||
* Fix trailing slash handling in server on Windows | ||
# 0.11.0 | ||
@@ -4,0 +12,0 @@ |
@@ -5,2 +5,5 @@ # Broccoli: Potential Data Loss On OS X | ||
**Update May 4, 2014: All affected package versions have been removed from | ||
npm. The original document is preserved below for posterity.** | ||
There is an issue in Broccoli and several helper libraries that can cause data | ||
@@ -7,0 +10,0 @@ loss on Mac OS X, stemming from their use of hardlinks. |
@@ -9,7 +9,6 @@ var path = require('path') | ||
this.tree = tree | ||
this.treesRead = [] // last build | ||
this.allTreesRead = [] // across all builds | ||
} | ||
Builder.prototype.build = function () { | ||
Builder.prototype.build = function (willReadStringTree) { | ||
var self = this | ||
@@ -25,12 +24,3 @@ | ||
.then(function (node) { | ||
self.treesRead = newTreesRead | ||
return { directory: node.directory, graph: node, totalTime: node.totalTime } | ||
}, function (err) { | ||
// self.treesRead is used by the watcher. Do not stop watching | ||
// directories if the build errors in the middle, or we get double | ||
// rebuilds. | ||
if (newTreesRead.length > self.treesRead.length) { | ||
self.treesRead = newTreesRead | ||
} | ||
throw err | ||
}) | ||
@@ -76,3 +66,7 @@ .finally(function () { | ||
if (typeof tree === 'string') { | ||
treeDirPromise = Promise.resolve(tree) | ||
treeDirPromise = Promise.resolve() | ||
.then(function () { | ||
if (willReadStringTree) willReadStringTree(tree) | ||
return tree | ||
}) | ||
} else if (!tree || typeof tree.read !== 'function') { | ||
@@ -79,0 +73,0 @@ throw new Error('Invalid tree found. You must supply a path or an object with a `read` function.'); |
@@ -14,4 +14,4 @@ var path = require('path') | ||
var directory = path.normalize(hash.directory) | ||
var pathname = url.parse(request.url).pathname | ||
var filename = path.normalize(path.join(directory, decodeURIComponent(pathname))) | ||
var urlObj = url.parse(request.url) | ||
var filename = path.join(directory, decodeURIComponent(urlObj.pathname)) | ||
var stat, lastModified, type, charset, buffer | ||
@@ -29,4 +29,4 @@ | ||
// handle document index | ||
if (filename[filename.length - 1] === '/') { | ||
filename = path.join(filename, 'index.html') | ||
if (filename[filename.length - 1] === path.sep) { | ||
filename += 'index.html' | ||
} | ||
@@ -44,3 +44,4 @@ | ||
if (stat.isDirectory()) { | ||
response.setHeader('Location', pathname + '/') | ||
urlObj.pathname += '/' | ||
response.setHeader('Location', url.format(urlObj)) | ||
response.writeHead(301) | ||
@@ -47,0 +48,0 @@ response.end() |
@@ -46,3 +46,3 @@ var Watcher = require('./watcher') | ||
watcher.on('change', function(results) { | ||
console.log('Built - ' + Math.round(results.graph.totalTime / 1e6) + ' ms') | ||
console.log('Built - ' + Math.round(results.totalTime / 1e6) + ' ms') | ||
liveReload() | ||
@@ -49,0 +49,0 @@ }) |
@@ -11,2 +11,4 @@ var EventEmitter = require('events').EventEmitter | ||
this.options = options || {} | ||
this.watchedDirs = {} | ||
this.check() | ||
@@ -18,11 +20,29 @@ } | ||
Watcher.prototype.addWatchDir = function (path) { | ||
this.watchedDirs[path] = helpers.hashTree(path) | ||
} | ||
Watcher.prototype.detectChanges = function () { | ||
var changedDirs = []; | ||
for (var dir in this.watchedDirs) { | ||
if (this.watchedDirs.hasOwnProperty(dir)) { | ||
var currentHash = helpers.hashTree(dir) | ||
if (this.watchedDirs[dir] !== currentHash) { | ||
changedDirs.push(dir) | ||
} | ||
} | ||
} | ||
return changedDirs; | ||
} | ||
Watcher.prototype.check = function() { | ||
try { | ||
var interval = this.options.interval || 100 | ||
var newStatsHash = this.builder.treesRead.map(function (tree) { | ||
return typeof tree === 'string' ? helpers.hashTree(tree) : '' | ||
}).join('\x00') | ||
if (newStatsHash !== this.statsHash) { | ||
this.statsHash = newStatsHash | ||
this.current = this.builder.build() | ||
var changedDirs = this.detectChanges(); | ||
if (Object.keys(this.watchedDirs).length === 0 || changedDirs.length > 0) { | ||
this.watchedDirs = {} | ||
this.current = this.builder.build(this.addWatchDir.bind(this)) | ||
this.current.then(function(hash) { | ||
@@ -35,3 +55,2 @@ if (this.options.verbose) { | ||
this.emit('error', error) | ||
throw error | ||
}.bind(this)).finally(this.check.bind(this)) | ||
@@ -38,0 +57,0 @@ } else { |
{ | ||
"name": "broccoli", | ||
"description": "Fast client-side asset builder", | ||
"version": "0.11.0", | ||
"version": "0.12.0", | ||
"author": "Jo Liss <joliss42@gmail.com>", | ||
@@ -6,0 +6,0 @@ "main": "lib/index.js", |
@@ -7,6 +7,2 @@ # Broccoli | ||
*Note April 7, 2014: There was a recent <strong>data loss</strong> issue on OS X in | ||
Broccoli and several plugins. [Check to see if you're | ||
affected.](https://github.com/broccolijs/broccoli/blob/master/docs/hardlink-issue.md)* | ||
A fast, reliable asset pipeline, supporting constant-time rebuilds and compact | ||
@@ -60,2 +56,3 @@ build definitions. Comparable to the Rails asset pipeline in scope, though it | ||
* [broccoli-absurd-filter](https://github.com/Xulai/broccoli-absurd-filter) | ||
* [broccoli-autoprefixer](https://github.com/sindresorhus/broccoli-autoprefixer) | ||
@@ -81,6 +78,9 @@ * [broccoli-bake-handlebars](https://github.com/thomasboyt/broccoli-bake-handlebars) | ||
* [broccoli-jstransform](https://github.com/aexmachina/broccoli-jstransform) | ||
* [broccoli-merge-trees](https://github.com/broccolijs/broccoli-merge-trees) | ||
* [broccoli-nunjucks](https://github.com/sindresorhus/broccoli-nunjucks) | ||
* [broccoli-regenerator](https://github.com/sindresorhus/broccoli-regenerator) | ||
* [broccoli-replace](https://github.com/outaTiME/broccoli-replace) | ||
* [broccoli-rev](https://github.com/mjijackson/broccoli-rev) | ||
* [broccoli-sass](https://github.com/joliss/broccoli-sass) | ||
* [broccoli-select](https://github.com/mjijackson/broccoli-select) | ||
* [broccoli-static-compiler](https://github.com/joliss/broccoli-static-compiler) | ||
@@ -153,2 +153,21 @@ * [broccoli-strip-debug](https://github.com/sindresorhus/broccoli-strip-debug) | ||
### Debugging | ||
#### Errors | ||
When it is know which file caused a given error, plugin authors can make errors | ||
easier to track down by setting the `.file` property on the generated error. | ||
This `.file` property is used by both the console logging, and the server middleware | ||
to display more helpful error messages. | ||
#### Descriptive Naming | ||
As of 0.11 Broccoli prints a log of any trees that took a significant amount of the total | ||
build time to assist in finding which trees are consuming the largest build times. | ||
To determine the name to be printed Broccoli will first look for a `.description` | ||
property on the plugin instance then fall back to using the plugin constructor's name. | ||
## Security | ||
@@ -155,0 +174,0 @@ |
@@ -114,3 +114,9 @@ var test = require('tap').test | ||
t.equal(typeof a, 'number') | ||
t.ok(a >= b - 5e6 && a <= b + 5e6, 'Wanted ' + b + ' +/- 5e6, found ' + a) | ||
// do not run timing assertions in Travis builds | ||
// the actual results of process.hrtime() are not | ||
// reliable | ||
if (process.env.CI !== 'true') { | ||
t.ok(a >= b - 5e6 && a <= b + 5e6, 'Wanted ' + b + ' +/- 5e6, found ' + a) | ||
} | ||
} | ||
@@ -143,3 +149,11 @@ | ||
test('string tree callback', function (t) { | ||
var builder = new Builder('fooDir') | ||
builder.build(function willReadStringTree (dir) { | ||
t.equal(dir, 'fooDir') | ||
t.end() | ||
}) | ||
}) | ||
t.end() | ||
}) |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
412629
619
191
4