Comparing version 0.5.1 to 0.6.0
@@ -0,1 +1,8 @@ | ||
0.6.0 / 2015-05-06 | ||
================== | ||
* **HOT CODE RELOADING AND BAD ERROR HANDLING REMOVED** | ||
* Reload functionality should be implemented outside gu with chokidar | ||
- process isolation of `gu` would provide a safer reload environment | ||
- `load` and `unload` methods provide the base logic for watchers | ||
0.5.0 / 2015-04-05 | ||
@@ -2,0 +9,0 @@ ================== |
50
gu.js
var smell = require('smell'); | ||
var path = require('path'); | ||
var hotReload = require('hot-reload'); | ||
var Duplex = require('stream').Duplex; | ||
@@ -23,40 +22,27 @@ | ||
this.verbose = !!opts.verbose; | ||
this.reload(true); | ||
if (!opts.noReload) { // hard to test gu when reload watchers keeps process alive | ||
hotReload.create(require) | ||
.loggingEnabled(!!opts.hotLogging) | ||
.watch(scriptPath) | ||
.uncache(scriptPath, true) | ||
.reload(scriptPath, true) | ||
.afterReload(this.reload.bind(this)) | ||
.start(); | ||
} | ||
this.unload(); | ||
this.load(); | ||
} | ||
Gu.prototype = Object.create(Duplex.prototype); | ||
// this should not be used by implementations | ||
Gu.prototype.reload = function (first) { | ||
// helpers for chokidar watchers | ||
Gu.prototype.unload = function () { | ||
// stop handlers from being intercepted | ||
this.handlers = []; | ||
// force reload of all files next time | ||
this.files.forEach(function (f) { | ||
if (require.cache[f]) { | ||
this.log.info('Unloaded handlers from', f); | ||
} | ||
delete require.cache[f]; | ||
}); | ||
}; | ||
Gu.prototype.load = function () { | ||
// require all files on the passed in scripts list to reattach handlers | ||
for (var i = 0; i < this.files.length; i += 1) { | ||
var f = this.files[i]; | ||
// try catch to avoid reloaded-syntax errors to keep the bot online | ||
try { | ||
var fn = require(f); | ||
if (!fn || 'function' !== typeof fn) { | ||
throw new Error("module.exports from file " + | ||
f + " in scripts directory is not a function" | ||
); | ||
} | ||
fn(this, this.injected); | ||
if (!first) { | ||
this.log.info('Reloaded handlers from', f); | ||
} | ||
} | ||
catch (e) { | ||
// some files failed to load - ignore these scripts | ||
this.log.error('FAILED TO LOAD', f); | ||
this.log.error(e.stack); | ||
} | ||
var fn = require(f); | ||
fn(this, this.injected); | ||
this.log.info('Loaded handlers from', f); | ||
} | ||
@@ -63,0 +49,0 @@ }; |
{ | ||
"name": "gu", | ||
"description": "Streaming bot makers library with hot code reloading and regex handlers", | ||
"description": "Streaming bot makers library with regex handlers", | ||
"author": "Eirik Albrigtsen <analsandblaster@gmail.com>", | ||
"version": "0.5.1", | ||
"version": "0.6.0", | ||
"repository": { | ||
@@ -12,4 +12,2 @@ "type": "git", | ||
"bot", | ||
"regex", | ||
"hotswap", | ||
"duplex" | ||
@@ -25,4 +23,3 @@ ], | ||
"dependencies": { | ||
"smell": "^2.0.2", | ||
"hot-reload": "1.4.2-beta" | ||
"smell": "^2.0.2" | ||
}, | ||
@@ -29,0 +26,0 @@ "devDependencies": { |
@@ -9,6 +9,5 @@ # gu | ||
It has three main features: | ||
It has two main features: | ||
- regular expression handlers in a style similar to [hubot](https://github.com/github/hubot) (but without all those annoying environment variables and coffee-script..) | ||
- hot code reloading of specified files (without the bot having to leave the server) | ||
- streaming input and output allows for easy control, extensibility and transport-less testing of handlers | ||
@@ -82,13 +81,2 @@ | ||
## Caveats | ||
### What files are reloaded | ||
The script path you specify to `gu` should only contain the handler functions. If you point the path at your `lib` dir, then it may reload all the files in that directory when you change one of your handlers. | ||
If you have multiple handler files in your `scriptdir`, then if one changes, all these files will be reloaded, and any internal state in them will be cleared. To get around this, persist important state elsewhere. | ||
### When things can still go wrong | ||
If you save one of the reload-watched files, and there's a syntax error, we will catch this error for you. An exception and a stack trace will be logged and all the handlers from the file with the error will be inactive. | ||
However, it is possible to save a file that looks valid but will have a runtime error, for instance referencing an undefined variable. This we will not guard on (otherwise we'd have to try-catch _everything_), and your bot will crash. Thus, you should use a fast-response linter to prevent this from happening. | ||
## Options | ||
@@ -99,4 +87,2 @@ A few options can be passed along to the `gu` instance as the third parameter, these are: | ||
{ | ||
noReload: Boolean, // disable the hot-reload module (a must for handler tests) | ||
hotLogging: Boolean, // enable logging from the hot-reload module | ||
verbose: Boolean // enable regex match log when gu receives messages | ||
@@ -126,3 +112,3 @@ } | ||
```bash | ||
```sh | ||
$ npm install gu | ||
@@ -129,0 +115,0 @@ ``` |
var Gu = require(process.env.GU_COV ? '../gu-cov' : '../') | ||
, sulfur = require('sulfur') | ||
, fs = require('fs') | ||
, join = require('path').join | ||
@@ -11,3 +10,2 @@ ; | ||
var exBot = new Gu(scriptsPath, ['dice.js', 'weather.js'], { | ||
noReload: true, | ||
verbose: true | ||
@@ -39,36 +37,1 @@ }); | ||
}; | ||
exports.hotReload = function (t) { | ||
var h1 = 'gu.handle(/hi/, function (say) { say("a"); });'; | ||
var h2 = 'gu.handle(/hi/, function (say) { say("b"); });'; | ||
var makeScript = function (h) { | ||
return 'module.exports = function (gu) { ' + h + ' };'; | ||
}; | ||
var scriptsPath = join(__dirname, 'scripts'); | ||
var tempFile = join(scriptsPath, 'temp.js'); | ||
fs.writeFileSync(tempFile, makeScript(h1)); | ||
var rBot = new Gu(scriptsPath, ['temp.js']); | ||
var ys = []; | ||
rBot.on('data', function (y) { | ||
ys.push(y); | ||
}); | ||
rBot.write({user: 'clux', message: 'hi'}); | ||
setTimeout(function () { | ||
t.equal(ys[0].message, "a", "first message uses first handler"); | ||
fs.writeFileSync(tempFile, makeScript(h2)); | ||
setTimeout(function () { | ||
rBot.write({user: 'clux', message: 'hi2'}); | ||
setTimeout(function () { | ||
t.equal(ys[1].message, "b", "second message uses second handler"); | ||
fs.unwatchFile(tempFile); | ||
fs.unlinkSync(tempFile); | ||
t.done(); | ||
setTimeout(function () { | ||
process.exit(0); // can't easily kill reload watchers unfortunately | ||
}, 10); | ||
}, 10); | ||
}, 10); | ||
}, 10); | ||
}; |
Sorry, the diff of this file is not supported yet
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
1
3
12658
148
123
- Removedhot-reload@1.4.2-beta
- Removeddirectory-walker@1.2.5(transitive)
- Removedhot-reload@1.4.2-beta(transitive)
- Removedjsonminify@0.2.3(transitive)
- Removedpath-filters@1.0.6(transitive)
- Removedproperty-handlers@0.1.0(transitive)
- Removedq@1.0.1(transitive)