UNPKG

3.41 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 'diff-object': {
49 describe: 'Use objects instead of arrays in document diff',
50 type: 'boolean',
51 default: false
52 }
53};
54
55var OPTION_KEYS = Object.keys(OPTIONS).reduce(function(acc, key) {
56 acc[camelize(key)] = true;
57 return acc;
58}, {});
59
60var cmd = optimist()
61 .usage('Usage: $0 [patch] [options]')
62 .options(OPTIONS);
63
64var error = function(name) {
65 var args = Array.prototype.slice.call(arguments, 1);
66 return { option: name, message: util.format.apply(null, args) };
67};
68
69var version = function(argv) {
70 var v = require('../../package').version;
71 return util.format('mongopatch v%s', v);
72};
73
74var validate = function(patch, options) {
75 if (!patch) {
76 return error('patch', 'Patch path required');
77 }
78 if (!fs.existsSync(patch)) {
79 return error('patch', 'Cannot find patch with path "%s"', patch);
80 }
81
82 var invalidOptions = Object.keys(options).filter(function(arg) {
83 return !OPTION_KEYS.hasOwnProperty(arg);
84 });
85
86 if (invalidOptions.length) {
87 var option = invalidOptions.shift();
88 return error(option, 'Unknown option: %s', option);
89 }
90
91 if (!options.db) {
92 return error('db', '--db option required');
93 }
94 if (!options.update) {
95 return error('update', '--update option required');
96 }
97
98 if (['dummy', 'query', 'document'].indexOf(options.update) < 0) {
99 return error('update', '--update option invalid');
100 }
101
102 if (options.update !== 'dummy' && !options.logDb && !options.force) {
103 return error('logDb', '--log-db option required');
104 }
105};
106
107var parse = function(argv) {
108 var options = cmd.parse(argv);
109 var patch = options._[0];
110
111 patch = patch && path.resolve(process.cwd(), patch);
112
113 delete options._;
114 delete options.$0;
115
116 options = camelize(options);
117
118 options.dryRun = ('dryRun' in options) || options.update === 'dummy';
119 if ('parallel' in options) {
120 options.parallel = parseInt(options.parallel, 10) || 10;
121 }
122 if (options.dryRun) {
123 options.update = 'dummy';
124 }
125
126 var conf = options.config ? JSON.parse(fs.readFileSync(options.config, 'utf-8')) : {};
127 options = xtend(camelize(conf), options);
128 var result = {
129 patch: patch,
130 options: options,
131 help: cmd.help,
132 version: version
133 };
134 var error = validate(patch, options);
135 if (error) {
136 result.error = error;
137 }
138 return result;
139};
140
141module.exports = function(argv) {
142 argv = argv || process.argv.slice(2);
143 return parse(argv);
144};