Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: timoxley/sentry
base: master
...
head fork: rolandpoulter/sentry
compare: master
Checking mergeability… Don't worry, you can still create the pull request.
  • 6 commits
  • 25 files changed
  • 0 commit comments
  • 2 contributors
Showing with 499 additions and 355 deletions.
  1. +3 −2 .gitignore
  2. +0 −11 Cakefile
  3. +1 −1  LICENSE
  4. +35 −35 README.md
  5. +12 −26 package.json
  6. +266 −0 sentry.js
  7. +0 −8 spec/helpers/spec_helper.coffee
  8. +0 −170 spec/sentry_spec.coffee
  9. +0 −102 src/sentry.coffee
  10. 0  {spec/fixtures/wildcard → test/fixtures}/bar.js
  11. 0  {spec/fixtures/string → test/fixtures/deepwildcard}/bar.js
  12. 0  spec/fixtures/wildcard/qux.js → test/fixtures/deepwildcard/deep/baz.json
  13. 0  {spec/fixtures/wildcard → test/fixtures/deepwildcard/deep}/foo.js
  14. 0  {spec → test}/fixtures/deepwildcard/deep/qux.js
  15. 0  {spec → test}/fixtures/regex/bar.js
  16. 0  {spec/fixtures/string → test/fixtures/regex/deep}/foo.js
  17. 0  {spec → test}/fixtures/regex/deep/foo.txt
  18. 0  {spec/fixtures/deepwildcard → test/fixtures/string}/bar.js
  19. 0  {spec → test}/fixtures/string/baz.js
  20. 0  {spec/fixtures/regex/deep → test/fixtures/string}/foo.js
  21. 0  {spec/fixtures → test/fixtures/wildcard}/bar.js
  22. 0  spec/fixtures/wildcard/baz.coffee → test/fixtures/wildcard/baz.json
  23. 0  {spec/fixtures/deepwildcard/deep → test/fixtures/wildcard}/foo.js
  24. 0  spec/fixtures/deepwildcard/deep/baz.coffee → test/fixtures/wildcard/qux.js
  25. +182 −0 test/sentry_test.js
