Comparing version 0.0.6 to 0.0.7
@@ -5,14 +5,15 @@ 'use strict'; | ||
var EventEmitter = require('events').EventEmitter | ||
var readInput = require('./read-input') | ||
var manifest = require('../lib/read/manifest') | ||
var forwardEvents = require('../lib/forward-events') | ||
var read = require('../lib/read') | ||
var fromStream = require('../lib/read/from-stream') | ||
var getAliases = require('../lib/read/get-aliases') | ||
var helpers = require('./helpers') | ||
var helpers = require('../lib/helpers') | ||
function aliases(opts) { | ||
var ev = new EventEmitter() | ||
readInput.openSomeInput(opts.file, function (err, input, filePath) { | ||
manifest.open(opts.file, function (err, input, filePath) { | ||
if (err) return helpers.bailoutEv(ev, err) | ||
var rt = readUnit(input, filePath) | ||
forwardEvents(ev, rt, function (errored, unit) { | ||
if (errored) return ev.emit('finish') | ||
var aliases | ||
@@ -34,3 +35,3 @@ try { aliases = getAliases(unit.relations) } | ||
var augmentError = function augmentError(err) { err.filePath = filePath } | ||
var rt = read.readUnit(input) | ||
var rt = fromStream.readUnit(input) | ||
forwardEvents(ev, rt, function unitReady(errored, unit) { | ||
@@ -37,0 +38,0 @@ if (errored) return ev.emit('finish') |
@@ -12,3 +12,3 @@ 'use strict'; | ||
var mkdirp = require('mkdirp') | ||
var helpers = require('./helpers') | ||
var helpers = require('../lib/helpers') | ||
var path = require('path') | ||
@@ -15,0 +15,0 @@ |
@@ -12,12 +12,13 @@ #!/usr/bin/env node | ||
var KNOWN_OPTS = { | ||
'dry-run': Boolean, 'file': String, 'silent': Boolean, 'robot': Boolean | ||
, 'force': Boolean, 'version': Boolean, 'shy': Boolean | ||
'dry-run': Boolean, 'file': String, 'robot': Boolean | ||
, 'version': Boolean, 'shy': Boolean | ||
} | ||
var SHORTHANDS = { | ||
'f': ['--file'], 'n': ['--dry-run'], 's': ['--silent'] | ||
, 'F': ['--force'], 'v': ['--version'], 'y': ['--shy'], 'r': ['--robot'] | ||
'f': ['--file'], 'n': ['--dry-run'] | ||
, 'v': ['--version'], 'y': ['--shy'], 'r': ['--robot'] | ||
} | ||
function main() { | ||
if (process.getuid && process.getuid() === 0) return noRoot() | ||
var opts = nopt(KNOWN_OPTS, SHORTHANDS) | ||
@@ -38,10 +39,8 @@ if (opts.version) return version() | ||
var finished = false | ||
var signal = null | ||
ev.on('error', function (err) { | ||
log('error', err) | ||
if (err.signal) signal = err.signal | ||
errored = true | ||
}).on('warning', function (err) { | ||
log('warning', err) | ||
}).on('finish', function () { | ||
}).on('finish', function (signal) { | ||
finished = true | ||
@@ -96,2 +95,8 @@ if (signal) return process.kill(process.pid, signal) | ||
function noRoot() { | ||
console.error('error: cowardly refusing to execute as root') | ||
console.error('error: bugs in the tool or recipes could cause grave losses') | ||
process.exit(9) | ||
} | ||
function version() { | ||
@@ -98,0 +103,0 @@ console.log(require('../package').version) |
@@ -8,3 +8,3 @@ 'use strict'; | ||
var common = require('./common') | ||
var helpers = require('./helpers') | ||
var helpers = require('../lib/helpers') | ||
var util = require('util') | ||
@@ -11,0 +11,0 @@ var dotify = require('../lib/graph/dotify') |
@@ -7,6 +7,6 @@ 'use strict'; | ||
var EventEmitter = require('events').EventEmitter | ||
var readInput = require('./read-input') | ||
var manifest = require('../lib/read/manifest') | ||
var forwardEvents = require('../lib/forward-events') | ||
var Scope = require('../lib/scope') | ||
var helpers = require('./helpers') | ||
var helpers = require('../lib/helpers') | ||
var refreshGraph = require('./refresh-graph') | ||
@@ -26,3 +26,3 @@ var errors = require('../lib/errors') | ||
var ev = new EventEmitter() | ||
var ri = readInput.readInput(manifestPath) | ||
var ri = manifest.read(manifestPath) | ||
forwardEvents(ev, ri, function inputRead(errored, data) { | ||
@@ -29,0 +29,0 @@ if (errored) return ev.emit('finish') |
@@ -13,3 +13,3 @@ 'use strict'; | ||
var forwardEvents = require('../lib/forward-events') | ||
var helpers = require('./helpers') | ||
var helpers = require('../lib/helpers') | ||
var errors = require('../lib/errors') | ||
@@ -16,0 +16,0 @@ var extractCliRefs = require('./extract-cli-refs') |
@@ -16,3 +16,3 @@ 'use strict'; | ||
var common = require('./common') | ||
var helpers = require('./helpers') | ||
var helpers = require('../lib/helpers') | ||
var errors = require('../lib/errors') | ||
@@ -25,2 +25,3 @@ | ||
var REM_ORPHAN = 'Removing orphan: %s' | ||
var SIG_ABORT = 'aborting on %s, recipe process will detach' | ||
@@ -38,3 +39,3 @@ var SIGS = ['SIGINT', 'SIGHUP', 'SIGTERM', 'SIGQUIT'] | ||
}) | ||
forwardEvents(ev, uev, function () { | ||
forwardEvents(ev, uev, function (errored, signal) { | ||
unregisterSigs(sigInfo) | ||
@@ -46,3 +47,3 @@ if (opts['dry-run']) return ev.emit('finish') | ||
s.end(function () { | ||
ev.emit('finish') | ||
ev.emit('finish', signal) | ||
}) | ||
@@ -67,7 +68,8 @@ }) | ||
st.updateMessage(st, null) | ||
res = runEdges(data.edges, re, os.cpus().length) | ||
var reOpts = {concurrency: os.cpus().length, shy: opts.shy} | ||
res = runEdges(data.edges, re, reOpts) | ||
ev.on('signal', function (signal) { | ||
if (signal !== 'SIGINT') { | ||
res.emit('signal', signal) | ||
for (var j in st.stopFns) st.stopFns[j]() | ||
res.abort(signal) | ||
for (var j in st.stopFns) st.stopFns[j](signal) | ||
return | ||
@@ -77,3 +79,3 @@ } | ||
}) | ||
return forwardEvents(ev, res, function (errored) { | ||
return forwardEvents(ev, res, function (errored, signal) { | ||
st.output.endUpdate() | ||
@@ -84,3 +86,3 @@ if (!errored) { | ||
} | ||
ev.emit('finish') | ||
ev.emit('finish', signal) | ||
}, function () { st.output.endUpdate() }) | ||
@@ -121,7 +123,8 @@ } | ||
}) | ||
st.stopFns[edge.index] = function stopRunEdge () { | ||
st.stopFns[edge.index] = function stopRunEdge (signal) { | ||
delete st.stopFns[edge.index] | ||
stopped = true | ||
st.updateMessage(st, edge) | ||
return cb(new Error('aborting, recipe process will detach')) | ||
var msg = util.format(SIG_ABORT, signal) | ||
return cb(new Error(msg)) | ||
} | ||
@@ -128,0 +131,0 @@ }) |
@@ -16,4 +16,4 @@ 'use strict'; | ||
var ug = updateGraph(data, opts) | ||
forwardEvents(ev, ug, function graphUpdated() { | ||
ev.emit('finish') | ||
forwardEvents(ev, ug, function graphUpdated(errored, signal) { | ||
ev.emit('finish', signal) | ||
}) | ||
@@ -20,0 +20,0 @@ }) |
@@ -12,3 +12,3 @@ 'use strict'; | ||
var common = require('./common') | ||
var helpers = require('./helpers') | ||
var helpers = require('../lib/helpers') | ||
var updateGraph = require('./update-graph') | ||
@@ -35,2 +35,3 @@ | ||
var truce = false | ||
var gz | ||
var update = debounce(function () { | ||
@@ -43,3 +44,7 @@ truce = true | ||
} | ||
forwardEvents(ev, updateGraph(data), function () { | ||
forwardEvents(ev, updateGraph(data), function (errored, signal) { | ||
if (signal !== 'SIGINT') { | ||
gz.close() | ||
return ev.emit('finish', signal) | ||
} | ||
truce = false | ||
@@ -49,3 +54,3 @@ }) | ||
}, DELAY_MS) | ||
gaze(patterns, function (err) { | ||
gz = gaze(patterns, function (err) { | ||
if (err) return helpers.bailoutEv(ev, err) | ||
@@ -52,0 +57,0 @@ if (!opts.robot) console.error('Watching...') |
@@ -25,7 +25,9 @@ 'use strict'; | ||
var args = Array.prototype.slice.call(arguments) | ||
args.unshift(errored) | ||
if (onFinish) return onFinish.apply(null, args) | ||
to.emit('finish') | ||
if (onFinish) { | ||
args.unshift(errored) | ||
return onFinish.apply(null, args) | ||
} | ||
to.emit.apply(to, ['finish'].concat(args)) | ||
}) | ||
return to | ||
} |
'use strict'; | ||
module.exports = mergeLists | ||
var errors = require('./errors') | ||
function mergeLists(a, b, comp) { | ||
if (!(a instanceof Array)) throw errors.invalidArg('a', a) | ||
if (!(b instanceof Array)) throw errors.invalidArg('b', b) | ||
if (typeof comp !== 'function') throw errors.invalidArg('comp', comp) | ||
a.sort(comp) | ||
@@ -6,0 +11,0 @@ b.sort(comp) |
@@ -6,50 +6,72 @@ 'use strict'; | ||
var EventEmitter = require('events').EventEmitter | ||
var errors = require('../errors') | ||
var SIG_ABORT = 'aborting because of signal: %s' | ||
function runEdges(edges, runEdge, opts) { | ||
if (!(edges instanceof Array)) throw errors.invalidArg('edges', edges) | ||
if (typeof runEdge !== 'function') | ||
throw errors.invalidArg('runEdge', runEdge) | ||
if (opts && !(opts instanceof Object)) | ||
throw errors.invalidArg('opts', opts) | ||
if (!opts) opts = { } | ||
if (opts.concurrency && | ||
(typeof opts.concurrency !== 'number' || opts.concurrency < 1)) | ||
throw errors.invalidArg('opts.concurrency', opts.concurrency) | ||
if (opts.shy && typeof opts.shy !== 'boolean') | ||
throw errors.invalidArg('opts.shy', opts.shy) | ||
return new RunEdgesTask(edges, runEdge, opts) | ||
} | ||
function runEdges(edges, runEdge, maxPending) { | ||
var st = { | ||
runEdge: runEdge | ||
, edges: edges | ||
, done: {} | ||
} | ||
var signal = null | ||
var task = new EventEmitter() | ||
task.on('signal', function (sig) { signal = sig }) | ||
util.inherits(RunEdgesTask, EventEmitter) | ||
function RunEdgesTask(edges, runEdge, opts) { | ||
this._concurrency = opts.concurrency || 1 | ||
this._shy = opts.shy || false | ||
this._isEdgeDone = {} | ||
for (var k = 0; k < edges.length; ++k) | ||
st.done[edges[k].index] = false | ||
var pending = 0 | ||
var queued = [] | ||
;(function nextEdges(edges) { | ||
queued = queued.concat(edges) | ||
edges = queued.splice(0, maxPending - pending) | ||
edges.forEach(function forEdge(edge) { | ||
pending++ | ||
runEdge(edge, function edgeRun(err) { | ||
pending-- | ||
if (!err) st.done[edge.index] = true | ||
if (err) { | ||
task.emit('error', err) | ||
if (err.signal) signal = err.signal | ||
} | ||
if (signal === null) | ||
return nextEdges(getReadyOutEdges(st, edge.outFiles)) | ||
if (pending > 0) return | ||
if (signal !== null) { | ||
var nerr = new Error(util.format(SIG_ABORT, signal)) | ||
nerr.signal = signal | ||
task.emit('error', nerr) | ||
} | ||
task.emit('finish') | ||
}) | ||
}) | ||
if (pending === 0) return task.emit('finish') | ||
})(getReadyEdges(st, edges)) | ||
return task | ||
this._isEdgeDone[edges[k].index] = false | ||
this._signal = null | ||
this._abort = false | ||
this._pending = 0 | ||
this._queue = [] | ||
this._runEdge = runEdge | ||
this._processEdge = this._processEdge.bind(this) | ||
this._processEdges(getReadyEdges(this._isEdgeDone, edges)) | ||
} | ||
function getReadyOutEdges(st, files) { | ||
RunEdgesTask.prototype._processEdges = function (edges) { | ||
this._queue = this._queue.concat(edges) | ||
edges = this._queue.splice(0, this._concurrency - this._pending) | ||
edges.forEach(this._processEdge) | ||
if (this._pending === 0) return this.emit('finish') | ||
} | ||
RunEdgesTask.prototype._processEdge = function (edge) { | ||
var self = this | ||
this._pending++ | ||
this._runEdge(edge, function edgeRun(err) { | ||
self._pending-- | ||
if (err) { | ||
self.emit('error', err) | ||
if (err.signal) self.abort(err.signal) | ||
else if (self._shy) self.abort() | ||
} else { | ||
self._isEdgeDone[edge.index] = true | ||
} | ||
if (!self._abort) { | ||
var nextEdges = getReadyOutEdges(self._isEdgeDone, edge.outFiles) | ||
return self._processEdges(nextEdges) | ||
} | ||
if (self._pending > 0) return | ||
self.emit('finish', self._signal) | ||
}) | ||
} | ||
RunEdgesTask.prototype.abort = function (signal) { | ||
this._abort = true | ||
if (signal) this._signal = signal | ||
} | ||
function getReadyOutEdges(isEdgeDone, files) { | ||
var edges = [] | ||
files.forEach(function (file) { | ||
edges = edges.concat(getReadyEdges(st, file.outEdges)) | ||
edges = edges.concat(getReadyEdges(isEdgeDone, file.outEdges)) | ||
}) | ||
@@ -59,9 +81,9 @@ return edges | ||
function getReadyEdges(st, edges) { | ||
function getReadyEdges(isEdgeDone, edges) { | ||
var readyEdges = [] | ||
for (var i = 0; i < edges.length; ++i) { | ||
var edge = edges[i] | ||
if (!st.done.hasOwnProperty(edge.index)) continue | ||
st.done[edge.index] = false | ||
if (isEdgeReady(st, edge)) readyEdges.push(edge) | ||
if (!isEdgeDone.hasOwnProperty(edge.index)) continue | ||
isEdgeDone[edge.index] = false | ||
if (isEdgeReady(isEdgeDone, edge)) readyEdges.push(edge) | ||
} | ||
@@ -71,10 +93,10 @@ return readyEdges | ||
function isEdgeReady(st, edge) { | ||
function isEdgeReady(isEdgeDone, edge) { | ||
for (var k = 0; k < edge.inFiles.length; ++k) { | ||
var file = edge.inFiles[k] | ||
if (file.inEdge === null) continue | ||
if (!st.done.hasOwnProperty(file.inEdge.index)) continue | ||
if (!st.done[file.inEdge.index]) return false | ||
if (!isEdgeDone.hasOwnProperty(file.inEdge.index)) continue | ||
if (!isEdgeDone[file.inEdge.index]) return false | ||
} | ||
return true | ||
} |
{ | ||
"name": "mekano", | ||
"version": "0.0.6", | ||
"version": "0.0.7", | ||
"description": "maintain, update and regenerate groups of files", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -169,4 +169,2 @@ # ![mekano](https://cdn.mediacru.sh/0hecryCVR3vS.svg) | ||
* `-r, --robot` Output machine-parseable text. | ||
* `-s, --silent` Be silent: don't write executed commands. | ||
* `-F, --force` Force things, like overwriting modified files. Dangerous. | ||
* `-v, --version` Output version and exit. | ||
@@ -173,0 +171,0 @@ |
114189
51
2715
432