New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

weaver

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

weaver - npm Package Compare versions

Comparing version
0.1.2
to
0.2.0
+67
t/11-cwd.coffee
assert = require('assert')
weaver = require('../lib/weaver.js')
exec = require('child_process').exec
write = require('fs').writeFileSync
unlink = require('fs').unlinkSync
daemon = '../bin/weaver'
port = 58011
config = "#{__dirname}/weaver_#{port}.json"
options =
cwd: __dirname
env:
PATH: process.env.PATH
WEAVER_TEST: 1
WEAVER_PORT: port
(require 'vows')
.describe('cwd')
.addBatch
start:
topic: ->
# Write config
write config, JSON.stringify
tasks:
base:
cwd: '..'
count: 2
executable: yes
source: 't/bin/sleep'
arguments: [[2011, 2111]]
# Start daemon
exec "#{daemon} --config #{config}", options, @callback
return
code: (error, stdout, stderr) -> assert not error
stdout: (error, stdout, stderr) -> assert not stdout
stderr: (error, stdout, stderr) -> assert not stderr
status:
topic: ->
# Check status
exec "#{daemon} status --nocolor", options, (args...) =>
args[1] = args[1]
.replace(/\n$/, '')
.split(/\n/)
.map(($_) -> +/^\s*(\d+)/.exec($_)[1])
@callback(args...)
return
code: (error, stdout, stderr) -> assert not error
stderr: (error, stdout, stderr) -> assert not stderr
stdout: (error, stdout, stderr) -> assert.equal stdout.length, 3
exit:
topic: ->
# Remove config file
unlink config
# Stop daemon
exec "#{daemon} exit", options, @callback
return
code: (error, stdout, stderr) -> assert not error
stdout: (error, stdout, stderr) -> assert not stdout
stderr: (error, stdout, stderr) -> assert not stderr
.export(module)
assert = require('assert')
weaver = require('../lib/weaver.js')
exec = require('child_process').exec
write = require('fs').writeFileSync
unlink = require('fs').unlinkSync
daemon = '../bin/weaver'
port = 58012
config = "#{__dirname}/weaver_#{port}.json"
options =
cwd: __dirname
env:
PATH: process.env.PATH
WEAVER_TEST: 1
WEAVER_PORT: port
(require 'vows')
.describe('path')
.addBatch
start:
topic: ->
# Write config
write config, JSON.stringify
path: '../lib'
tasks:
base:
cwd: '../bin'
count: 3
executable: yes
source: '../t/bin/sleep'
arguments: [[3012, 3112, 3212]]
# Start daemon
exec "#{daemon} --config #{config}", options, @callback
return
code: (error, stdout, stderr) -> assert not error
stdout: (error, stdout, stderr) -> assert not stdout
stderr: (error, stdout, stderr) -> assert not stderr
status:
topic: ->
# Check status
exec "#{daemon} status --nocolor", options, (args...) =>
args[1] = args[1]
.replace(/\n$/, '')
.split(/\n/)
.map(($_) -> +/^\s*(\d+)/.exec($_)[1])
@callback(args...)
return
code: (error, stdout, stderr) -> assert not error
stderr: (error, stdout, stderr) -> assert not stderr
stdout: (error, stdout, stderr) -> assert.equal stdout.length, 4
exit:
topic: ->
# Remove config file
unlink config
# Stop daemon
exec "#{daemon} exit", options, @callback
return
code: (error, stdout, stderr) -> assert not error
stdout: (error, stdout, stderr) -> assert not stdout
stderr: (error, stdout, stderr) -> assert not stderr
.export(module)
assert = require('assert')
weaver = require('../lib/weaver.js')
exec = require('child_process').exec
write = require('fs').writeFileSync
unlink = require('fs').unlinkSync
daemon = '../bin/weaver'
port = 58013
config = "#{__dirname}/weaver_#{port}.json"
options =
cwd: __dirname
env:
PATH: process.env.PATH
WEAVER_TEST: 1
WEAVER_PORT: port
(require 'vows')
.describe('binary')
.addBatch
start:
topic: ->
# Write config
write config, JSON.stringify
path: '../lib'
tasks:
base:
count: 1
executable: yes
source: 'bin/borken'
# Start daemon
exec "#{daemon} --config #{config}", options, @callback
return
code: (error, stdout, stderr) -> assert not error
stdout: (error, stdout, stderr) -> assert not stdout
stderr: (error, stdout, stderr) -> assert not stderr
status:
topic: ->
# Check status
exec "#{daemon} status --nocolor", options, (args...) =>
args[1] = args[1]
.replace(/\n$/, '')
.split(/\n/)
.map(($_) -> +/^\s*(\d+)/.exec($_)[1])
@callback(args...)
return
code: (error, stdout, stderr) -> assert not error
stderr: (error, stdout, stderr) -> assert not stderr
stdout: (error, stdout, stderr) -> assert.equal stdout.length, 2
pid: (error, stdout, stderr) -> assert.equal stdout[1], 0
exit:
topic: ->
# Remove config file
unlink config
# Stop daemon
exec "#{daemon} exit", options, @callback
return
code: (error, stdout, stderr) -> assert not error
stdout: (error, stdout, stderr) -> assert not stdout
stderr: (error, stdout, stderr) -> assert not stderr
.export(module)
assert = require('assert')
weaver = require('../lib/weaver.js')
exec = require('child_process').exec
write = require('fs').writeFileSync
unlink = require('fs').unlinkSync
daemon = '../bin/weaver'
port = 58014
config = "#{__dirname}/weaver_#{port}.json"
options =
cwd: __dirname
env:
PATH: process.env.PATH
WEAVER_TEST: 1
WEAVER_PORT: port
status = []
(require 'vows')
.describe('drop')
.addBatch
start:
topic: ->
# Write config
write config, JSON.stringify
tasks:
s1:
count: 4
executable: yes
source: 'sleep'
arguments: [4014]
s2:
count: 2
executable: yes
source: 'sleep'
arguments: [2014]
# Start daemon
exec "#{daemon} --config #{config}", options, @callback
return
code: (error, stdout, stderr) -> assert not error
stdout: (error, stdout, stderr) -> assert not stdout
stderr: (error, stdout, stderr) -> assert not stderr
status:
topic: ->
# Check status
exec "#{daemon} status --nocolor", options, (args...) =>
args[1] = args[1]
.replace(/\n$/, '')
.split(/\n/)
.map(($_) -> +/^\s*(\d+)/.exec($_)[1])
@callback(args...)
return
code: (error, stdout, stderr) -> assert not error
stderr: (error, stdout, stderr) -> assert not stderr
stdout: (error, stdout, stderr) -> assert.equal stdout.length, 7
drop:
topic: (pid) ->
# Drop second group
exec "#{daemon} drop s2", options, =>
# Get configuration dump
exec "#{daemon} dump --nocolor", options, (args...) =>
dump = JSON.parse args[1]
# Check status
exec "#{daemon} status --nocolor", options, (args...) =>
@callback(args..., pid, dump)
return
code: (error, stdout, stderr, pid, dump) -> assert not error
dump: (error, stdout, stderr, pid, dump) -> assert not dump.hasOwnProperty 's2'
stderr: (error, stdout, stderr, pid, dump) -> assert not stderr
stdout: (error, stdout, stderr, pid, dump) ->
status = stdout
.replace(/\n$/, '')
.split(/\n/)
.map(($_) -> +/^\s*(\d+)/.exec($_)[1])
assert.equal status.length, 5
assert.match stdout, /^(?:[\s\S](?!s2))+$/
assert.equal pid[1], status[1]
assert.equal pid[2], status[2]
assert.equal pid[3], status[3]
assert.equal pid[4], status[4]
exit:
topic: ->
# Remove config file
unlink config
# Stop daemon
exec "#{daemon} exit", options, @callback
return
code: (error, stdout, stderr) -> assert not error
stdout: (error, stdout, stderr) -> assert not stdout
stderr: (error, stdout, stderr) -> assert not stderr
.export(module)

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

