mikeal / watch Goto Github PK
View Code? Open in Web Editor NEWUtilities for watching file trees in node.js
License: Apache License 2.0
Utilities for watching file trees in node.js
License: Apache License 2.0
There is a bug (I think) in:
function walk (dir, options, callback) {
if (!callback) {callback = options; options = {}}
if (!callback.files) callback.files = {};
if (!callback.pending) callback.pending = 0;
callback.pending += 1;
fs.stat(dir, function (err, stat) {
should be
function walk (dir, options, callback) {
if (!callback) {callback = options; options = {}}
if (!callback.files) callback.files = {};
if (!callback.pending) callback.pending = 0;
fs.stat(dir, function (err, stat) {
callback.pending += 1;
At least the change makes couchapp push work more reliably.
It doesn't look like there's currently a way to do this (from the CLI). It would be nice if the watch CLI could take multiple directories to watch:
Something like this:
watch [...directory] [--wait=] [--ignoreDotFiles] [--ignoreUnreadable]
Ex:
watch "echo file changed" dir1/ dir2/
created
event is emitted when the file is busy or locked (EBUSY
), for example, with a big file in Windows platform. I try to open a created
file after receive the event and I get the error.
This problem is known in Windows platform: Node.js and File System on Windows - EBUSY error
It would be nice to be able to unwatch the directory
Is it possible for watch to preserve colors output by the commands it runs?
The filter option does not appear to do anything. I put in a filter function which returns true or false according to a regex match, and it logs out the correct directories, then proceeds to watch all the files regardless of the filter function.
Do you want a code example here? I can if you want, but I've tested it through in the simplest way and it's quite clearly broken : (
It does not use polling and is faster. I'm just wondering if it's easy to check whether fs.watch works and if it does not fallback to watchFile.
I recently updated from 0.13 to 0.14 and noticed this behavior.
watchit.js:
require("watch").createMonitor(".", { interval: 500 }, function(monitor) {
monitor.on("changed", function(fileName) { console.log(fileName) })
})
Using it:
$ node watchit &
[1] 1259
$ touch watchit.js
watchit.js
watchit.js
I'm using node 0.11.14 on Linux Mint.
Right now the only way to stop watching the files is to kill the process (or manually traverse files and unwatch). unwatchTree
, and/or monitor.stop
functions to stop watching the files.
I want to send a PR to implement that but I see there are a few stale pull requests so before I write any code is that something you'll be interested in merging?
First of all, thanks for you work!
I'm trying to use watch
cli as part of my npm scripts, like so:
"scripts": {
"start": "node index",
"js:watch": "watch 'npm start' lib/"
}
But then everytime a file changes, it gives the EADDRINUSE
, as the server (node index
) is already started... How can I accomplish this? What should I put in npm stop
script or what should I pass to watch
?
Thank you!
The following code is faulty (L49 and L50):
if (options.ignoreDotFiles && path.basename(f)[0] === '.') return done && callback(null, callback.files);
if (options.filter && options.filter(f, stat)) return done && callback(null, callback.files);
If done
is true
the part after &&
is not evaluated.
The documentation says that the created event has three arguments, and the changed has two. This should be fixed.
There's a situation when the file is unreadable. When I try to run the following code
var watch = require('watch');
watch.watchTree('C:\\', {ignoreUnreadableDir: true}, function (f, curr, prev) {
if (typeof f == "object" && prev === null && curr === null) {
console.log('done');
} else if (prev === null) {
console.log('created', f);
} else if (curr.nlink === 0) {
console.log('removed', f);
} else {
console.log('changed', f);
}
});
I get an error
D:\heroku\dedup\node_modules\watch\main.js:73
if (err) throw err;
^
Error: EBUSY, stat 'C:\hiberfil.sys'
at Error (native)
It certainly should be fixed, because unreadable files are quite common. For example, IDE may lock some files in source code directory, and there won't be a way to watch its changes.
Make a folder structure like this
root
+-file1
+-ignoremedir
+-dir2
Watch root with options {ignoreDirectoryPattern: /ignoremedir/}
Now touch root/ignoremedir/newfile
Result, get created notification about root/ignoremedir/dir2
and root/ignoremedir/newfile
I'm using the example code from the README and watching a directory with only three files in it. When I make a change to one of the files it's taking anywhere between 1 and 4 seconds to report. When I simply use fs.watch
the change is reported almost immediately.
Is this expected? If not, do you have any idea what might be causing the slowness?
If you use .watchTree()
in a given process, will those file watchers prevent the process from exiting otherwise? If so, it would probably be a good idea to have an unwatchTree()
method which checks if the directory tree is being watched and then removes the listeners using fs.unwatchFile(filename)
I have the following scripts:
"scripts": {
"lint": "jshint .",
"test": "tape test/index.js | tap-bail | tap-difflet",
"c1:section5:example-1": "tape examples/software-testing/section5/example-1.js | tap-bail | tap-difflet",
"c1:section5:example-2": "tape examples/software-testing/section5/example-1.js | tap-bail | tap-difflet",
"dev": "watch --wait=5 'npm run lint && npm run test' ."
}
When I run these scripts directly, they have color output (via tap-difflet). When I do npm run dev
and use watch
to launch the tasks, the colors are stripped.
Hi,
first of all, thanks for the code, it replaced mine.
But I expanded it a little because I had it break on some files.
If one error occurs you will not get any information. I changed this:
fs.stat(f, function (err, stat) {
callback.pending -= 1;
if (err) return callback(err, [f])
this will ensure that if one fs.stat inside the walk breaks the rest goes through unharmed.
To inform the user I kind of changed your createMonitor to return an EventEmitter:
exports.createMonitor = function (root, options, cb) {
if (!cb) {cb = options; options = {}}
var monitor = new events.EventEmitter();
exports.watchTree(root, options, function (f, curr, prev, err) {
if(err)
return monitor.emit("error", err, f);
if (typeof f == "object" && prev == null && curr === null) {
monitor.files = f;
monitor.emit("initialized", f);
if(cb)
cb.call(monitor, f);
//cb.call(monitor, monitor, f);
return;
}
if (prev === null) {
return monitor.emit("created", f, curr);
}
if (curr.nlink === 0) {
return monitor.emit("removed", f, curr);
}
monitor.emit("changed", f, curr, prev);
})
return monitor;
}
This should not break your code as it still works like before, except the stuff with cb.call.
The big difference is, this function returns the monitor so you can write you code like this:
var monitor = watch.createMonitor('./dir', function init(files) {
console.log("Monitor has [%d : %d] files"
, Object.keys(files).length
, Object.keys(this.files).length
);
}).on('error', function(err, file) {
console.log("Found an error in %s", file)
});
Thanks again!
watchTree will pick up dot files up on changes even if ignoreDotFiles=true this causes eg .svn be monitored
nfiles.forEach(function (b) {
var file = path.join(f, b);
// added to skip dot files
if (options.ignoreDotFiles && path.basename(file)[0] === '.') return;
if (options.filter && options.filter(file)) return;
Hi there !
Like the title say so, my "ceated"
event gets triggered twice and I can't seem to figure out why.
Here is a sample code:
var root = "/home/me/myfolder",
watch = require('watch');
watch.createMonitor(root, function (monitor) {
monitor.on("created", function (path, stat) {
console.log("created", path);
});
});
When a new document is created, I see the log print twice.
Has anyone an idea on how could I fix this ?
The latest published version on npm is 0.9.0. The repository package.json is currently listed as 0.9.1.
when a file is removed, the prev stat object is all zeros.
there is an ino
property, and time is also reset to Jan 1st 1970
hmm, I was kinda expecting for this to be the stat before it was deleted.
I guess it doesn't really matter any more, because the file doesn't even exist.
{ dev: 0,
ino: 0,
mode: 0,
nlink: 0,
uid: 0,
gid: 0,
rdev: 0,
size: 0,
blksize: 0,
blocks: 0,
atime: Thu Jan 01 1970 01:00:00 GMT+0100 (CET),
mtime: Thu Jan 01 1970 01:00:00 GMT+0100 (CET),
ctime: Thu Jan 01 1970 01:00:00 GMT+0100 (CET) }
Files are ignored when the result of filter is true. They should be included as per your readme.
if (options.filter && options.filter(f)) return;
should be
if (options.filter && !options.filter(f)) return;
to not watch the file.
watch misses a delete event if the file is created, but not changed.
touch hello
# wait for watch to see it.
rm hello
# watch won't emit a removed event..
however, watch does see this...
touch hello
date > hello
rm hello
it's just a problem with the logic in watch, but not fs.watchFile
,
this will generate created
, then a modified
event
touch hello
rm hello
touch hello
PR forthcoming.
It's still at 0.10.0
There are a few contributors now and a likely increase in activity coming to this project. To help wrangle PR approvals, I propose we add LGTM.
We add a simple .lgtm
in the root that lists contributors. Then, PR statuses will then require approval from contributors by adding a comment with "LGTM" in it. The number of required approvals is configurable. Also, if commits are added after approvals were given, status is reset.
You can see it used at shelljs and enclave for examples.
If we agree this is a good move, I'll set it up right away.
watch is crashing on me when it comes across the autosave files produced by emacs. This is true even if I implement a filter function and/or use ignoreDotFiles
.
The error is: ENOENT, no such file or directory
.
In 0.17 argument splitting is now broken on OSX/Linux when single quotes are used correctly.
Basically:
Given package.json
:
"watch": "watch 'npm run css' ./src",
OSX/Linux
process.argv.slice(2) => ['npm run css', './src'] // OK
process.argv.slice(2).join(' ') => 'npm run css ./src'
require('splitargs')(process.argv.slice(2).join(' ')) => [ 'npm', 'run', 'css', './src']
Please see discussion in #80.
I use npm tasks as a build tool, I have these two tasks:
"scripts": {
"build:js": "babel -d lib/ src/",
"watch:js": "watch 'npm run build:js' src/"
}
Is there a way, using CLI, to execute babel
only on a changed file? Something like:
"scripts": {
"build:js": "babel -d lib/$CHANGED_FILE src/$CHANGED_FILE",
"watch:js": "watch --only-changed 'npm run build:js' src/"
}
Its possible to support windows ???
there are some kind of error in v.0.5.0 ...
Error: use fs.watch api instead
at Object.watchFile (fs.js:734:11)
at C:\Users\outaTiME\Development\projects\skycop\skyweb-mvc\node_modules\watch\main.js:56:10
at C:\Users\outaTiME\Development\projects\skycop\skyweb-mvc\node_modules\watch\main.js:83:5
at Object.oncomplete (C:\Users\outaTiME\Development\projects\skycop\skyweb-mvc\node_modules\watch\main.js:42:39)
and if we fix watchFile with watch ... another error comes (is change detected) ...
jake aborted.
TypeError: Object change has no method 'isDirectory'
at FSWatcher.<anonymous> (C:\Users\outaTiME\Development\projects\skycop\skyweb-mvc\node_modules\watch\main.js:60:23)
at FSWatcher.emit (events.js:70:17)
at FSEvent.onchange (fs.js:652:12)
thks !
I found it odd that I couldn't watch just one file, I have to watch a whole dir.
I'm sick and tired of these bad less watchers. Those has lead me to here. I still need a way to define file filter to use this instead.
Example:
watch "lessc style.less style.css" --globFilter **.less
globFilter
would make my life so much easier. Thanks.
Hi,
little WARN when installs ...
npm WARN [email protected] package.json: bugs['web'] should probably be bugs['url']
something wrong ??
thks !
Hi again,
no directory delete detection ... any ideas ?? other things works fine ...
there ... the code example ... the same in README file ...
watch.watchTree(target, function (f, curr, prev) {
if (typeof f == "object" && prev === null && curr === null) {
// Finished walking the tree
} else if (prev === null) {
console.log('New file: %s', f);
// f is a new file
} else if (curr.nlink === 0) {
// f was removed
console.log('File removed: %s', f);
} else {
// f was changed
console.log('File changed: %s', f);
}
});
when i delete directory from 'target' no file removed thrown :(
thks !
When is this going to be windows ready?
The problem is this one (line 44):
callback.pending -= 1;
if (!enoent) {
if (options.ignoreDotFiles && path.basename(f)[0] === '.') return;
if (options.filter && options.filter(f, stat)) return;
callback.files[f] = stat;
if (stat.isDirectory()) walk(f, options, callback);
if (callback.pending === 0) callback(null, callback.files);
}
If the script has reached the last file in the directory (callback.pending
would be 0 then) but gets filtered, the script would exit before the if (callback.pending === 0) callback(null, callback.files);
. So the callback wouldn't be fired, even if one of the files before has been approved by the filter.
I would be nice to be able to just get the library separate from the cli utility.
That way there would be no dependency in minimist and exec-sh
What do you think?
Is it possible? I tried something like:
paths
watch: 'libs/mikael/watch',
Then called the var watch = require('watch')
But watch
is always undefined
When I create a new directory in a root I'm watching, I get this error:
events.js:141
throw er; // Unhandled 'error' event
^
Error: EISDIR: illegal operation on a directory, read
at Error (native)
Is this the expected behavior?
Instead of waiting a certain number of seconds, waiting for the last executed command to finish might be desirable.
An option to wait a number of seconds since the command was last ran may also be nice. It differs from the current 'wait interval after file change' in that the first change after some idle interval can be reacted to immediately without delay, and throttling will happen only if changes happen more often than the specified interval.
Also, some kind of wait must be enabled by default, otherwise watch becomes a forkbomb if any kind of rapid file change (such as npm install) occurs in the watched directory.
Calling watch.createMonitor
just throws the error: fs.js:523 stat.addListener('change', listener);
for me...
walk
is calling back multiple times if the final entry in a directory is itself a directory.
On this line callback.pending
will be incremented, but the value of done
is not updated before calling back.
On Ubuntu 64bit precise fires oncreate twice.
I presume this is a known bug, may be the other process is touching the file twice but this is happening.
While watching dir on creation and removal events are emitted twice.
There are 6 PRs open going back to Oct of 2015. I've also been trying to get some movement on #84 since Mar 8. Please respond. This is a great package holding a superb npm name, it would be a bummer to see it go stale.
Also, (again) willing to help!
For example, I use createMonitor to monitor folder A
, if I copy a folder named a1
into A
, I get only one created event for folder a1
, all of the sub-files in folder a1
doesn't get fired created
event.
I think all files in the folder a1 should get "created" event fired, because the fire is indeed created.
When i use the Example Code:
watch.createMonitor('/home/mikeal', function (monitor) {
monitor.files['/home/mikeal/.zshrc'] // Stat object for my zshrc.
monitor.on("created", function (f, stat) {
// Handle file changes
})
monitor.on("changed", function (f, curr, prev) {
// Handle new files
})
monitor.on("removed", function (f, stat) {
// Handle removed files
})
}
The Create Events fire 2 times. Any reason why this could happen? I looked into the Code but have no idea.
Right now there are no automated tests. It would be kind of nice to add them, so that we could hook this up with travis and actually use npm test
. I personally like tape as a testing module.
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.