2 Star 0 Fork 0

mirrors_Unitech / watch

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
main.js 3.99 KB
一键复制 编辑 原始数据 按行查看 历史
Jonathan D. Knezek 提交于 2013-04-08 12:54 . walk edge case fix
// Copyright 2010-2011 Mikeal Rogers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
var sys = require('util')
, fs = require('fs')
, path = require('path')
, events = require('events')
;
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) {
if (err) return callback(err);
callback.files[dir] = stat;
fs.readdir(dir, function (err, files) {
if (err) return callback(err);
callback.pending -= 1;
files.forEach(function (f, index) {
f = path.join(dir, f);
callback.pending += 1;
fs.stat(f, function (err, stat) {
var enoent = false
, done = false;
if (err) {
if (err.code !== 'ENOENT') {
return callback(err);
} else {
enoent = true;
}
}
callback.pending -= 1;
done = callback.pending === 0;
if (!enoent) {
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);
callback.files[f] = stat;
if (stat.isDirectory()) walk(f, options, callback);
done = callback.pending === 0;
if (done) callback(null, callback.files);
}
})
})
if (callback.pending === 0) callback(null, callback.files);
})
if (callback.pending === 0) callback(null, callback.files);
})
}
exports.watchTree = function ( root, options, callback ) {
if (!callback) {callback = options; options = {}}
walk(root, options, function (err, files) {
if (err) throw err;
var fileWatcher = function (f) {
fs.watchFile(f, options, function (c, p) {
// Check if anything actually changed in stat
if (files[f] && !files[f].isDirectory() && c.nlink !== 0 && files[f].mtime.getTime() == c.mtime.getTime()) return;
files[f] = c;
if (!files[f].isDirectory()) callback(f, c, p);
else {
fs.readdir(f, function (err, nfiles) {
if (err) return;
nfiles.forEach(function (b) {
var file = path.join(f, b);
if (!files[file] && (options.ignoreDotFiles !== true || b[0] != '.')) {
fs.stat(file, function (err, stat) {
callback(file, stat, null);
files[file] = stat;
fileWatcher(file);
})
}
})
})
}
if (c.nlink === 0) {
// unwatch removed files.
delete files[f]
fs.unwatchFile(f);
}
})
}
fileWatcher(root);
for (var i in files) {
fileWatcher(i);
}
callback(files, null, null);
})
}
exports.createMonitor = function (root, options, cb) {
if (!cb) {cb = options; options = {}}
var monitor = new events.EventEmitter();
exports.watchTree(root, options, function (f, curr, prev) {
if (typeof f == "object" && prev == null && curr === null) {
monitor.files = f;
return cb(monitor);
}
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);
})
}
exports.walk = walk;
1
https://gitee.com/mirrors_Unitech/watch.git
git@gitee.com:mirrors_Unitech/watch.git
mirrors_Unitech
watch
watch
master

搜索帮助