diff --git a/core/cb.watch/init.js b/core/cb.watch/init.js deleted file mode 100644 index 52a1ae3c..00000000 --- a/core/cb.watch/init.js +++ /dev/null @@ -1,129 +0,0 @@ -// Requires -var Q = require('q'); -var _ = require('lodash'); -var path = require('path'); -var watchr = require('watchr'); - -var batch = require('../utils').batch; - - -function init(logger, events, rootPath) { - var d = Q.defer(); - - // Normalize paths - function normalize(fullPath) { - return path.normalize( - '/' + path.relative(rootPath, fullPath) - ); - } - - logger.log('Starting Watch'); - // Construct - watchr.watch({ - paths: [rootPath], - - // Following links causes issues with broken symlinks - // crashing the whole watchr instance and thus codebox - // so disabling link following for now - followLinks: false, - - listeners: { - log: function(logLevel) { - /* - events.emit('watch.log', { - level: logLevel, - args: _.toArray(arguments) - }); - */ - }, - error: function(err) { - events.emit('watch.error', err); - }, - watching: function(err, watcherInstance, isWatching) { - var emitStr = 'watch.watching.' + (err ? 'error' : 'success'); - var info = { - watching: isWatching, - state: watcherInstance.state, - path: normalize(watcherInstance.path), - error: err || null - }; - - events.emit(emitStr, info); - }, - change: batch(function(changeType, filePath, fileCurrentStat, filePreviousStat) { - // Simply queue the data for our batch processor - return { - change: changeType, - path: normalize(filePath), - stats: { - current: fileCurrentStat, - old: filePreviousStat - } - }; - }, function process(eventList) { - // Aggregate events by folder - var folderEvents = _(eventList).reduce(function(context, e) { - // Aggregate by parent folder of changed path - var key = path.dirname(e.path); - - // Set list if empty - if(context[key] === undefined) { - context[key] = []; - } - - // Add event to folder's event list - context[key].push(e); - - return context; - }, {}); - - // Refresh each of those changed folders - _.each(folderEvents, function(eventList, folder) { - // Many events, so group by folder - if(eventList.length >= 3) { - // Send out aggregated event - return events.emit('watch.change.folder', { - change: 'folder', - path: folder - }); - } - - // Few events so send them out individually - _.each(eventList, function(e) { - events.emit( - // e.change can be any of - // ['updated', 'created', 'deleted'] - 'watch.change.'+e.change, - - // Actual event data - e - ); - - }); - }); - - - }, { - // Debounce 200ms - debounce: 100, - - // Force processing every 1000 events - n: 1000 - }) - }, - next: function(err, watchers) { - // Fail building Codebox on error - if (err) { - return d.reject(err); - } - - return d.resolve(watchers); - } - }); - - return d.promise; -} - - -// Exports -exports.init = init; diff --git a/core/cb.watch/main.js b/core/cb.watch/main.js index 4fc4da2a..3b03edf0 100644 --- a/core/cb.watch/main.js +++ b/core/cb.watch/main.js @@ -1,6 +1,6 @@ // Requires var _ = require('lodash'); -var init = require('./init').init; +var Watcher= require('./watcher'); function setup(options, imports, register) { @@ -8,10 +8,10 @@ function setup(options, imports, register) { var events = imports.events; var logger = imports.logger.namespace("watch"); + var watcher = new Watcher(logger, events); + register(null, { - "watch": { - init: _.partial(init, logger, events) - } + "watch": watcher }); } diff --git a/core/cb.watch/watcher.js b/core/cb.watch/watcher.js new file mode 100644 index 00000000..20248681 --- /dev/null +++ b/core/cb.watch/watcher.js @@ -0,0 +1,132 @@ +// Requires +var Q = require('q'); +var _ = require('lodash'); +var path = require('path'); +var fs = require('fs'); +var harmonycollections = require("harmony-collections"); + +// Hack for pathwatcher and not be dependant on node option --harmony +global.WeakMap = harmonycollections.WeakMap; + +var PathWatcher = require("pathwatcher"); + +var batch = require('../utils').batch; + +var Watcher = function(logger, events) { + this.logger = logger; + this.events = events; + this.rootPath = "/"; + this.watchers = {}; +} + +// Init te watcher with a root path +Watcher.prototype.init = function(rootPath) { + this.logger.log("init", rootPath); + this.rootPath = rootPath; + this.start("./"); + this.start("./hello.py"); +} + +// Normalize a path to the root path +Watcher.prototype.normalize = function(fullPath) { + return path.normalize( + '/' + path.relative(this.rootPath, fullPath) + ); +} + +// Start watching a path +Watcher.prototype.start = function(basePath) { + var that = this; + + // already watching this file + if (this.watchers[basePath]) return; + + this.logger.log("start", basePath); + + this.watchers[basePath] = PathWatcher.watch(path.join(this.rootPath, basePath), function() { + console.log(basePath, arguments); + }); + this.watchers[basePath].handleWatcher.on("change", function() { + console.log(basePath, "2", arguments); + }); + + /*this.watchers[basePath] = fs.watch( + path.join(this.rootPath, basePath), + { + + }, + batch(function(changeType, filePath) { + console.log(changeType, filePath); + // Simply queue the data for our batch processor + return { + change: changeType, + path: that.normalize(filePath), + stats: { + current: {}, + old: {} + } + }; + }, function process(eventList) { + // Aggregate events by folder + var folderEvents = _(eventList).reduce(function(context, e) { + // Aggregate by parent folder of changed path + var key = path.dirname(e.path); + + // Set list if empty + if(context[key] === undefined) { + context[key] = []; + } + + // Add event to folder's event list + context[key].push(e); + + return context; + }, {}); + + // Refresh each of those changed folders + _.each(folderEvents, function(eventList, folder) { + // Many events, so group by folder + if(eventList.length >= 3) { + // Send out aggregated event + return that.events.emit('watch.change.folder', { + change: 'folder', + path: folder + }); + } + + // Few events so send them out individually + _.each(eventList, function(e) { + events.emit( + // e.change can be any of + // ['updated', 'created', 'deleted'] + 'watch.change.'+e.change, + + // Actual event data + e + ); + + }); + }); + }) + )*/ +} + +// Stop watching a path +Watcher.prototype.stop = function (basePath) { + + this.logger.log("stop", rootPath); + + if (!this.watchers[basePath]) { + this.logger.error("Trying to stop inexistant watcher"); + } else { + this.watchers[basePath].close(); + delete this.watchers[basePath]; + + this.events.emit("watch.stop", { + path: this.normalize(basePath) + }); + } +} + +// Exports +module.exports = Watcher; diff --git a/package.json b/package.json index 0cd3a5e6..d06f7255 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "vfs-http-adapter": "git+https://github.com/AaronO/vfs-http-adapter.git#6c9934e4f2da7886310397170b6ebaf745833936", "vfs-local": "git+https://github.com/FriendCode/vfs-local.git#af6bafede0ccb9fb362a0c280e708648f7363f33", "watchr": "2.4.11", + "pathwatcher": "0.19.0", "gittle": "0.2.2", "uuid": "1.4.1", "glob": "3.2.6",