Skip to content

Commit

Permalink
Merge 759add7 into b9839e2
Browse files Browse the repository at this point in the history
  • Loading branch information
todvora committed Apr 19, 2016
2 parents b9839e2 + 759add7 commit ffbb796
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 37 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module.exports = {
"env": {
"node": true,
"es6": true,
"jasmine": true
},
"extends": "eslint:recommended",
Expand Down
4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# intellij idea project files
.idea/

# variety.js should not be part of the repository, will be downloaded automatically
variety.js
*.iml

# Node.js dependencies
node_modules/
Expand Down
2 changes: 0 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
language: node_js
sudo: false
node_js:
- "0.10"
- "0.12"
- "4"
- "5"

Expand Down
3 changes: 0 additions & 3 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
environment:
matrix:
- nodejs_version: "0.11"
- nodejs_version: "0.12"
- nodejs_version: "3"
- nodejs_version: "4"
- nodejs_version: "5"
install:
Expand Down
48 changes: 32 additions & 16 deletions lib/cli.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,52 @@
'use strict';

var Q = require('q');
var child = require('child-process-promise');
var program = require('./program');
var utils = require('./utils');
var colors = require('colors/safe');

var executeVariety = function(proc, args, libPath) {
var spawnArgs = [args.db, '--eval='+utils.buildParams(args.collection, args.params), libPath].concat(args.shellParams);
return child.spawn('mongo', spawnArgs)
.progress(function (childProcess) {
childProcess.stdout.on('data', function (data) {
proc.stdout.write(data.toString());
});
childProcess.stderr.on('data', function (data) {
proc.stderr.write(data.toString());
});
});

var promise = child.spawn('mongo', spawnArgs);

var childProcess = promise.childProcess;
childProcess.stdout.on('data', function (data) {
proc.stdout.write(data.toString());
});
childProcess.stderr.on('data', function (data) {
proc.stderr.write(data.toString());
});

return promise;

};

var parse = function(proc) {
return Q.resolve(program.parse(proc.argv));
try {
return Promise.resolve(program.parse(proc.argv));
} catch (err) {
return Promise.reject(err);
}
};

var shouldRunAnalysis = function(args) {
return (args.params.help || !args.db || !args.collection) ? Q.reject() : Q.resolve(args);
return (args.params.help || !args.db || !args.collection) ? Promise.reject() : Promise.resolve(args);
};

var printHelp = function(proc, ex) {
if(ex) {
proc.stderr.write(ex.message);
var errText = '\nERROR: ' + ex.message + '\n\n';
proc.stderr.write(colors.red.bold(errText));
}
var helpText = program.help();
proc.stdout.write(helpText);

if(ex) {
return Promise.reject(ex);
} else {
return Promise.resolve(helpText);
}
proc.stdout.write(program.help());
};

var verifyVarietyLib = function() {
Expand All @@ -45,7 +61,7 @@ module.exports = function(proc) {
.then(function(){return verifyVarietyLib(proc);})
.then(function(libPath){return executeVariety(proc, args, libPath);});
})
.fail(function(ex) {
printHelp(proc, ex);
.catch(function(ex) {
return printHelp(proc, ex);
});
};
18 changes: 15 additions & 3 deletions lib/program.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,17 @@ var _ = require('lodash');

var opt = function(name, desc, parser) { return {'name':name, 'desc':desc, 'parser':parser};};

var parseHson = function(input) {
try {
return HJSON.parse(input);
} catch (e) {
throw new Error('Failed to parse option \''+this.name+'\': ' + e.message);
}
};

var options = [
opt('query', 'standard Mongo query object (json), to filter the set of documents required before analysis', HJSON.parse),
opt('sort', 'analyze documents in the specified order, takes Mongo sort object (json)', HJSON.parse),
opt('query', 'standard Mongo query object (json), to filter the set of documents required before analysis', parseHson),
opt('sort', 'analyze documents in the specified order, takes Mongo sort object (json)', parseHson),
opt('maxDepth', 'limit the <n> depth Variety will recursively search to find new objects', parseInt),
opt('limit', 'analyze only the <n> newest documents in a collection', parseInt),
opt('outputFormat', 'output format of results, possible variants are "ascii" or "json", default is "ascii"', String),
Expand Down Expand Up @@ -41,7 +49,11 @@ var parseVarietyArgs = function(options, args) {
var parseMongoArgs = function(options, args) {
var unknownOpts = parsedOpts(options, args).filter(function(opt){return !opt.def && opt.name != '_';});
var accumulate = function(acc, opt) {
acc.push('--' + opt.name);
if(opt.name.length > 1) {
acc.push('--' + opt.name);
} else {
acc.push('-' + opt.name);
}
if(typeof opt.value !== 'boolean') {
acc.push(opt.value);
}
Expand Down
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@
"url": "https://github.com/variety/variety-cli/issues"
},
"dependencies": {
"minimist": "^1.1.1",
"child-process-promise": "^2.0.1",
"colors": "^1.1.2",
"hjson": "^1.6.3",
"q": "^1.3.0",
"lodash": "^4.6.1",
"child-process-promise": "^1.0.2",
"minimist": "^1.1.1",
"variety": "variety/variety"
},
"devDependencies": {
Expand All @@ -41,5 +41,8 @@
"pretest": "npm run lint",
"test": "istanbul cover -x **/spec/** jasmine-node -- spec --verbose --captureExceptions",
"coverage": "cat ./coverage/lcov.info | coveralls"
},
"engines": {
"node": ">=4"
}
}
100 changes: 94 additions & 6 deletions spec/cli_spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
var cli = require('../lib/cli');
var Q = require('q');

var getWritableStream = function() {
var Writable = require('stream').Writable;
Expand All @@ -13,7 +12,14 @@ var getWritableStream = function() {
};

var mockSpawn = function(bin, args) {
return Q.resolve({'bin':bin, 'args':args});
var promise = Promise.resolve({'bin':bin, 'args':args});

promise.childProcess = {
stdout:{on:function(){}},
stderr:{on:function(){}}
};

return promise;
};

describe(__filename, function () {
Expand All @@ -35,11 +41,10 @@ describe(__filename, function () {
argv: ['node', 'variety-cli.js', '--help'],
process: null
})
.fin(function(){
.then(function(){
expect(ws.content).toContain('Usage: variety db_name/collection_name [options]');
done();
})
.done();
});
});

it('CLI should correctly execute Variety', function (done) {
Expand All @@ -65,6 +70,89 @@ describe(__filename, function () {
expect(res.args[4]).toEqual('localhost'); //library path
done();
})
.done();
.catch(done);
});

it('CLI should forward auth arguments directly to mongo shell', function (done) {

var child = require('child-process-promise');

spyOn(child, 'spawn').andCallFake(mockSpawn);

var ws = getWritableStream();
cli({
stdout: ws,
stderr: ws,
exitFn: function(){},
argv: ['node', 'variety-cli.js', 'foo/bar', '--username', 'lorem', '--password', 'ipsum', '--authenticationDatabase', 'my-auth-db'],
process: null
})
.then(function(res) {
expect(res.bin).toEqual('mongo');
expect(res.args[0]).toEqual('foo'); //db name
expect(res.args[1]).toEqual('--eval=var collection="bar";'); //variety args
expect(res.args[2]).toEndWith('variety.js'); //library path
expect(res.args[3]).toEqual('--username');
expect(res.args[4]).toEqual('lorem');
expect(res.args[5]).toEqual('--password');
expect(res.args[6]).toEqual('ipsum');
expect(res.args[7]).toEqual('--authenticationDatabase');
expect(res.args[8]).toEqual('my-auth-db');
done();
})
.catch(done);
});

it('CLI should handle short versions of mongo arguments (for example -u, -p)', function (done) {

var child = require('child-process-promise');

spyOn(child, 'spawn').andCallFake(mockSpawn);

var ws = getWritableStream();
cli({
stdout: ws,
stderr: ws,
exitFn: function(){},
argv: ['node', 'variety-cli.js', 'foo/bar', '-u', 'lorem', '-p', 'ipsum', '--authenticationDatabase', 'my-auth-db'],
process: null
})
.then(function(res) {
expect(res.bin).toEqual('mongo');
expect(res.args[0]).toEqual('foo'); //db name
expect(res.args[1]).toEqual('--eval=var collection="bar";'); //variety args
expect(res.args[2]).toEndWith('variety.js'); //library path
expect(res.args[3]).toEqual('-u');
expect(res.args[4]).toEqual('lorem');
expect(res.args[5]).toEqual('-p');
expect(res.args[6]).toEqual('ipsum');
expect(res.args[7]).toEqual('--authenticationDatabase');
expect(res.args[8]).toEqual('my-auth-db');
done();
})
.catch(done);
});

it('CLI should handle incorrect args and print error + help', function (done) {

var child = require('child-process-promise');
spyOn(child, 'spawn').andCallFake(mockSpawn);

var ws = getWritableStream();
cli({
stdout: ws,
stderr: ws,
exitFn: function(){},
argv: ['node', 'variety-cli.js', 'foo/bar', '--sort', '{foo:bar)'], // incorrect brackets pair
process: null
})
.then(function() {
done(new Error('Should throw exception and continue in catch branch'));
})
.catch(function(err) {
expect(err.message).toContain('Failed to parse option');
done();
});
});

});
2 changes: 1 addition & 1 deletion variety-cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ cli({
exitFn: process.exit,
argv: process.argv,
process: process
}).done(); // end the promise
});

0 comments on commit ffbb796

Please sign in to comment.