+9
-0
# Changelog
## 0.2.0
Released 2016-02-26
* Upgrade extends weaver configuration instead of replacing it
* Added drop command
* Fixed argument validation for kill command
* Fixed crash on broken executables
## 0.1.2

@@ -4,0 +13,0 @@

+105
-105
'use strict';
var fs = require('fs'),
assert = require('assert'),
util = require('util'),
events = require('events'),
assert = require('assert'),
dirname = require('path').dirname,
resolve = require('path').resolve,

@@ -37,3 +35,5 @@ fork = require('child_process').spawn,

*/
function Weaver () {}
function Weaver () {
return this;
}

@@ -103,15 +103,8 @@ util.inherits(Weaver, events.EventEmitter);

* Parsed configuration file
* @property parameters
* @property config
* @type Object
*/
define('property', 'parameters', {});
define('property', 'config', Object.create(null), { writable: false });
/**
* Path to configuration file
* @property file
* @type String
*/
define('property', 'file', '');
/**
* Extend Weaver with property or method

@@ -127,3 +120,2 @@ * @method define

* @param {Object} options
* @chainable
*/

@@ -141,9 +133,10 @@ define('method', 'task', Task);

* @method validate
* @param {Object} config
* @param {Object} configuration
* @return {Object} Valid configuration
*/
define('method', 'validate', function (config) {
var tasks = config.tasks;
define('method', 'validate', function (configuration) {
var tasks = configuration.tasks;
/* Validate schema */
assert.ok(validator.validate(config, schema), 'Invalid configuration');
assert.ok(validator.validate(configuration, schema), 'Invalid configuration');

@@ -171,3 +164,3 @@ /* Perform additional validation */

return config;
return configuration;
});

@@ -179,3 +172,2 @@

* @param {Number} code Exit code
* @chainable
*/

@@ -205,4 +197,2 @@ define('method', 'die', function (code) {

}, timeout);
return this;
});

