1 | #!/usr/bin/env node
|
2 |
|
3 | var amok = require('./');
|
4 | var async = require('async');
|
5 | var cmd = require('commander');
|
6 | var fs = require('fs');
|
7 | var path = require('path');
|
8 | var temp = require('temp');
|
9 | var repl = require('repl');
|
10 | var util = require('util');
|
11 |
|
12 | var pkg = require('./package.json');
|
13 |
|
14 | cmd.usage('[options] <script>');
|
15 |
|
16 | cmd.option('-h, --host <HOST>', 'specify http host', 'localhost');
|
17 | cmd.option('-p, --port <PORT>', 'specify http port', 9966);
|
18 |
|
19 | cmd.option('-H, --debugger-host <HOST>', 'specify debugger host', 'localhost');
|
20 | cmd.option('-P, --debugger-port <PORT>', 'specify debugger port', 9222);
|
21 |
|
22 | cmd.option('-i, --interactive', 'enable interactive mode');
|
23 |
|
24 | cmd.option('--client <CMD>', 'specify the client to spawn');
|
25 | cmd.option('--compiler <CMD>', 'specify the compiler to spawn');
|
26 |
|
27 | cmd.option('-v, --verbose', 'enable verbose logging mode');
|
28 |
|
29 | cmd.version(pkg.version);
|
30 | cmd.parse(process.argv);
|
31 |
|
32 | cmd.cwd = process.cwd();
|
33 |
|
34 | function compiler(callback, data) {
|
35 | if (cmd.compiler) {
|
36 | if (cmd.verbose) {
|
37 | console.info('Spawning compiler...');
|
38 | }
|
39 |
|
40 | temp.track();
|
41 | temp.mkdir('amok', function(error, dirpath) {
|
42 | if (error) {
|
43 | return callback(error);
|
44 | }
|
45 |
|
46 | var compiler = amok.compile(cmd, function(error, stdout, stderr) {
|
47 | if (error) {
|
48 | return callback(error);
|
49 | }
|
50 |
|
51 | stdout.pipe(process.stdout);
|
52 | stderr.pipe(process.stderr);
|
53 |
|
54 | cmd.scripts = {
|
55 | 'bundle.js': compiler.output,
|
56 | };
|
57 |
|
58 | callback(null, compiler);
|
59 | });
|
60 | });
|
61 |
|
62 | } else {
|
63 | cmd.scripts = cmd.args.reduce(function(object, value, key) {
|
64 | object[value] = path.resolve(value);
|
65 | return object;
|
66 | }, {});
|
67 |
|
68 | callback(null, null);
|
69 | }
|
70 | }
|
71 |
|
72 | function watcher(callback, data) {
|
73 | var watcher = amok.watch(cmd, function() {
|
74 | if (cmd.verbose) {
|
75 | console.info('File watcher ready');
|
76 | }
|
77 |
|
78 | watcher.on('change', function(filename) {
|
79 | if (cmd.verbose) {
|
80 | console.info(filename, 'changed');
|
81 | }
|
82 |
|
83 | var script = Object.keys(cmd.scripts)
|
84 | .filter(function(key) {
|
85 | return cmd.scripts[key] === filename
|
86 | })[0];
|
87 |
|
88 | if (script) {
|
89 | if (cmd.verbose) {
|
90 | console.info('Re-compiling', script, '...');
|
91 | }
|
92 |
|
93 | fs.readFile(filename, 'utf-8', function(error, contents) {
|
94 | if (error) {
|
95 | return console.error(error);
|
96 | }
|
97 |
|
98 | data.bugger.source(script, contents, function(error) {
|
99 | if (error) {
|
100 | return console.error(error);
|
101 | }
|
102 |
|
103 | if (cmd.verbose) {
|
104 | console.info('Re-compilation succesful');
|
105 | }
|
106 | });
|
107 | });
|
108 | }
|
109 | });
|
110 |
|
111 | callback(null, watcher);
|
112 | });
|
113 | }
|
114 |
|
115 | function server(callback, data) {
|
116 | if (cmd.verbose) {
|
117 | console.info('Starting server...');
|
118 | }
|
119 |
|
120 | var server = amok.serve(cmd, function() {
|
121 | var address = server.address();
|
122 | if (cmd.verbose) {
|
123 | console.info('Server listening on http://%s:%d', address.address,
|
124 | address.port);
|
125 | }
|
126 |
|
127 | callback(null, server);
|
128 | });
|
129 | }
|
130 |
|
131 | function client(callback, data) {
|
132 | if (cmd.client) {
|
133 | if (cmd.verbose) {
|
134 | console.log('Spawning client...');
|
135 | }
|
136 |
|
137 | var client = amok.open(cmd, function(error, stdout, stderr) {
|
138 | if (error) {
|
139 | return callback(error);
|
140 | }
|
141 |
|
142 | stdout.pipe(process.stdout);
|
143 | stderr.pipe(process.stderr);
|
144 |
|
145 | callback(null, client);
|
146 | });
|
147 | } else {
|
148 | callback(null, null);
|
149 | }
|
150 | }
|
151 |
|
152 | function bugger(callback, data) {
|
153 | if (cmd.verbose) {
|
154 | console.info('Attaching debugger...');
|
155 | }
|
156 |
|
157 | var bugger = amok.debug(cmd, function(error, target) {
|
158 | if (error) {
|
159 | return callback(error);
|
160 | }
|
161 |
|
162 | if (cmd.verbose) {
|
163 | console.info('Debugger attached to', target.title);
|
164 | }
|
165 |
|
166 | bugger.console.on('data', function(message) {
|
167 | var parameters = message.parameters.map(function(parameter) {
|
168 | return parameter.value;
|
169 | });
|
170 |
|
171 | console[message.level].apply(console, parameters);
|
172 | });
|
173 |
|
174 | callback(null, bugger);
|
175 | });
|
176 | }
|
177 |
|
178 | function prompt(callback, data) {
|
179 | if (cmd.interactive) {
|
180 | var options = {
|
181 | prompt: '> ',
|
182 | input: process.stdin,
|
183 | output: process.stdout,
|
184 | writer: function(result) {
|
185 | if (result.value) {
|
186 | return util.inspect(result.value, {
|
187 | colors: true,
|
188 | });
|
189 | } else if (result.objectId) {
|
190 | return util.format('[class %s]\n%s', result.className, result.description);
|
191 | }
|
192 | },
|
193 |
|
194 | eval: function(cmd, context, filename, write) {
|
195 | data.bugger.evaluate(cmd, function(error, result) {
|
196 | write(error, result);
|
197 | });
|
198 | },
|
199 | };
|
200 |
|
201 | var prompt = repl.start(options);
|
202 | callback(null, prompt);
|
203 | } else {
|
204 | callback(null, null);
|
205 | }
|
206 | }
|
207 |
|
208 | async.auto({
|
209 | 'compiler': [compiler],
|
210 | 'server': ['compiler', server],
|
211 | 'client': ['server', client],
|
212 | 'bugger': ['client', bugger],
|
213 | 'watcher': ['bugger', watcher],
|
214 | 'prompt': ['bugger', prompt],
|
215 | }, function(error, data) {
|
216 | if (error) {
|
217 | console.error(error);
|
218 | process.exit(1);
|
219 | }
|
220 | });
|