UNPKG

4.92 kBJavaScriptView Raw
1
2'use strict';
3
4process.env.PM2_NO_INTERACTION = 'true';
5// Do not print banner
6process.env.PM2_DISCRETE_MODE = true;
7
8var commander = require('commander');
9
10var PM2 = require('../..');
11var Log = require('../API/Log');
12var cst = require('../../constants.js');
13var pkg = require('../../package.json');
14var chalk = require('chalk');
15var path = require('path');
16var fmt = require('../tools/fmt.js');
17var exec = require('child_process').exec;
18var os = require('os');
19
20commander.version(pkg.version)
21 .description('pm2-dev monitor for any file changes and automatically restart it')
22 .option('--raw', 'raw log output')
23 .option('--timestamp', 'print timestamp')
24 .option('--node-args <node_args>', 'space delimited arguments to pass to node in cluster mode - e.g. --node-args="--debug=7001 --trace-deprecation"')
25 .option('--ignore [files]', 'files to ignore while watching')
26 .option('--post-exec [cmd]', 'execute extra command after change detected')
27 .option('--silent-exec', 'do not output result of post command', false)
28 .option('--test-mode', 'debug mode for test suit')
29 .option('--interpreter <interpreter>', 'the interpreter pm2 should use for executing app (bash, python...)')
30 .option('--env [name]', 'select env_[name] env variables in process config file')
31 .option('--auto-exit', 'exit if all processes are errored/stopped or 0 apps launched')
32 .usage('pm2-dev app.js');
33
34var pm2 = new PM2.custom({
35 pm2_home : path.join(os.homedir ? os.homedir() : (process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE), '.pm2-dev')
36});
37
38pm2.connect(function() {
39 commander.parse(process.argv);
40});
41
42function postExecCmd(command, cb) {
43 var exec_cmd = exec(command);
44
45 if (commander.silentExec !== true) {
46 exec_cmd.stdout.on('data', function(data) {
47 process.stdout.write(data);
48 });
49
50 exec_cmd.stderr.on('data', function(data) {
51 process.stderr.write(data);
52 });
53 }
54
55 exec_cmd.on('close', function done() {
56 if (cb) cb(null);
57 });
58
59 exec_cmd.on('error', function (err) {
60 console.error(err.stack || err);
61 });
62};
63
64function run(cmd, opts) {
65 var timestamp = opts.timestamp;
66
67 opts.watch = true;
68 opts.autorestart = true;
69 opts.restart_delay = 1000
70 if (opts.autoExit)
71 autoExit();
72
73 if (opts.ignore) {
74 opts.ignore_watch = opts.ignore.split(',')
75 opts.ignore_watch.push('node_modules');
76 }
77
78 if (timestamp === true)
79 timestamp = 'YYYY-MM-DD-HH:mm:ss';
80
81 pm2.start(cmd, opts, function(err, procs) {
82
83 if (err) {
84 console.error(err);
85 pm2.destroy(function() {
86 process.exit(0);
87 });
88 return false;
89 }
90
91 if (opts.testMode) {
92 return pm2.disconnect(function() {
93 });
94 }
95
96 fmt.sep();
97 fmt.title('PM2 development mode');
98 fmt.field('Apps started', procs.map(function(p) { return p.pm2_env.name } ));
99 fmt.field('Processes started', chalk.bold(procs.length));
100 fmt.field('Watch and Restart', chalk.green('Enabled'));
101 fmt.field('Ignored folder', opts.ignore_watch || 'node_modules');
102 if (opts.postExec)
103 fmt.field('Post restart cmd', opts.postExec);
104 fmt.sep();
105
106 setTimeout(function() {
107 pm2.Client.launchBus(function(err, bus) {
108 bus.on('process:event', function(packet) {
109 if (packet.event == 'online') {
110 if (opts.postExec)
111 postExecCmd(opts.postExec);
112 }
113 });
114 });
115 }, 1000);
116
117 Log.devStream(pm2.Client, 'all', opts.raw, timestamp, false);
118
119 process.on('SIGINT', function() {
120 console.log('>>>>> [PM2 DEV] Stopping current development session');
121 pm2.delete('all', function() {
122 pm2.destroy(function() {
123 process.exit(0);
124 });
125 });
126 });
127
128 });
129}
130
131commander.command('*')
132 .action(function(cmd, opts){
133 run(cmd, commander);
134 });
135
136commander.command('start <file|json_file>')
137 .description('start target config file/script in development mode')
138 .action(function(cmd, opts) {
139 run(cmd, commander);
140 });
141
142function exitPM2() {
143 if (pm2 && pm2.connected == true) {
144 console.log(chalk.green.bold('>>> Exiting PM2'));
145 pm2.kill(function() {
146 process.exit(0);
147 });
148 }
149 else
150 process.exit(0);
151}
152
153function autoExit(final) {
154 setTimeout(function() {
155 pm2.list(function(err, apps) {
156 if (err) console.error(err.stack || err);
157
158 var online_count = 0;
159
160 apps.forEach(function(app) {
161 if (app.pm2_env.status == cst.ONLINE_STATUS ||
162 app.pm2_env.status == cst.LAUNCHING_STATUS)
163 online_count++;
164 });
165
166 if (online_count == 0) {
167 console.log('0 application online, exiting');
168 if (final == true)
169 process.exit(1);
170 else
171 autoExit(true);
172 return false;
173 }
174 autoExit(false);
175 });
176 }, 3000);
177}
178
179if (process.argv.length == 2) {
180 commander.outputHelp();
181 exitPM2();
182}