@@ -214,6 +204,7 @@

* @param {String} data Configuration data
* @chainable
* @param {String} path Configuration path
*/
define('method', 'upgrade', function (data) {
var parameters;
define('method', 'upgrade', function (data, path) {
var parts = [path],
params;

@@ -225,14 +216,28 @@ try {

/* Validate new state */
parameters = this.validate(data);
params = this.validate(data);
} catch (error) {
error.message = 'Config error: ' + error.message;
this.emit('error', error);
}
if (parameters) {
this.parameters = parameters;
if (params) {
if (params.path) {
parts.push(params.path);
}
Object.keys(params.tasks)
.map(function (name) {
return params.tasks[name];
}).forEach(function (task) {
task.cwd = resolve.apply(undefined, parts.concat(task.cwd || '.'));
});
Object.keys(params.tasks)
.forEach(function (name) {
weaver.config[name] = params.tasks[name];
});
this.emit('upgrade');
}
return this;
});

@@ -281,3 +286,2 @@

* @param {Array} args Arguments
* @chainable
*/

@@ -319,4 +323,2 @@ define('method', 'command', function (action, name, args) {

}
return this;
});

@@ -334,20 +336,2 @@

/**
* Fired when configuration file should be re-read
* @event config
*/
define('handler', 'config', function () {
var that = this;
if (this.file) {
fs.readFile(this.file, function (error, data) {
if (error) {
that.emit('error', error);
} else {
that.upgrade(data);
}
});
}
});
/**
* Fired when tasks should be checked and upgraded

@@ -357,18 +341,7 @@ * @event upgrade

define('handler', 'upgrade', function () {
var tasks = this.parameters.tasks,
path = this.parameters.path || '',
name;
var name;
if (path[0] !== '/') {
path = dirname(this.file) + '/' + path;
}
this.path = resolve(path);
for (name in tasks) {
/* Set cwd for tasks */
tasks[name].cwd = tasks[name].cwd || this.path;
for (name in this.config) {
/* Create or update task */
this.task(name, tasks[name]);
this.task(name, this.config[name]);
}

@@ -390,2 +363,4 @@ });

