Skip to content

Commit

Permalink
Merge pull request #2 from SerCeMan/master
Browse files Browse the repository at this point in the history
Change fs.watch to node-watch plugin
  • Loading branch information
shafirov authored Sep 15, 2016
2 parents e39edae 207af9a commit f91a993
Showing 1 changed file with 299 additions and 7 deletions.
306 changes: 299 additions & 7 deletions src/main/resources/kwp.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 2,292 @@ var path = require("path");
var fs = require('fs')
var execSync = require('child_process').execSync
var isWin = /^win/.test(process.platform);
var isMacOs = 'darwin' == process.platform;

/**
* Node-watch npm package https://github.com/yuanchuan/node-watch
* MIT license http://www.opensource.org/licenses/mit-license.php
* Copyright (c) 2012-2016 Yuan Chuan <[email protected]>
*/
var watch = (function () {
/**
* Module dependencies.
*/
var fs = require('fs')
, path = require('path')
, events = require('events');


/**
* Utility functions to synchronously test whether the giving path
* is a file or a directory or a symbolic link.
*/
var is = function(ret) {
var shortcuts = {
'file': 'File'
, 'dir': 'Directory'
, 'sym': 'SymbolicLink'
};
Object.keys(shortcuts).forEach(function(method) {
var stat = fs[method === 'sym' ? 'lstatSync' :'statSync'];
ret[method] = function(fpath) {
try {
var yes = stat(fpath)['is' shortcuts[method]]();
memo.push(fpath, method);
return yes;
} catch(e) {}
}
});
return ret;
}({});


/**
* Get sub-directories in a directory.
*/
var sub = function(parent, cb) {
if (is.dir(parent)) {
fs.readdir(parent, function(err, all) {
all && all.forEach(function(f) {
var sdir = path.join(parent, f);
if (is.dir(sdir)) {
cb.call(null, sdir)
}
});
});
}
};


/**
* Mixing object properties.
*/
var mixin = function() {
var mix = {};
[].forEach.call(arguments, function(arg) {
for (var name in arg) {
if (arg.hasOwnProperty(name)) {
mix[name] = arg[name];
}
}
});
return mix;
};


/**
* A container for memorizing names of files or directories.
*/
var memo = function(memo) {
return {
push: function(name, type) {
memo[name] = type;
},
has: function(name) {
return {}.hasOwnProperty.call(memo, name);
},
update: function(name) {
if (!is.file(name) || !is.dir(name)) {
delete memo[name];
}
return true;
}
};
}({});


/**
* A Container for storing unique and valid filenames.
*/
var fileNameCache = function(cache) {
return {
push: function(name) {
cache[name] = 1;
return this;
},
each: function() {
var temp = Object.keys(cache).filter(function(name){
return is.file(name) || memo.has(name) && memo.update(name);
});
temp.forEach.apply(temp, arguments);
return this;
},
clear: function(){
cache = {};
return this;
}
};
}({});


/**
* Abstracting the way of avoiding duplicate function call.
*/
var worker = function() {
var free = true;
return {
busydoing: function(cb) {
if (free) {
free = false;
cb.call();
}
},
free: function() {
free = true;
}
}
}();


/**
* Delay function call and ignore invalid filenames.
*/
var normalizeCall = function(fname, options, cb, watcher) {
// Store each name of the modifying or temporary files generated by an editor.
fileNameCache.push(fname);

worker.busydoing(function() {
// A heuristic delay of the write-to-file process.
setTimeout(function() {

// When the write-to-file process is done, send all filtered filenames
// to the callback function and call it.
fileNameCache
.each(function(f) {
// Watch new created directory.
if (options.recursive && !memo.has(f) && is.dir(f)) {
watch(f, options, cb, watcher);
}
cb && cb.call(null, f);
watcher.emit('change', f);
}).clear();

worker.free();

}, 100);
});
};


/**
* Watcher class to simulate FSWatcher
*/
var Watcher = function Watcher() {
this.watchers = [];
this.closed = false;
this.close = function() {
this.watchers.forEach(function(watcher) {
watcher.close();
});
this.watchers = [];
this.closed = true;
};
this.addWatcher = function(watcher, cb) {
var self = this;
this.watchers.push(watcher);

watcher.on('error', function(err) {
self.emit('error', err);
});
};
};

Watcher.prototype.__proto__ = events.EventEmitter.prototype;


/**
* Option handler for the `watch` function.
*/
var handleOptions = function(origin, defaultOptions) {
return function() {
var args = [].slice.call(arguments);
args[3] = new Watcher;
if (Object.prototype.toString.call(args[1]) === '[object Function]') {
args[2] = args[1];
}
if (!Array.isArray(args[0])) {
args[0] = [args[0]];
}
//overwrite default options
args[1] = mixin(defaultOptions, args[1]);
//handle multiple files.
args[0].forEach(function(path) {
origin.apply(null, [path].concat(args.slice(1)));
});
return args[3];
}
};


/**
* Ignore the recursive option on platforms which natively support it,
* or temporarily set it to false for optimization.
*/
var noRecursive = function(option) {
return mixin(option, { recursive: false });
};


/**
* Watch a file or a directory (recursively by default).
*
* @param {String} fpath
* @options {Object} options
* @param {Function} cb
*
* Options:
* `recursive`: Watch it recursively or not (defaults to true).
* `followSymLinks`: Follow symbolic links or not (defaults to false).
* `maxSymLevel`: The max number of following symbolic links (defaults to 1).
* `filter`: Filter function(fullPath:string) => boolean (defaults to () => true ).
*
* Example:
*
* watch('fpath', { recursive: true }, function(file) {
* console.log(file, ' changed');
* });
*/
function watch(fpath, options, cb, watcher) {
var skip = watcher.closed || !options.filter(fpath) || (
is.sym(fpath) && !(options.followSymLinks && options.maxSymLevel--)
);
if (skip) return;

// Due to the unstable fs.watch(), if the `fpath` is a file then
// switch to watch its parent directory instead of watch it directly.
// Once the logged filename matches it then triggers the callback function.
if (is.file(fpath)) {
var parent = path.resolve(fpath, '..');
watcher.addWatcher(fs.watch(parent, noRecursive(options)).on('change', function(evt, fname) {
if (path.basename(fpath) === fname) {
normalizeCall(fname, options, cb, watcher);
}
}), cb);
}
else if (is.dir(fpath)) {
watcher.addWatcher(fs.watch(fpath, noRecursive(options)).on('change', function(evt, fname) {
normalizeCall(path.join(fpath, fname), options, cb, watcher);
}), cb);

if (options.recursive) {
// Recursively watch its sub-directories.
sub(fpath, function(dir) {
watch(dir, options, cb, watcher);
});
}
}
}

/**
* Set default options and expose.
*/
return handleOptions(watch, {
recursive: true
, followSymLinks: false
, maxSymLevel: 1
, filter: function(fullPath) { return true; }
});
})()


/* ##### MODULE ALIAS PLUGIN COPY-PASTED SO THIS DOESN"T HAVE ANY DEPENDENCIES
Expand Down Expand Up @@ -110,12 396,17 @@ KotlinWebpackPlugin.prototype.apply = function (compiler) {
if (running) return

running = true
console.log("\nRunning Gradle: " cmdline)
console.time("Done Gradle")
var stdout = execSync(cmdline)
// console.log(stdout)
console.timeEnd("Done Gradle")
running = false
try {
console.log("\nRunning Gradle: " cmdline)
console.time("Done Gradle")
var stdout = execSync(cmdline)
// console.log(stdout)
console.timeEnd("Done Gradle")
} catch (err) {
console.error("Gradle task ended with an error", err)
} finally {
running = false
}
}

execGradle()
Expand All @@ -124,7 415,8 @@ KotlinWebpackPlugin.prototype.apply = function (compiler) {
for (var i = 0; i < deps.length; i ) {
var t = deps[i].trim()
if (t.length > 0) {
fs.watch(t, {
var watchFn = isWin || isMacOs ? fs.watch : watch
watchFn(t, {
recursive: true,
persistent: false
}, execGradle)
Expand Down

0 comments on commit f91a993

Please sign in to comment.