Skip to content

Commit

Permalink
Use eco template for action. Pass {file} as context. closes #3
Browse files Browse the repository at this point in the history
For Dio.
  • Loading branch information
dfjones committed Jan 4, 2013
1 parent 4c8876f commit ccb234b
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 41 deletions.
23 changes: 20 additions & 3 deletions README.md
Expand Up @@ -3,9 +3,7 @@ Watchman


Simple utility that watches files/directories for changes and performs an action when they change. Inspired (and partially based on) the coffee-script compiler. Simple utility that watches files/directories for changes and performs an action when they change. Inspired (and partially based on) the coffee-script compiler.


I'm sure this is reinventing 100 other, better tools. Yes, I wrote it in coffee-script and NodeJS. Does that make me hip now?

Yes I wrote it in coffee-script and NodeJS. Does that make me hip now?


(Calm down, you don't need coffee-script to run it.) (Calm down, you don't need coffee-script to run it.)


Expand Down Expand Up @@ -55,8 +53,27 @@ Later after adding "newFile"...


Tue Apr 12 2011 23:08:36 - watching: test/newFile Tue Apr 12 2011 23:08:36 - watching: test/newFile


Even better, the action is an [eco](https://github.com/sstephenson/eco) template!

./watchman test "echo 'The file <%= @file %> changed!'"
Thu Jan 03 2013 22:47:35 - watching directory: test
Thu Jan 03 2013 22:47:35 - watching: test/foo
Thu Jan 03 2013 22:48:17 - Running action...
Thu Jan 03 2013 22:48:17 - stderr:
Thu Jan 03 2013 22:48:17 - stdout: The file test/foo changed

By default, Watchman will perform the action immediately upon running. To prevent this, pass -w as an option. By default, Watchman will perform the action immediately upon running. To prevent this, pass -w as an option.


About Actions
-------------

The action you specify will be exec'ed in a shell with the same working directory as watchman. The action string is actually a template
for [eco](https://github.com/sstephenson/eco). Currently, the context provided to the action template is simply:
```
{file: '/file/that/changed'}
```


Install Install
-------- --------


Expand Down
5 changes: 3 additions & 2 deletions package.json
@@ -1,6 +1,6 @@
{ "name": "watchman", { "name": "watchman",
"description": "A simple utility to watch files/directories and perform an action when they change.", "description": "A simple utility to watch files/directories and perform an action when they change.",
"version": "0.1.6", "version": "0.1.7",
"homepage": "http://github.com/dfjones/watchman", "homepage": "http://github.com/dfjones/watchman",
"keywords": ["file", "filesystem", "change", "command line"], "keywords": ["file", "filesystem", "change", "command line"],
"author": "Doug Jones <doug@dfjones.net>", "author": "Doug Jones <doug@dfjones.net>",
Expand All @@ -17,6 +17,7 @@
}, },
"engines": { "node": ">= 0.4.0" }, "engines": { "node": ">= 0.4.0" },
"dependencies": { "dependencies": {
"cli": ">= 0.2.8" "cli": ">= 0.2.8",
"eco": ">= 1.1.0"
} }
} }
34 changes: 21 additions & 13 deletions watchman
@@ -1,10 +1,12 @@
#!/usr/bin/env node #!/usr/bin/env node
// Generated by CoffeeScript 1.4.0 // Generated by CoffeeScript 1.4.0
(function() { (function() {
var cli, exec, fs, getFormattedDate, log, path; var cli, eco, exec, fs, getFormattedDate, log, path;


cli = require('cli'); cli = require('cli');


eco = require('eco');

fs = require('fs'); fs = require('fs');


path = require('path'); path = require('path');
Expand Down Expand Up @@ -35,7 +37,7 @@
}; };


cli.main(function(args, options) { cli.main(function(args, options) {
var action, actionQueue, directoryWatcher, execAction, execFromQueue, find_files, queueAction, rate, rateMap, target, testHidden, useQueue, watched, watcher; var action, actionQueue, directoryWatcher, execAction, execFromQueue, find_files, onFileChange, queueAction, rate, rateMap, target, testHidden, useQueue, watched, watcher;
if (args.length < 2) { if (args.length < 2) {
console.log("Please specify a target and action"); console.log("Please specify a target and action");
return; return;
Expand All @@ -50,29 +52,40 @@
watched = {}; watched = {};
useQueue = false; useQueue = false;
actionQueue = []; actionQueue = [];
queueAction = function() { queueAction = function(action, file) {
if (actionQueue.length < options["queue"]) { if (actionQueue.length < options["queue"]) {
return actionQueue.push(action); return actionQueue.push([action, file]);
} }
}; };
execFromQueue = function() { execFromQueue = function() {
var a, _i, _len; var a, _i, _len;
for (_i = 0, _len = actionQueue.length; _i < _len; _i++) { for (_i = 0, _len = actionQueue.length; _i < _len; _i++) {
a = actionQueue[_i]; a = actionQueue[_i];
execAction(a); execAction(a[0], a[1]);
} }
return actionQueue = []; return actionQueue = [];
}; };
execAction = function(toExec) { execAction = function(toExec, file) {
if (toExec == null) { if (toExec == null) {
toExec = action; toExec = action;
} }
toExec = eco.render(toExec, {
file: file
});
log("Running action..."); log("Running action...");
return exec(toExec, function(error, stdout, stderr) { return exec(toExec, function(error, stdout, stderr) {
log("stderr: " + stderr); log("stderr: " + stderr);
return log("stdout: " + stdout); return log("stdout: " + stdout);
}); });
}; };
onFileChange = function(file) {
log("File changed: " + file);
if (useQueue) {
return queueAction(action, file);
} else {
return execAction(action, file);
}
};
watcher = function(file) { watcher = function(file) {
if (file in watched) { if (file in watched) {
return; return;
Expand All @@ -86,12 +99,7 @@
if (curr.size === prev.size && curr.mtime.getTime() === prev.mtime.getTime()) { if (curr.size === prev.size && curr.mtime.getTime() === prev.mtime.getTime()) {
return; return;
} }
log("File changed: " + file); return onFileChange(file);
if (useQueue) {
return queueAction();
} else {
return execAction();
}
}); });
}; };
directoryWatcher = function(dir) { directoryWatcher = function(dir) {
Expand Down Expand Up @@ -126,7 +134,7 @@
setInterval(execFromQueue, rate); setInterval(execFromQueue, rate);
} }
find_files = function(target, quiet) { find_files = function(target, quiet) {
return path.exists(target, function(exists) { return fs.exists(target, function(exists) {
if (!quiet && !exists) { if (!quiet && !exists) {
throw "Target file not found: " + target; throw "Target file not found: " + target;
} }
Expand Down
25 changes: 15 additions & 10 deletions watchman.coffee
@@ -1,6 +1,7 @@
#!/usr/bin/env coffee #!/usr/bin/env coffee


cli = require 'cli' cli = require 'cli'
eco = require 'eco'
fs = require 'fs' fs = require 'fs'
path = require 'path' path = require 'path'
exec = require 'child_process' exec = require 'child_process'
Expand Down Expand Up @@ -42,33 +43,37 @@ cli.main (args, options) ->
useQueue = false useQueue = false
actionQueue = [] actionQueue = []


queueAction = -> queueAction = (action, file) ->
if actionQueue.length < options["queue"] if actionQueue.length < options["queue"]
actionQueue.push(action) actionQueue.push([action, file])


execFromQueue = -> execFromQueue = ->
for a in actionQueue for a in actionQueue
execAction(a) execAction(a[0], a[1])
actionQueue = [] actionQueue = []


execAction = (toExec) -> execAction = (toExec, file) ->
toExec ?= action toExec ?= action
toExec = eco.render(toExec, {file})
log("Running action...") log("Running action...")
exec toExec, (error, stdout, stderr) -> exec toExec, (error, stdout, stderr) ->
log("stderr: " + stderr) log("stderr: " + stderr)
log("stdout: " + stdout) log("stdout: " + stdout)


onFileChange = (file) ->
log("File changed: " + file)
if useQueue
queueAction(action, file)
else
execAction(action, file)

watcher = (file) -> watcher = (file) ->
return if file of watched return if file of watched
watched[file] = true watched[file] = true
log("watching: #{file}") log("watching: #{file}")
fs.watchFile file, {persistent: true, interval: 500}, (curr, prev) -> fs.watchFile file, {persistent: true, interval: 500}, (curr, prev) ->
return if curr.size is prev.size and curr.mtime.getTime() is prev.mtime.getTime() return if curr.size is prev.size and curr.mtime.getTime() is prev.mtime.getTime()
log("File changed: " + file) onFileChange(file)
if useQueue
queueAction()
else
execAction()


directoryWatcher = (dir) -> directoryWatcher = (dir) ->
return if dir of watched return if dir of watched
Expand All @@ -93,7 +98,7 @@ cli.main (args, options) ->
setInterval(execFromQueue, rate) setInterval(execFromQueue, rate)


find_files = (target, quiet) -> find_files = (target, quiet) ->
path.exists target, (exists) -> fs.exists target, (exists) ->
throw "Target file not found: #{target}" if not quiet and not exists throw "Target file not found: #{target}" if not quiet and not exists
fs.stat target, (err, stats) -> fs.stat target, (err, stats) ->
if err? if err?
Expand Down
34 changes: 21 additions & 13 deletions watchman.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit ccb234b

Please sign in to comment.