UNPKG

3.22 kBJavaScriptView Raw
1var fs = require('fs');
2var path = require('path');
3var util = require('util');
4
5var xtend = require('xtend');
6var camelize = require('camelize');
7var optimist = require('optimist');
8
9var OPTIONS = {
10 config: {
11 describe: 'Specify a JSON config file to use as defaults',
12 type: 'string'
13 },
14 update: {
15 describe: 'The update mode: dummy, query or document (see documentation for more details)',
16 type: 'string',
17 default: 'document'
18 },
19 'dry-run': {
20 describe: 'Run patch without modifying data (same as --update dummy, overwrites --update option)',
21 type: 'string'
22 },
23 db: {
24 describe: 'Connection string for application database',
25 type: 'string'
26 },
27 'log-db': {
28 describe: 'Connection string for log database',
29 type: 'string'
30 },
31 parallel: {
32 describe: 'Specify a parallelism level for the patch. Defaults to 1',
33 type: 'string'
34 },
35 output: {
36 describe: 'Output progress while runing the patch',
37 type: 'boolean',
38 default: true
39 },
40 force: {
41 describe: 'Force a run without providing a log db',
42 type: 'boolean'
43 },
44 version: {
45 describe: 'Prints version',
46 type: 'boolean'
47 }
48};
49
50var OPTION_KEYS = Object.keys(OPTIONS).reduce(function(acc, key) {
51 acc[camelize(key)] = true;
52 return acc;
53}, {});
54
55var cmd = optimist()
56 .usage('Usage: $0 [patch] [options]')
57 .options(OPTIONS);
58
59var error = function(name) {
60 var args = Array.prototype.slice.call(arguments, 1);
61 return { option: name, message: util.format.apply(null, args) };
62};
63
64var version = function(argv) {
65 var v = require('../../package').version;
66 return util.format('mongopatch v%s', v);
67};
68
69var validate = function(patch, options) {
70 if(!patch) {
71 return error('patch', 'Patch path required');
72 }
73 if(!fs.existsSync(patch)) {
74 return error('patch', 'Cannot find patch with path "%s"', patch);
75 }
76
77 var invalidOptions = Object.keys(options).filter(function(arg) {
78 return !OPTION_KEYS.hasOwnProperty(arg);
79 });
80
81 if(invalidOptions.length) {
82 var option = invalidOptions.shift();
83 return error(option, 'Uknown option: %s', option);
84 }
85
86 if(!options.db) {
87 return error('db', '--db option required');
88 }
89 if(!options.update) {
90 return error('update', '--update option required');
91 }
92
93 if(['dummy', 'query', 'document'].indexOf(options.update) < 0) {
94 return error('update', '--update option invalid');
95 }
96
97 if(options.update !== 'dummy' && !options.logDb && !options.force) {
98 return error('logDb', '--log-db option required');
99 }
100};
101
102var parse = function(argv) {
103 var options = cmd.parse(argv);
104 var patch = options._[0];
105
106 patch = patch && path.resolve(process.cwd(), patch);
107
108 delete options._;
109 delete options.$0;
110
111 options = camelize(options);
112
113 options.dryRun = ('dryRun' in options) || options.update === 'dummy';
114 if('parallel' in options) {
115 options.parallel = parseInt(options.parallel, 10) || 10;
116 }
117 if(options.dryRun) {
118 options.update = 'dummy';
119 }
120
121 var conf = options.config ? JSON.parse(fs.readFileSync(options.config, 'utf-8')) : {};
122 options = xtend(camelize(conf), options);
123
124 return {
125 patch: patch,
126 options: options,
127 error: validate(patch, options),
128 help: cmd.help,
129 version: version
130 };
131};
132
133module.exports = function(argv) {
134 argv = argv || process.argv.slice(2);
135 return parse(argv);
136};