View
5 .gitignore
@@ -1,4 +1,5 @@
.DS_Store
*~
-/node_modules/
-/lib/
+node_modules/
+.c9revisions
+.settings
View
11 Cakefile
@@ -1,11 +0,0 @@
-exec = require('child_process').exec
-
-task 'build', 'src/ --> lib/', ->
- exec 'coffee -co lib src', (err, stdout, stderr) ->
- if err
- console.log stdout
- console.log stderr
- throw new Error "Error while compiling .coffee to .js"
-
-task 'stub', 'A stub task for testing running a child process', ->
- console.log '\nRunning stub task...'
View
2  LICENSE
@@ -1,6 +1,6 @@
(The MIT License)
-Copyright (c) Craig Spaeth <craigspaeth@gmail.com>, Art.sy, 2011
+Copyright (c) Craig Spaeth <craigspaeth@gmail.com>, Art.sy, 2011; (c) Roland Poulter, NaN
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
View
70 README.md
@@ -4,27 +4,29 @@ Sentry is a simple node tool to watch for file changes (using a path, wildcards,
## Installation
- $ npm install sentry
+ $ npm install sentry2
## Example
-````coffeescript
-sentry = require 'sentry'
+````javascript
+var sentry = require('sentry2');
-# Watch changes in file.js
-sentry.watch 'file.js', (filename) -> console.log "A change has been made in #{file}"
+// Watch changes in file.js
+sentry.watch('file.js', function (error, filename) {
+ console.log("A change has been made in " + filename);
+});
-# Watch changes on any file ending in .coffee one directory deep
-sentry.watch 'fld/*.coffee', ->
+// Watch changes on any file ending in .coffee one directory deep
+sentry.watch('fld/*.coffee', callback);
-# Watch changes recursively on any files
-sentry.watch 'fld/**/*', ->
+// Watch changes recursively on any files
+sentry.watch('fld/**/*', callback);
-# Watch files recursively that match a regex
-sentry.watchRegExp 'fld/', /regex/, ->
+// Watch files recursively that match a regex
+sentry.watchRegExp('fld/', /regex/, callback);
-# If you pass a string instead of a function it'll execute that child process
-sentry.watch 'file.coffee', 'coffee -c'
+// If you pass a string instead of a function it'll execute that child process
+sentry.watch('file.coffee', 'coffee -c');
````
## API
@@ -33,50 +35,48 @@ Sentry comes with two methods `watch` and `watchRegExp`.
### sentry.watch(filePath, [task], callback)
-When running a child process you may optionally pass a callback with the arguments `(err, stdout, stderr)`
+When running a child process you may optionally pass a callback with the arguments `(error, filename, stdout, stderr)`
-````coffeescript
-sentry.watch 'file.js', 'coffee -c', (err, stdout, stderr) ->
+````javascript
+sentry.watch('file.js', 'coffee -c', function (error, filename, stdout, stderr) {/*...*/});
````
Or just pass a callback and Sentry will pass the filename to the callback
-````coffeescript
-sentry.watch 'file.js', (filename) ->
+````javascript
+sentry.watch('file.js', function (error, filename) {/*...*/});
````
Feel free to use wildcards with extensions
-````coffeescript
+````javascript
-# Find all files one directory deep
-sentry.watch '/folder/*', ->
+// Find all files one directory deep
+sentry.watch('/folder/*', callback);
-# Find all files one directory deep ending in .coffee
-sentry.watch '/folder/*.coffee', ->
+// Find all files one directory deep ending in .coffee
+sentry.watch('/folder/*.coffee', callback);
-# Find all files recursively
-sentry.watch '/folder/**/*', ->
+// Find all files recursively
+sentry.watch('/folder/**/*', callback);
-# Find all files recursively ending in .txt
-sentry.watch '/folder/**/*.txt', ->
+// Find all files recursively ending in .txt
+sentry.watch('/folder/**/*.txt', callback);
````
### sentry.watchRegExp(root, regex, [task], callback)
Just like sentry.watch but instead you must pass a root directory and regular expression to match files against.
-````coffeescript
+````javascript
-# Find all files in this folder that end in .coffee
-sentry.watchRegExp '', /\.coffee$/, ->
+// Find all files in this folder that end in .coffee
+sentry.watchRegExp('', /\.coffee$/, callback);
-# Find all files in the adjacent 'test' folder that begin with `test_` and end in `.coffee`
-sentry.watchRegExp '../tests/', /^test_,.coffee$/, ->
+// Find all files in the adjacent 'test' folder that begin with `test_` and end in `.coffee`
+sentry.watchRegExp('../tests/', /^test_,.coffee$/, callback);
````
## To run tests
-Sentry uses [Jasmine-node](https://github.com/mhevery/jasmine-node) for testing. Simply run the jasmine-node command with the coffeescript flag
-
- jasmine-node spec --coffee
+ npm test
View
38 package.json
@@ -1,33 +1,19 @@
{
- "name": "sentry",
- "version": "0.1.2",
- "author": "Craig Spaeth <craigspaeth@gmail.com> (http://craigspaeth.com)",
+ "name": "sentry2",
+ "version": "0.2.0",
"description": "Watch files (using a path, wildcards, or a regex) and execute a function or shell command.",
- "keywords": [
- "watch",
- "watchr",
- "guard",
- "wildcards",
- "recursive"
+ "homepage": "http://github.com/rolandpoulter/sentry",
+ "main": "./sentry.js",
+ "keywords": ["watch", "watcher", "watchr", "guard", "wildcards", "recursive", "directory"],
+ "contributors": [
+ {"name": "Craig Spaeth", "email": "craigspaeth@gmail.com", "web": "http://craigspaeth.com"},
+ {"name": "Roland Poulter", "web": "http://github.com/rolandpoulter"}
],
+ "dependencies": {"file": "0.2.1"},
+ "devDependencies": {"mocha": "1.8.1"},
+ "scripts": {"test": "mocha ./test/sentry_test.js"},
"repository": {
"type": "git",
- "url": "git://github.com/craigspaeth/sentry.git"
- },
- "dependencies": {
- "coffee-script": "*",
- "underscore": "*",
- "file": "*"
- },
- "devDependencies": {
- "jasmine-node": "*"
- },
- "main": "lib/sentry",
- "scripts": {
- "install": "cake build",
- "test": "jasmine-node spec --coffee"
- },
- "engines": {
- "node": "*"
+ "url": "git://github.com/rolandpoulter/sentry.git"
}
}
View
266 sentry.js
@@ -0,0 +1,266 @@
+var exec = require('child_process').exec,
+ path = require('path'),
+ file = require('file'),
+ fs = require('fs');
+
+// FIXME: callbacks get fire more than once per change
+
+// Watch for changes on a file using a file path or wildcards
+// If passed a task callback is passed (err, stdout, stderr)
+// If task is ommitted then callback is passed (filename)
+//
+// @param {String} filename File path to watch, optionally pass /* or /**/* wildcards
+// @param {String} [task] Optionally run a child process
+// @param {Function} callback (error, filename, [stdout], [stderr])
+// @param {Object} [options]
+// @param {Object} [map]
+exports.watch = function (filename, task, callback, options, map) {
+ if (typeof task === 'function') {
+ callback = task;
+ task = null;
+ }
+
+ map = map || {};
+
+ if (filename.indexOf('/*') !== -1) {
+ // Get the files we want to catch with the wildcards, and watch them
+ exports.findWildcards(filename, function (error, files) {
+ if (error) {
+ return callback(error, filename);
+ }
+
+ files.forEach(function (file) {
+ watchFile(file, task, callback, options, map);
+ });
+ }, map)
+
+ } else {
+ // If the file is a string without wildcards, watch just that file
+ watchFile(filename, task, callback, options, map);
+ }
+
+ return map;
+};
+
+// Watch for file changes recursively in a directory that match a regex
+// If passed a task callback is passed (err, stdout, stderr)
+// If task is ommitted then callback is passed (filename)
+//
+// @param {String} dir Root directory to search in
+// @param {RegExp} regex
+// @param {String} [task] Optionally run a child process
+// @param {Function} callback (error, filename, [stdout], [stderr])
+// @param {Object} [options]
+// @param {Object} [map]
+exports.watchRegExp = function (dir, regex, task, callback, options, map) {
+ if (typeof task === 'function') {
+ callback = task;
+ task = null;
+ }
+
+ // Recursively find anything that matches the regex
+ dir = path.resolve(path.dirname(module.parent.filename), dir);
+ map = map || {};
+
+ // Watch the matches files
+ try {
+ file.walk(dir, function (error, start, dirs, files) {
+ if (error) {
+ return callback(error, dir);
+ }
+
+ dirs.forEach(function (dir) {
+ if (dir.indexOf(start) === -1) {
+ dir = start + '/' + dir;
+ }
+
+ watchFile(file, task, function (dirname) {
+ if (regex.test(dirname)) {
+ callback(null, dirname);
+
+ exports.watchRegExp(dir, regex, task, callback, options, map);
+ }
+ }, options, map)
+ });
+
+ files.forEach(function (file) {
+ if (file.indexOf(start) === -1) {
+ file = start + '/' + file;
+ }
+
+ watchFile(file, task, function (filename) {
+ if (regex.test(filename)) {
+ callback(null, filename);
+ }
+ }, options, map);
+ })
+ });
+
+ } catch (error) {
+ callback(error, dir);
+ }
+
+ return map;
+};
+
+// Watch a file for changes and execute a callback or child process.
+//
+// @param {String} filename
+// @param {String} [task]
+// @param {Function} callback (error, filename, [stdout], [stderr])
+// @param {Object} [options]
+// @param {Object} [map]
+function watchFile (filename, task, callback, options, map) {
+ fs.exists(filename, function (exists) {
+ if (!exists) {
+ return callback(new Error('Sentry2.watch file: "' + filename + '" does not exist!'), filename);
+ }
+
+ var listener;
+
+ if (map && map[filename]) return;
+
+ try {
+ if (fs.watch) {
+ fs.watch(filename, listener = function (event, _filename) {
+ _filename = _filename || filename;
+
+ if (event === 'rename') {
+ if (map && map[_filename]) map[_filename]();
+
+ watchFile(_filename, task, callback, options, map);
+ }
+
+ finish(_filename);
+ });
+
+ } else {
+ fs.watchFile(filename, listener = function (curr, prev) {
+ if (curr.size === prev.size && curr.mtime.getTime() === prev.mtime.getTime()) {
+ return;
+ }
+
+ finish(filename);
+ });
+ }
+ } catch (error) {
+ callback(error, filename);
+ }
+
+ if (map) {
+ map[filename] = function () {
+ fs.unwatchFile(filename, listener);
+ };
+ }
+ });
+
+ function finish (filename) {
+ if (typeof task === 'string') {
+ exec(task, function (error, stdout, stderr) {
+ if (callback) {
+ callback(error, filename, stdout, stderr);
+ } else {
+ console.log(stdout);
+ if (error) {
+ console.log(error);
+ }
+ }
+ });
+
+ } else if (callback) {
+ callback(null, filename);
+ }
+ }
+}
+
+// Given a filename such as /fld/**/* return all recursive files
+// or given a filename such as /fld/* return all files one directory deep.
+// Limit by extension via /fld/**/*.coffee
+//
+// @param {String} filename
+// @param {Function} callback (error, files)
+exports.findWildcards = function (filename, callback, map) {
+ var split,
+ root,
+ ext;
+
+ if (typeof filename !== 'string') {
+ return callback(new Error('Sentry2.findWildcards was provided an invalid filename: ' + filename));
+ }
+
+ map = map || {};
+ map.__map = map.__map || {};
+
+ // If there is a wildcard in the /**/* form of a file then remove it and
+ // splice in all files recursively in that directory
+ if (filename.indexOf('**/*') !== -1) {
+ split = filename.split('**/*');
+ root = split[0];
+ ext = split[1];
+
+ walkDir();
+ watchFile(root, null, walkDir, {persistent: false}, map.__map);
+
+ function walkDir () {
+ try {
+ file.walk(root, function (error, start, dirs, files) {
+ if (error) {
+ return callback(error, root);
+ }
+
+ callback(null, filterList(start, dirs.concat(files)));
+ });
+ } catch (error) {
+ callback(error, root);
+ }
+ }
+
+ // If there is a wildcard in the /* form then remove it and splice in all the
+ // files one directory deep
+ } else if (filename.indexOf('/*')) {
+ split = filename.split('/*');
+ root = split[0];
+ ext = split[1];
+
+ scanDir();
+ watchFile(root, null, scanDir, {persistent: false}, map.__map);
+
+ function scanDir () {
+ fs.readdir(root, function (error, files) {
+ if (error) {
+ return callback(error, root);
+
+ callback(null, filterList(root, files));
+ }
+ });
+ }
+
+ } else {
+ callback(null, []);
+ }
+
+ function filterList (start, list) {
+ var filtered = [],
+ _map = {};
+
+ if (start.charAt(start.length - 1) !== '/') {
+ start += '/';
+ }
+
+ list.forEach(function (name) {
+ if (new RegExp(ext + '$').test(name)) {
+ if (name.indexOf(start) === -1) {
+ name = start + name;
+ }
+
+ if (!_map[name]) {
+ _map[name] = true;
+
+ filtered.push(name);
+ }
+ }
+ });
+
+ return filtered;
+ }
+};
View
8 spec/helpers/spec_helper.coffee
@@ -1,8 +0,0 @@
-# Run an entire suite aynchronously
-_done = false
-@done = -> _done = true
-@runAsync = (timeout = 10000) ->
- beforeEach -> _done = false
- afterEach -> waitsFor (-> _done), null, timeout
-
-global.__rootdir = __dirname.split('/').slice(0, -2).join('/')
View
170 spec/sentry_spec.coffee
@@ -1,170 +0,0 @@
-require './helpers/spec_helper.coffee'
-sentry = require '../src/sentry.coffee'
-fs = require 'fs'
-exec = require('child_process').exec
-spawn = require('child_process').spawn
-path = require 'path'
-_ = require 'underscore'
-
-describe 'sentry.watch', ->
-
- describe 'given a relative file string', ->
-
- it 'throws an error if it cant find the file', ->
- try
- sentry.watch('garbage')
- catch e
- expect(e.message).toEqual "SENTRY: File 'garbage' does not exist!"
-
- it 'runs a function when the file is changed', ->
- done = false; waitsFor -> done
- fs.writeFileSync __rootdir + '/spec/fixtures/string/foo.js', 'Blank'
- sentry.watch __rootdir + '/spec/fixtures/string/foo.js', ->
- expect(true).toBeTruthy()
- done = true
- _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/string/foo.js', 'Hello World'
-
- it 'runs a task when the file is changed', ->
- done = false; waitsFor (-> done), null, 10000
- fs.writeFileSync __rootdir + '/spec/fixtures/string/bar.js', 'Blank'
- sentry.watch __rootdir + '/spec/fixtures/string/bar.js', 'cake stub', (err, stdout, stderr) ->
- expect(stdout.indexOf 'stub').toNotEqual -1
- done = true
- _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/string/bar.js', 'Hello World'
-
- it 'passes the filename to the callback' , ->
- done = false; waitsFor -> done
- fs.writeFileSync __rootdir + '/spec/fixtures/string/baz.js', 'Blank'
- sentry.watch __rootdir + '/spec/fixtures/string/baz.js', (filename) ->
- expect(filename).toEqual __rootdir + '/spec/fixtures/string/baz.js'
- done = true
- _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/string/baz.js', 'Hello World'
-
- describe 'given a single wild card', ->
-
- it 'runs a function when a file is changed', ->
- done = false; waitsFor -> done
- fs.writeFileSync __rootdir + '/spec/fixtures/wildcard/foo.js', 'Blank'
- sentry.watch __rootdir + '/spec/fixtures/wildcard/*', ->
- expect(true).toBeTruthy()
- done = true
- _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/wildcard/foo.js', 'Hello World'
-
- it 'runs a task when a file is changed', ->
- done = false; waitsFor (-> done), null, 10000
- fs.writeFileSync __rootdir + '/spec/fixtures/wildcard/bar.js', 'Blank'
- sentry.watch __rootdir + '/spec/fixtures/wildcard/*', 'cake stub', (err, stdout, stderr) ->
- expect(stdout.indexOf 'stub').toNotEqual -1
- done = true
- _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/wildcard/bar.js', 'Hello World'
-
- it 'it passes the filename to the callback', ->
- done = false; waitsFor -> done
- fs.writeFileSync __rootdir + '/spec/fixtures/wildcard/foo.js', 'Blank'
- sentry.watch __rootdir + '/spec/fixtures/wildcard/*', (filename) ->
- expect(filename.match(/foo|baz|qux|bar/)).toBeTruthy()
- done = true
- _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/wildcard/foo.js', 'Hello World'
-
- it 'it only watches the file with given extension', ->
- done = false; waitsFor -> done
- filesWritten = 0
- sentryWatchedFiles = 0
- fs.writeFileSync __rootdir + '/spec/fixtures/wildcard/qux.js', 'Blank'
- fs.writeFileSync __rootdir + '/spec/fixtures/wildcard/baz.coffee', 'Blank'
- sentry.watch __rootdir + '/spec/fixtures/wildcard/*.coffee', (filename) ->
- filesWritten++
- sentryWatchedFiles++
- if filesWritten is 2
- expect(sentryWatchedFiles).toEqual 1
- done = true
- fs.watchFile __rootdir + '/spec/fixtures/wildcard/qux.js', (curr, prev) ->
- filesWritten++
- if filesWritten is 2
- expect(sentryWatchedFiles).toEqual 1
- done = true
- _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/wildcard/qux.js', 'Hello World'
- _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/wildcard/baz.coffee', 'Hello World'
-
- describe 'given a recursive wild card', ->
-
- it 'runs a function when a deeply nested file is changed', ->
- done = false; waitsFor -> done
- fs.writeFileSync __rootdir + '/spec/fixtures/deepwildcard/deep/foo.js', 'Blank'
- sentry.watch __rootdir + '/spec/fixtures/deepwildcard/**/*.js', ->
- expect(true).toBeTruthy()
- done = true
- _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/deepwildcard/deep/foo.js', 'Hello World'
-
- it 'runs a function when a not so deeply nested file is changed', ->
- done = false; waitsFor (-> done), null, 10000
- fs.writeFileSync __rootdir + '/spec/fixtures/deepwildcard/bar.js', 'Blank'
- sentry.watch __rootdir + '/spec/fixtures/deepwildcard/**/*.js', 'cake stub', (err, stdout, stderr) ->
- expect(stdout.indexOf 'stub').toNotEqual -1
- done = true
- _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/deepwildcard/bar.js', 'Hello World'
-
- it 'it passes the filename to the callback', ->
- done = false; waitsFor -> done
- fs.writeFileSync __rootdir + '/spec/fixtures/deepwildcard/deep/foo.js', 'Blank'
- sentry.watch __rootdir + '/spec/fixtures/deepwildcard/**/*', (filename) ->
- expect(filename.match(/foo|baz|qux/)).toBeTruthy()
- done = true
- _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/deepwildcard/deep/foo.js', 'Hello World'
-
- it 'it only watches the file with given extension', ->
- done = false; waitsFor -> done
- filesWritten = 0
- sentryWatchedFiles = 0
- fs.writeFileSync __rootdir + '/spec/fixtures/deepwildcard/deep/qux.js', 'Blank'
- fs.writeFileSync __rootdir + '/spec/fixtures/deepwildcard/deep/baz.coffee', 'Blank'
- sentry.watch __rootdir + '/spec/fixtures/deepwildcard/**/*.coffee', (filename) ->
- filesWritten++
- sentryWatchedFiles++
- if filesWritten is 2
- expect(sentryWatchedFiles).toEqual 1
- done = true
- fs.watchFile __rootdir + '/spec/fixtures/deepwildcard/deep/qux.js', (curr, prev) ->
- filesWritten++
- if filesWritten is 2
- expect(sentryWatchedFiles).toEqual 1
- done = true
- _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/deepwildcard/deep/qux.js', 'Hello World'
- _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/deepwildcard/deep/baz.coffee', 'Hello World'
-
-
-describe 'sentry.watchRegExp', ->
-
- it 'runs a function when a deeply nested file that matches the regex changes', ->
- done = false; waitsFor -> done
- fs.writeFileSync __rootdir + '/spec/fixtures/regex/deep/foo.txt', 'Blank'
- sentry.watchRegExp './fixtures/regex/', /txt$/, ->
- expect(true).toBeTruthy()
- done = true
- _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/regex/deep/foo.txt', 'Hello World'
-
-describe 'sentry.findWildcards', ->
-
- it 'given a /* type wildcard finds files one directory deep', ->
- equal = _.isEqual sentry.findWildcards(__rootdir + '/spec/fixtures/wildcard/*'), [
- '/Users/Craig/sentry/spec/fixtures/wildcard/bar.js',
- '/Users/Craig/sentry/spec/fixtures/wildcard/baz.coffee',
- '/Users/Craig/sentry/spec/fixtures/wildcard/foo.js',
- '/Users/Craig/sentry/spec/fixtures/wildcard/qux.js'
- ]
- expect(equal).toBeTruthy()
-
- it 'given a /**/* type wildcard finds files recursive', ->
- equal = _.isEqual sentry.findWildcards(__rootdir + '/spec/fixtures/deepwildcard/**/*'), [
- '/Users/Craig/sentry/spec/fixtures/deepwildcard/bar.js',
- '/Users/Craig/sentry/spec/fixtures/deepwildcard/deep/baz.coffee',
- '/Users/Craig/sentry/spec/fixtures/deepwildcard/deep/foo.js',
- '/Users/Craig/sentry/spec/fixtures/deepwildcard/deep/qux.js'
- ]
- expect(equal).toBeTruthy()
-
- it 'given a /**/*.coffee type wildcard finds files with only that extension', ->
- equal = _.isEqual sentry.findWildcards(__rootdir + '/spec/fixtures/deepwildcard/**/*.coffee'), [
- '/Users/Craig/sentry/spec/fixtures/deepwildcard/deep/baz.coffee'
- ]
- expect(equal).toBeTruthy()
View
102 src/sentry.coffee
@@ -1,102 +0,0 @@
-fileUtil = require 'file'
-_ = require 'underscore'
-fs = require 'fs'
-exec = require('child_process').exec
-path = require 'path'
-
-# Watch for changes on a file using a file path or wildcards
-# If passed a task callback is passed (err, stdout, stderr)
-# If task is ommitted then callback is passed (filename)
-#
-# @param {String} filename File path to watch, optionally pass /* or /**/* wildcards
-# @param {String} [task] Optionally run a child process
-# @param {Function} callback
-
-@watch = (filename, task, callback) =>
-
- callback = task if _.isFunction task
-
- # If the file is a string without wildcards, watch just that file
- if filename.indexOf('/*') isnt -1
- files = @findWildcards filename
- watchFile file, task, callback for file in files
-
- # Get the files we want to catch with the wildcards
- else
- throw new Error("SENTRY: File '#{filename}' does not exist!") unless path.existsSync filename
- watchFile filename, task, callback
-
-# Watch for file changes recursively in a directory that match a regex
-# If passed a task callback is passed (err, stdout, stderr)
-# If task is ommitted then callback is passed (filename)
-#
-# @param {String} dir Root directory to search in
-# @param {RegExp} regex
-# @param {String} [task] Optionally run a child process
-# @param {Function} callback
-
-@watchRegExp = (dir, regex, task, callback) ->
-
- callback = task if _.isFunction task
-
- # Recursively find anything that matches the regex
- dir = path.resolve(path.dirname(module.parent.filename), dir)
- files = []
- fileUtil.walkSync dir, (rt, flds, fls) ->
- for fl in fls
- flPath = rt + '/' + fl
- files.push(flPath) if flPath.match regex
- files
-
- # Watch the matches files
- watchFile(file, task, callback) for file in files
-
-# Watch a file for changes and execute a callback or child process.
-#
-# @param {String} filename
-# @param {String} [task]
-# @param {Function} callback
-
-watchFile = (filename, task, callback) ->
- fs.watchFile filename, (curr, prev) ->
- return if curr.size is prev.size and curr.mtime.getTime() is prev.mtime.getTime()
- if _.isString task
- exec task, (err, stdout, stderr) ->
- console.log stdout
- console.log err if err?
- callback(err, stdout, stderr) if callback?
- else
- callback filename
-
-# Given a filename such as /fld/**/* return all recursive files
-# or given a filename such as /fld/* return all files one directory deep.
-# Limit by extension via /fld/**/*.coffee
-#
-# @param {String} filename
-# @return {Array} An array of file path strings
-
-@findWildcards = (filename) ->
-
- files = []
-
- # If there is a wildcard in the /**/* form of a file then remove it and
- # splice in all files recursively in that directory
- if filename? and filename.indexOf('**/*') isnt -1
- root = filename.split('**/*')[0]
- ext = filename.split('**/*')[1]
- fileUtil.walkSync root, (root, flds, fls) ->
- root = (if root.charAt(root.length - 1) is '/' then root else root + '/')
- for file in fls
- if file.match(new RegExp ext + '$')? and _.indexOf(files, root + file) is -1
- files.push(root + file)
-
- # If there is a wildcard in the /* form then remove it and splice in all the
- # files one directory deep
- else if filename? and filename.indexOf('/*') isnt -1
- root = filename.split('/*')[0]
- ext = filename.split('/*')[1]
- for file in fs.readdirSync(root)
- if file.indexOf('.') isnt -1 and file.match(new RegExp ext + '$')? and _.indexOf(files, root + '/' + file) is -1
- files.push(root + '/' + file)
-
- files
View
0  spec/fixtures/wildcard/bar.js → test/fixtures/bar.js
File renamed without changes
View
0  spec/fixtures/string/bar.js → test/fixtures/deepwildcard/bar.js
File renamed without changes
View
0  spec/fixtures/wildcard/qux.js → test/fixtures/deepwildcard/deep/baz.json
File renamed without changes
View
0  spec/fixtures/wildcard/foo.js → test/fixtures/deepwildcard/deep/foo.js
File renamed without changes
View
0  spec/fixtures/deepwildcard/deep/qux.js → test/fixtures/deepwildcard/deep/qux.js
File renamed without changes
View
0  spec/fixtures/regex/bar.js → test/fixtures/regex/bar.js
File renamed without changes
View
0  spec/fixtures/string/foo.js → test/fixtures/regex/deep/foo.js
File renamed without changes
View
0  spec/fixtures/regex/deep/foo.txt → test/fixtures/regex/deep/foo.txt
File renamed without changes
View
0  spec/fixtures/deepwildcard/bar.js → test/fixtures/string/bar.js
File renamed without changes
View
0  spec/fixtures/string/baz.js → test/fixtures/string/baz.js
File renamed without changes
View
0  spec/fixtures/regex/deep/foo.js → test/fixtures/string/foo.js
File renamed without changes
View
0  spec/fixtures/bar.js → test/fixtures/wildcard/bar.js
File renamed without changes
View
0  spec/fixtures/wildcard/baz.coffee → test/fixtures/wildcard/baz.json
File renamed without changes
View
0  spec/fixtures/deepwildcard/deep/foo.js → test/fixtures/wildcard/foo.js
File renamed without changes
View
0  spec/fixtures/deepwildcard/deep/baz.coffee → test/fixtures/wildcard/qux.js
File renamed without changes
View
182 test/sentry_test.js
@@ -0,0 +1,182 @@
+var fs = require('fs'),
+ path = require('path'),
+ exec = require('child_process').exec,
+ spawn = require('child_process').spawn,
+ assert = require('assert');
+
+
+var sentry = require('../sentry');
+
+
+describe('sentry.watch', function () {
+ this.timeout(5000);
+
+ describe('given a relative file string', function () {
+
+ it('throws an error if it cant find the file', function (done) {
+ sentry.watch('garbage', function (error) {
+ assert.equal(error.message, 'Sentry2.watch file: "garbage" does not exist!');
+ done();
+ });
+ });
+
+ it('runs a function when the file is changed and passes the filename to the callback', function (done) {
+ var target = __dirname + '/fixtures/string/foo.js';
+
+ fs.writeFileSync(target, 'Blank');
+
+ sentry.watch(target, function (error, filename) {
+ assert(!error);
+ assert.equal(target, filename);
+ done();
+ });
+
+ fs.writeFileSync(target, 'Hello World');
+ });
+
+ it('runs a task when the file is changed', function (done) {
+ var target = __dirname + '/fixtures/string/bar.js';
+
+ fs.writeFileSync(target, 'Blank');
+
+ // TODO: use a real command
+ sentry.watch(target, 'fake_cmd', function (error, filename, stdout, stderr) {
+ assert(error);
+ done();
+ });
+
+ fs.writeFileSync(target, 'Hello World');
+ });
+ });
+
+ // TODO: finish rewriting the tests
+});
+
+// describe 'given a single wild card', ->
+//
+// it 'runs a function when a file is changed', ->
+// done = false; waitsFor -> done
+// fs.writeFileSync __rootdir + '/spec/fixtures/wildcard/foo.js', 'Blank'
+// sentry.watch __rootdir + '/spec/fixtures/wildcard/*', ->
+// expect(true).toBeTruthy()
+// done = true
+// _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/wildcard/foo.js', 'Hello World'
+//
+// it 'runs a task when a file is changed', ->
+// done = false; waitsFor (-> done), null, 10000
+// fs.writeFileSync __rootdir + '/spec/fixtures/wildcard/bar.js', 'Blank'
+// sentry.watch __rootdir + '/spec/fixtures/wildcard/*', 'cake stub', (err, stdout, stderr) ->
+// expect(stdout.indexOf 'stub').toNotEqual -1
+// done = true
+// _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/wildcard/bar.js', 'Hello World'
+//
+// it 'it passes the filename to the callback', ->
+// done = false; waitsFor -> done
+// fs.writeFileSync __rootdir + '/spec/fixtures/wildcard/foo.js', 'Blank'
+// sentry.watch __rootdir + '/spec/fixtures/wildcard/*', (filename) ->
+// expect(filename.match(/foo|baz|qux|bar/)).toBeTruthy()
+// done = true
+// _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/wildcard/foo.js', 'Hello World'
+//
+// it 'it only watches the file with given extension', ->
+// done = false; waitsFor -> done
+// filesWritten = 0
+// sentryWatchedFiles = 0
+// fs.writeFileSync __rootdir + '/spec/fixtures/wildcard/qux.js', 'Blank'
+// fs.writeFileSync __rootdir + '/spec/fixtures/wildcard/baz.json', 'Blank'
+// sentry.watch __rootdir + '/spec/fixtures/wildcard/*.json', (filename) ->
+// filesWritten++
+// sentryWatchedFiles++
+// if filesWritten is 2
+// expect(sentryWatchedFiles).toEqual 1
+// done = true
+// fs.watchFile __rootdir + '/spec/fixtures/wildcard/qux.js', (curr, prev) ->
+// filesWritten++
+// if filesWritten is 2
+// expect(sentryWatchedFiles).toEqual 1
+// done = true
+// _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/wildcard/qux.js', 'Hello World'
+// _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/wildcard/baz.json', 'Hello World'
+//
+// describe 'given a recursive wild card', ->
+//
+// it 'runs a function when a deeply nested file is changed', ->
+// done = false; waitsFor -> done
+// fs.writeFileSync __rootdir + '/spec/fixtures/deepwildcard/deep/foo.js', 'Blank'
+// sentry.watch __rootdir + '/spec/fixtures/deepwildcard/**/*.js', ->
+// expect(true).toBeTruthy()
+// done = true
+// _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/deepwildcard/deep/foo.js', 'Hello World'
+//
+// it 'runs a function when a not so deeply nested file is changed', ->
+// done = false; waitsFor (-> done), null, 10000
+// fs.writeFileSync __rootdir + '/spec/fixtures/deepwildcard/bar.js', 'Blank'
+// sentry.watch __rootdir + '/spec/fixtures/deepwildcard/**/*.js', 'cake stub', (err, stdout, stderr) ->
+// expect(stdout.indexOf 'stub').toNotEqual -1
+// done = true
+// _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/deepwildcard/bar.js', 'Hello World'
+//
+// it 'it passes the filename to the callback', ->
+// done = false; waitsFor -> done
+// fs.writeFileSync __rootdir + '/spec/fixtures/deepwildcard/deep/foo.js', 'Blank'
+// sentry.watch __rootdir + '/spec/fixtures/deepwildcard/**/*', (filename) ->
+// expect(filename.match(/foo|baz|qux/)).toBeTruthy()
+// done = true
+// _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/deepwildcard/deep/foo.js', 'Hello World'
+//
+// it 'it only watches the file with given extension', ->
+// done = false; waitsFor -> done
+// filesWritten = 0
+// sentryWatchedFiles = 0
+// fs.writeFileSync __rootdir + '/spec/fixtures/deepwildcard/deep/qux.js', 'Blank'
+// fs.writeFileSync __rootdir + '/spec/fixtures/deepwildcard/deep/baz.json', 'Blank'
+// sentry.watch __rootdir + '/spec/fixtures/deepwildcard/**/*.json', (filename) ->
+// filesWritten++
+// sentryWatchedFiles++
+// if filesWritten is 2
+// expect(sentryWatchedFiles).toEqual 1
+// done = true
+// fs.watchFile __rootdir + '/spec/fixtures/deepwildcard/deep/qux.js', (curr, prev) ->
+// filesWritten++
+// if filesWritten is 2
+// expect(sentryWatchedFiles).toEqual 1
+// done = true
+// _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/deepwildcard/deep/qux.js', 'Hello World'
+// _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/deepwildcard/deep/baz.json', 'Hello World'
+//
+//
+//describe 'sentry.watchRegExp', ->
+//
+// it 'runs a function when a deeply nested file that matches the regex changes', ->
+// done = false; waitsFor -> done
+// fs.writeFileSync __rootdir + '/spec/fixtures/regex/deep/foo.txt', 'Blank'
+// sentry.watchRegExp './fixtures/regex/', /txt$/, ->
+// expect(true).toBeTruthy()
+// done = true
+// _.defer -> fs.writeFileSync __rootdir + '/spec/fixtures/regex/deep/foo.txt', 'Hello World'
+//
+//describe 'sentry.findWildcards', ->
+//
+// it 'given a /* type wildcard finds files one directory deep', ->
+// equal = _.isEqual sentry.findWildcards(__rootdir + '/spec/fixtures/wildcard/*'), [
+// '/Users/Craig/sentry/spec/fixtures/wildcard/bar.js',
+// '/Users/Craig/sentry/spec/fixtures/wildcard/baz.json',
+// '/Users/Craig/sentry/spec/fixtures/wildcard/foo.js',
+// '/Users/Craig/sentry/spec/fixtures/wildcard/qux.js'
+// ]
+// expect(equal).toBeTruthy()
+//
+// it 'given a /**/* type wildcard finds files recursive', ->
+// equal = _.isEqual sentry.findWildcards(__rootdir + '/spec/fixtures/deepwildcard/**/*'), [
+// '/Users/Craig/sentry/spec/fixtures/deepwildcard/bar.js',
+// '/Users/Craig/sentry/spec/fixtures/deepwildcard/deep/baz.json',
+// '/Users/Craig/sentry/spec/fixtures/deepwildcard/deep/foo.js',
+// '/Users/Craig/sentry/spec/fixtures/deepwildcard/deep/qux.js'
+// ]
+// expect(equal).toBeTruthy()
+//
+// it 'given a /**/*.json type wildcard finds files with only that extension', ->
+// equal = _.isEqual sentry.findWildcards(__rootdir + '/spec/fixtures/deepwildcard/**/*.json'), [
+// '/Users/Craig/sentry/spec/fixtures/deepwildcard/deep/baz.json'
+// ]
+// expect(equal).toBeTruthy()

No commit comments for this range

Something went wrong with that request. Please try again.