1 | #!/usr/bin/env node
|
2 | var fs = require('fs');
|
3 | var path = require('path');
|
4 | var xtend = require('xtend');
|
5 | var camelize = require('camelize');
|
6 | var util = require('util');
|
7 |
|
8 | require('colors');
|
9 |
|
10 | var optimist = require('optimist')
|
11 | .usage('Usage: $0 [patch] [options]')
|
12 | .string('config')
|
13 | .describe('config', 'Specify a JSON config file to use as defaults')
|
14 | .string('dry-run')
|
15 | .describe('dry-run', 'Run patch without modifying data')
|
16 | .string('db')
|
17 | .demand('db')
|
18 | .describe('db', 'Connection string for application database')
|
19 | .string('log-db')
|
20 | .describe('log-db', 'Connection string for log database')
|
21 | .string('parallel')
|
22 | .describe('parallel', 'Specify a parallelism level for the patch. Defaults to 1')
|
23 | .boolean('output')
|
24 | .describe('output', 'Output progress while runing the patch')
|
25 | .default('output', true)
|
26 | .string('force')
|
27 | .describe('force', 'Force a run without providing a log db')
|
28 | .boolean('version')
|
29 | .describe('version', 'Prints version');
|
30 |
|
31 | var version = function() {
|
32 | if (process.argv.indexOf('--version') < 0) {
|
33 | return;
|
34 | }
|
35 |
|
36 | var v = require('../package').version;
|
37 | console.log('mongopatch v' + v);
|
38 | error('');
|
39 | };
|
40 |
|
41 | var exit = function(code) {
|
42 | process.stdout.write('\x1B[?25h', function() {
|
43 | process.exit(code || 0);
|
44 | });
|
45 | };
|
46 |
|
47 | var error = function(err) {
|
48 | console.error((err.message || err).red);
|
49 |
|
50 | if(err.patch) {
|
51 | var patch = err.patch;
|
52 |
|
53 | console.log(JSON.stringify({
|
54 | modified: patch.modified,
|
55 | before: patch.before,
|
56 | after: patch.after,
|
57 | modifier: patch.modifier,
|
58 | diff: patch.diff
|
59 | }, null, 4));
|
60 | }
|
61 | if(err.stack) {
|
62 | console.log(err.stack);
|
63 | }
|
64 |
|
65 | exit(1);
|
66 | };
|
67 |
|
68 | var apply = function(patch, options) {
|
69 | if(!patch) {
|
70 | optimist.showHelp();
|
71 | return error('Patch path required');
|
72 | }
|
73 |
|
74 | patch = path.join(process.cwd(), patch);
|
75 |
|
76 | if(!fs.existsSync(patch)) {
|
77 | return error(util.format('Patch "%s" does not exist', patch));
|
78 | }
|
79 |
|
80 | var conf = options.config ? JSON.parse(fs.readFileSync(options.config, 'utf-8')) : {};
|
81 | options = xtend(options, camelize(conf));
|
82 |
|
83 | if(!options.dryRun && !options.logDb && !options.force) {
|
84 | error('--log-db required to run patch');
|
85 | }
|
86 | if (options.parallel === true) {
|
87 | options.parallel = 10;
|
88 | } else if(options.parallel) {
|
89 | options.parallel = parseInt(options.parallel, 10);
|
90 | }
|
91 |
|
92 | patch = require(patch);
|
93 |
|
94 | var run = require('../source/index');
|
95 | var stream = run(patch, options);
|
96 |
|
97 | process.stdout.write('\x1B[?25l');
|
98 | process.on('SIGINT', exit.bind(null, 0));
|
99 |
|
100 | stream.on('error', error);
|
101 | stream.on('end', function() {
|
102 | process.stdout.write('\x1B[?25h');
|
103 | });
|
104 | };
|
105 |
|
106 | process.on('uncaughtException', function(err) {
|
107 | error(err);
|
108 | });
|
109 |
|
110 | version();
|
111 |
|
112 | var argv = optimist.argv;
|
113 | var opts = camelize(argv);
|
114 |
|
115 | delete opts[''];
|
116 | delete opts.$0;
|
117 |
|
118 | apply(argv._[0], opts);
|