Permalink
Browse files

Fix 0.7 compat, use fs.watch, make snockets-built files play nice wit…

…h watching
  • Loading branch information...
1 parent 3b61a62 commit 07a4a8d35ef60045b264e73a822a7a57b69b0502 @airhorns committed May 14, 2012
Showing with 65 additions and 35 deletions.
  1. +2 −0 Cakefile
  2. +37 −21 lib/muffin.js
  3. +1 −1 package.json
  4. +25 −13 src/muffin.coffee
View
2 Cakefile
@@ -22,3 +22,5 @@ task 'doc', 'autogenerate docco anotated source and node IDL files', (options) -
options: options
map:
'src/muffin.coffee' : (matches) -> muffin.doccoFile(matches[0], options)
+
+task 'test', ->
View
58 lib/muffin.js
@@ -1,5 +1,5 @@
(function() {
- var CoffeeScript, Snockets, ask, clocFile, clocPath, compileMap, compileScript, compileString, compileTree, copyFile, doccoFile, ensurePerl, exec, extend, fs, getGitRoot, glob, growlAvailable, growlCheckPromise, growlCommand, growlImagePath, handleFileError, inRebase, k, langDefPath, minifyScript, mkdir_p, notify, ofs, orgExec, path, perlError, perlPresent, printTable, q, readFile, run, runOptions, snockets, spawn, statFile, statFiles, temp, v, writeFile, _, _ref, _ref1, _ref2, _statFiles,
+ var CoffeeScript, Snockets, addWatchDependency, ask, clocFile, clocPath, compileMap, compileScript, compileString, compileTree, copyFile, doccoFile, ensurePerl, exec, extend, fs, getGitRoot, glob, growlAvailable, growlCheckPromise, growlCommand, growlImagePath, handleFileError, inRebase, k, langDefPath, minifyScript, mkdir_p, muffin, notify, ofs, orgExec, path, perlError, perlPresent, printTable, q, readFile, run, runOptions, snockets, spawn, statFile, statFiles, temp, v, writeFile, _, _ref, _ref1, _ref2, _statFiles,
__slice = [].slice;
CoffeeScript = require('coffee-script');
@@ -22,6 +22,8 @@
orgExec = exec;
+ muffin = exports;
+
extend = function() {
var k, o, onto, others, result, v, _i, _len;
onto = arguments[0], others = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
@@ -53,7 +55,7 @@
};
inRebase = function() {
- return fs.existsSync('.git/rebase-apply');
+ return (fs.existsSync ? fs.existsSync : path.existsSync)('.git/rebase-apply');
};
ask = function(question, format) {
@@ -275,11 +277,19 @@
snockets = new Snockets;
compileTree = function(root, target, options) {
- var compilation;
+ var compilation, depGraph, file, _i, _len, _ref1;
if (options == null) {
options = {};
}
compilation = q.defer();
+ depGraph = snockets.scan(root, {
+ async: false
+ });
+ _ref1 = depGraph.getChain(root);
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
+ file = _ref1[_i];
+ muffin.addWatchDependency(file);
+ }
snockets.getConcatenation(root, {
minify: false,
async: false
@@ -618,6 +628,13 @@
}
};
+ addWatchDependency = function(file) {
+ if (!muffin._watchDependencies) {
+ return;
+ }
+ muffin._watchDependencies.push(file);
+ };
+
compileMap = function(map) {
var action, pattern, _results;
_results = [];
@@ -653,28 +670,26 @@
var actionPromises;
actionPromises = [];
compiledMap.forEach(function(map) {
- var file, i, matches, _ref2, _results;
+ var file, i, matches, _fn, _i, _len, _ref2, _ref3;
+ muffin._watchDependencies = [];
_ref2 = args.files;
- _results = [];
for (i in _ref2) {
file = _ref2[i];
if (matches = map.pattern.exec(file)) {
delete args.files[i];
actionPromises.push(map.action(matches));
+ muffin._watchDependencies.push(file);
if (args.options.watch) {
if (args.options.commit) {
console.error("Can't watch committed versions of files, sorry!");
process.exit(1);
}
- _results.push((function(map, matches) {
- return ofs.watchFile(file, {
- persistent: true,
- interval: 250
- }, function(curr, prev) {
- if (curr.mtime.getTime() === prev.mtime.getTime()) {
- return;
- }
- if (inRebase()) {
+ _ref3 = muffin._watchDependencies;
+ _fn = function(map, matches, file) {
+ return ofs.watch(file, {
+ persistent: true
+ }, function(event) {
+ if (event !== 'change' || inRebase()) {
return;
}
return q.call(before).then(function() {
@@ -685,15 +700,15 @@
}
}).end();
});
- })(map, matches));
- } else {
- _results.push(void 0);
+ };
+ for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
+ file = _ref3[_i];
+ _fn(map, matches, file);
+ }
}
- } else {
- _results.push(void 0);
}
}
- return _results;
+ return delete muffin._watchDependencies;
});
return q.all(actionPromises).then(function() {
if (args.after) {
@@ -717,7 +732,8 @@
exec: exec,
extend: extend,
statFiles: statFiles,
- mkdir_p: mkdir_p
+ mkdir_p: mkdir_p,
+ addWatchDependency: addWatchDependency
};
for (k in _ref2) {
v = _ref2[k];
View
2 package.json
@@ -13,7 +13,7 @@
"test": "cake test"
},
"engines": {
- "node": "0.4.x || 0.6.x || 0.7.x"
+ "node": "0.6.x || 0.7.x"
},
"dependencies": {
"q": "~>0.8",
View
38 src/muffin.coffee
@@ -17,6 +17,7 @@ Snockets = require 'snockets'
{spawn, exec} = require 'child_process'
orgExec = exec
+muffin = exports
# Simple variadic extend
extend = (onto, others...) ->
@@ -42,7 +43,7 @@ exec = (command, options = {}) ->
# Internal helper function for deciding if the repo is in the midst of a rebase.
inRebase = ->
- fs.existsSync('.git/rebase-apply')
+ (if fs.existsSync then fs.existsSync else path.existsSync)('.git/rebase-apply')
ask = (question, format = /.+/) ->
stdin = process.stdin
@@ -212,6 +213,9 @@ compileScript = (source, target, options = {}) ->
snockets = new Snockets
compileTree = (root, target, options = {}) ->
compilation = q.defer()
+ # Do synchronous snocketing for now because there are race conditions within snockets which result in bad dep graphs. Pout.
+ depGraph = snockets.scan root, {async: false}
+ muffin.addWatchDependency file for file in depGraph.getChain(root)
snockets.getConcatenation root, {minify: false, async: false}, compilation.node()
compilation.promise.then (returns) ->
@@ -265,16 +269,16 @@ minifyScript = (source, options = {}) ->
return writeFile(finalPath.join('.'), final, options).then(-> final)
# Internal function for finding the git root
-getGitRoot = () ->
+getGitRoot = ->
[child, promise] = exec 'git rev-parse --show-toplevel'
child.stdin.end()
promise.then ([stdout, stderr]) ->
stdout.toString().trim()
# Internal tracking variable and function used for asserting that Perl exists on the system muffin is being run on.
perlPresent = undefined
-perlError = () -> throw 'You need a perl v5.3 or higher installed to do this with muffin.'
-ensurePerl = () ->
+perlError = -> throw 'You need a perl v5.3 or higher installed to do this with muffin.'
+ensurePerl = ->
if perlPresent?
perlError() unless perlPresent
else
@@ -464,6 +468,11 @@ statFiles = (files, options = {}) ->
printTable(fields, results)
).end()
+addWatchDependency = (file) ->
+ return unless muffin._watchDependencies
+ muffin._watchDependencies.push file
+ return
+
# `compileMap` is an internal helper for taking the passed in options to `muffin.run` and turning strings
# into useful objects.
compileMap = (map) ->
@@ -495,30 +504,33 @@ run = (args) ->
# match any of the files in the array. If so, delete the file, and run the action.
actionPromises = []
compiledMap.forEach (map) ->
+ muffin._watchDependencies = []
for i, file of args.files
if matches = map.pattern.exec(file)
delete args.files[i]
actionPromises.push map.action(matches)
+ muffin._watchDependencies.push file
# Watch the file if the option was given.
if args.options.watch
if args.options.commit
console.error("Can't watch committed versions of files, sorry!")
process.exit(1)
- do (map, matches) ->
- ofs.watchFile file, persistent: true, interval: 250, (curr, prev) ->
- return if curr.mtime.getTime() is prev.mtime.getTime()
- return if inRebase()
- q.call(before)
- .then(-> map.action(matches))
- .then((result) -> args.after() if args.after)
- .end()
+ for file in muffin._watchDependencies
+ do (map, matches, file) ->
+ ofs.watch file, persistent: true, (event) ->
+ return if event != 'change' || inRebase()
+ q.call(before)
+ .then(-> map.action(matches))
+ .then((result) -> args.after() if args.after)
+ .end()
+ delete muffin._watchDependencies
q.all(actionPromises).then(->
args.after() if args.after
)
).end()
-for k, v of {run, copyFile, doccoFile, notify, minifyScript, readFile, writeFile, compileString, compileScript, compileTree, exec, extend, statFiles, mkdir_p}
+for k, v of {run, copyFile, doccoFile, notify, minifyScript, readFile, writeFile, compileString, compileScript, compileTree, exec, extend, statFiles, mkdir_p, addWatchDependency}
exports[k] = v

0 comments on commit 07a4a8d

Please sign in to comment.