* @constructor
* @param {String} name Task group name
* @param {Object} options Task group configuration
*/

@@ -403,2 +378,3 @@ function Task (name, options) {

task.upgrade(options);
return task;

@@ -442,5 +418,3 @@ }

if (options) {
this.upgrade(options);
}
this.upgrade(options);

@@ -522,25 +496,20 @@ return this;

* @method upgrade
* @param {Object} parameters
* @chainable
* @param {Object} options Task group configuration
*/
define('method', 'upgrade', function (parameters) {
var restart = false,
define('method', 'upgrade', function (options) {
var that = this,
restart = false,
i, l, pid, subtask, key;
/* Change parameters */
if (parameters) {
for (key in mutable) {
/* Upgrade parameters */
Object.keys(mutable)
.forEach(function (key) {
try {
if (this.hasOwnProperty(key) || key in parameters) {
assert.deepEqual(this[key], parameters[key]);
}
assert.deepEqual(that[key], options[key]);
} catch (change) {
this.upgradeParameter(key, parameters);
that.upgradeParameter(key, options[key]);
if (!mutable[key]) {
restart = true;
}
restart = restart || !mutable[key];
}
}
}
});

@@ -550,2 +519,3 @@ /* Restart on demand */

weaver.log(sprintf('Restart required for %s task group', this.name));
this.restartSubtasks();

@@ -570,11 +540,12 @@ }

/**
* Upgrade task parameter with value from parameters object
* Upgrade task parameter with value
* @method upgradeParameter
* @param {String} key
* @param {Object} parameters
* @param {String} key Parameter name
* @param {Object} value Parameter value
*/
define('method', 'upgradeParameter', function (key, parameters) {
define('method', 'upgradeParameter', function (key, value) {
switch (key) {
case 'watch':
this.watch = parameters.watch || [];
this.watch = value || [];
Watcher.stop(this.watchHandler);

@@ -585,6 +556,6 @@ Watcher.start(weaver, this.cwd, this.watch, this.watchHandler);

default:
if (key in parameters) {
this[key] = parameters[key];
if (null == value) {
delete this[key];
} else {
delete this[key];
this[key] = value;
}

@@ -630,3 +601,4 @@ }

* @method get
* @param {Number} pid
* @param {Number} pid
* @return {Object} Subtask
*/

@@ -689,16 +661,27 @@ define('method', 'get', function (pid) {

/* Get subtask pid */
subtask.pid = subtask.process.pid;
subtask.pid = subtask.process.pid || 0;
p1 = sprintf('%u (%s) ', subtask.pid, subtask.name);
p2 = sprintf('%u [%s] ', subtask.pid, subtask.name);
if (subtask.pid) {
p1 = sprintf('%u (%s) ', subtask.pid, subtask.name);
p2 = sprintf('%u [%s] ', subtask.pid, subtask.name);
/* Setup logger */
subtask.process.stdout.on('data', this.log.bind(this, p1));
subtask.process.stderr.on('data', this.log.bind(this, p2));
/* Setup logger */
subtask.process.stdout.on('data', this.log.bind(this, p1));
subtask.process.stderr.on('data', this.log.bind(this, p2));
/* Setup exit handler */
subtask.process.once('exit', this.exitHandler.bind(this, subtask));
/* Setup exit handler */
subtask.process.once('exit', this.exitHandler.bind(this, subtask));
weaver.log(sprintf('Task %u (%s) spawned', subtask.pid, subtask.name));
weaver.log(sprintf('Task %u (%s) spawned', subtask.pid, subtask.name));
} else {
subtask.status = 'E';
subtask.code = 255;
subtask.process.once('error', function (error) {
weaver.emit('error', error);
});
weaver.log(sprintf('Failed to start task (%s)', subtask.name));
}
this.subtasks[id] = subtask;

@@ -859,3 +842,4 @@ }, { target: Task.prototype });

define('method', 'exitHandler', function (subtask, code, signal) {
var elapsed;
var restart = this.persistent,
elapsed;

@@ -890,3 +874,3 @@ if (code === null) {

if (this.persistent && code) {
if (restart && code) {
elapsed = Date.now() - subtask.start;

@@ -899,9 +883,25 @@

));
return;
restart = false;
}
}
if (this.persistent || subtask.status === 'R') {
if (subtask.status === 'R') {
/* Restart was requested */
restart = true;
}
if (!(this.name in weaver.config)) {
/* Task was dropped */
restart = false;
if (!this.subtasks.filter(function (subtask) { return !!subtask.pid }).length) {
/* All subtasks were stopped */
delete weaver.tasks[this.name];
}
}
if (restart) {
this.spawn(subtask.id);
}
}, { target: Task.prototype });
{
"name" : "weaver",
"version" : "0.1.2",
"version" : "0.2.0",
"license" : "LGPL-3.0",

@@ -5,0 +5,0 @@ "author" : "Alexander Nazarov <n4kz@n4kz.com>",

+16
-14

@@ -22,4 +22,6 @@ # Weaver

weaver [--port <number>] [--config <path>] upgrade
weaver [--port <number>] <restart|stop> [[task|pid], ...]
weaver [--port <number>] restart [[task|pid], ...]
weaver [--port <number>] stop [[task|pid], ...]
weaver [--port <number>] kill <signal> [[task|pid], ...]
weaver [--port <number>] drop <task>
weaver [--port <number>] [--nocolor] status

@@ -32,10 +34,10 @@ weaver [--port <number>] [--nocolor] dump

- `start` Start daemon if it was not started before. Default command
- `upgrade` Change or re-read config file
- `upgrade` Extend configuration with tasks from configuration file
- `restart` Restart all tasks, task group, task by pid
- `stop` Stop all tasks, task group, task by pid
- `kill` Send signal to task group or task by pid
- `drop` Stop task group and remove it from configuration
- `status` Show status for all tasks
- `dump` Show current weaver configuration
- `monitor` Show log messages from running weaver
- `dump` Show current configuration
- `monitor` Stream log messages from daemon
- `exit` Stop all tasks and exit

@@ -45,7 +47,7 @@

--config Configuration file. Required to start daemon with predefined tasks
--debug Do not fork and give additional output. Makes sense only for start [boolean]
--nocolor Do not use colors for output [boolean]
--help Show help [boolean]
--version Show version [boolean]
--config Configuration file [default: weaver.json]
--debug Do not fork and give additional output
--nocolor Do not use colors for output
--help Show help and exit
--version Show version and exit
--port Use specified port [default: 8092]

@@ -119,4 +121,4 @@

- `tasks` Task groups
- `count` Task count for group
- `source` Source file for task group
- `count` Task count for group. Can be zero
- `source` Source file or executable for task group. Relative to `cwd` or absolute
- `persistent` Restart task on unclean exit. Defaults to false. Boolean. Optional

@@ -128,4 +130,4 @@ - `executable` Source is executable itself and v8 instance is not needed to run it. Defaults to false. Boolean. Optional

- `timeout` Timeout between SIGINT and SIGTERM for stop and restart commands. Defaults to 1000ms. Optional
- `cwd` Task group working directory. Defaults to path. Optional
- `runtime` Minimal runtime required for persistent task to be restarted after unclean exit
- `runtime` Minimal runtime required for persistent task to be restarted after unclean exit. Defaults to 1000ms. Optional
- `cwd` Task group working directory. Relative to `path` or absolute. Optional

@@ -132,0 +134,0 @@ Configuration file is validated with JSON Schema from file `lib/schema.json`.

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet