UNPKG

10.2 kBJavaScriptView Raw
1'use strict';
2
3require('./lib/common/init');
4
5var spawn = require('child_process').spawn,
6 path = require('path'),
7 chalk = require('chalk'),
8 Logger = require('./lib/common/logging/logger')
9;
10
11var logger = new Logger();
12
13logger.chalk = chalk;
14logger.verbosity = 1;
15
16module.exports = Gulp;
17
18function Gulp(gulp) {
19 if (gulp) {
20 this.init(gulp);
21 }
22}
23
24Gulp.prototype.init = function(gulp) {
25 var self = this,
26 server,
27 serverStopped = false
28 ;
29
30 // Display info on available tasks.
31 gulp.task('default', function() {
32 logger.log('<<blue>>Start a <<bold>>server<</bold>>:');
33 logger.log('<<grey>>$<</grey>> node danf serve', 0, 1);
34 logger.log('<<blue>>Execute a <<bold>>command<</bold>>:');
35 logger.log('<<grey>>$<</grey>> node danf $ my-command --foo bar', 0, 1);
36 });
37
38 // Execute a command.
39 gulp.task('$', function(done) {
40 self.executeCommand(done)
41 });
42
43 // Start a self watching server with a fresh client.
44 gulp.task('serve', ['watch', 'build-client', 'start-server'], function() {
45 });
46
47 // Build client.
48 gulp.task('watch', function(done) {
49 var options = {
50 interval: 700
51 }
52 ;
53
54 // Watch for client modifications.
55 this.watch(
56 [
57 './node_modules/danf/lib/client/main.js',
58 './node_modules/danf/lib/common/**/*.js',
59 './node_modules/danf/lib/client/**/*.js',
60 './node_modules/danf/config/common/**/*.js',
61 './node_modules/danf/config/client/**/*.js',
62 './node_modules/danf/resource/public/**/*'
63 ],
64 options,
65 ['build-client-danf', 'build-client-config']
66 );
67 this.watch(
68 [
69 './*.js',
70 './lib/common/**/*.js',
71 './lib/client/**/*.js',
72 './config/common/**/*.js',
73 './config/client/**/*.js',
74 './resource/public/**/*'
75 ],
76 options,
77 ['build-client-app']
78 );
79 this.watch(
80 './node_modules/danf/lib/common/init.js',
81 options,
82 ['build-client-init']
83 );
84
85 // Watch for server modifications.
86 this.watch(
87 [
88 './*.js',
89 './lib/common/**/*.js',
90 './lib/server/**/*.js',
91 './config/common/**/*.js',
92 './config/server/**/*.js',
93 './resource/private/**/*',
94 './node_modules/danf/*.js',
95 './node_modules/danf/lib/common/**/*.js',
96 './node_modules/danf/lib/server/**/*.js',
97 './node_modules/danf/config/common/**/*.js',
98 './node_modules/danf/config/server/**/*.js',
99 './node_modules/danf/resource/private/**/*'
100 ],
101 options,
102 ['start-server']
103 );
104 });
105
106 // Build client.
107 gulp.task('build-client', function(done) {
108 self.buildClient(function() {
109 done();
110 });
111 });
112
113 // Build client danf file.
114 gulp.task('build-client-danf', function(done) {
115 logger.log('<<magenta>><<bold>>Client danf file<</bold>> rebuilding...');
116
117 var danf = self.prepareBuilder(false);
118
119 danf.buildClientParts(
120 ['danf'],
121 done
122 );
123 });
124
125 // Build client app file.
126 gulp.task('build-client-app', function(done) {
127 logger.log('<<magenta>><<bold>>Client app file<</bold>> rebuilding...');
128
129 var danf = self.prepareBuilder(false);
130
131 danf.buildClientParts(
132 ['app'],
133 done
134 );
135 });
136
137 // Build client init file.
138 gulp.task('build-client-init', function(done) {
139 logger.log('<<magenta>><<bold>>Client init file<</bold>> rebuilding...');
140
141 var danf = self.prepareBuilder(false);
142
143 danf.buildClientParts(
144 ['init'],
145 done
146 );
147 });
148
149 // Build client require file.
150 gulp.task('build-client-require', function(done) {
151 logger.log('<<magenta>><<bold>>Client require file<</bold>> rebuilding...');
152
153 var danf = self.prepareBuilder(false);
154
155 danf.buildClientParts(
156 ['require'],
157 done
158 );
159 });
160
161 // Build client jquery file.
162 gulp.task('build-client-jquery', function(done) {
163 logger.log('<<magenta>><<bold>>Client jquery file<</bold>> rebuilding...');
164
165 var danf = self.prepareBuilder(false);
166
167 danf.buildClientParts(
168 ['jquery'],
169 done
170 );
171 });
172
173 // Build client config file.
174 gulp.task('build-client-config', function(done) {
175 logger.log('<<magenta>><<bold>>Client config file<</bold>> rebuilding...');
176
177 var danf = self.prepareBuilder(false);
178
179 danf.buildClientParts(
180 ['config'],
181 done
182 );
183 });
184
185 // Start a server.
186 gulp.task('start-server', function(done) {
187 var hasProcessedDone = false;
188
189 // Kill existing server.
190 if (server) {
191 server.kill();
192 serverStopped = true;
193 }
194
195 if (serverStopped) {
196 logger.log('<<magenta>><<bold>>Server<</bold>> restarting...');
197 serverStopped = false;
198 }
199
200 // Forward the task in order to not create a gulp cluster.
201 server = spawn(
202 'node',
203 [require.resolve('./main')].concat(process.argv),
204 {
205 cwd: process.cwd()
206 }
207 );
208
209 server.stdout.on('data', function(data) {
210 process.stdout.write(data);
211
212 if (
213 -1 !== data.toString('utf8').indexOf('__________') &&
214 !hasProcessedDone
215 ) {
216 hasProcessedDone = true;
217 done();
218 }
219 });
220 server.stderr.on('data', function(data) {
221 process.stderr.write(data);
222 });
223 server.on('close', function(code, signal) {
224 if (!hasProcessedDone) {
225 hasProcessedDone = true;
226 done();
227 }
228
229 if (code >= 1) {
230 logger.log('<<red>>An error occured during server starting. Waiting for correction...');
231 serverStopped = true;
232 }
233 });
234 });
235
236 process.on('close', function() {
237 if (server) {
238 server.kill();
239 }
240 });
241}
242
243Gulp.prototype.executeCommand = function(done) {
244 var net = require('net');
245
246 var self = this,
247 command = this.parseCommandLine(),
248 verbosity = command.silent ? 10 : 1
249 ;
250
251 // Try to connect to a command server.
252 logger.log('<<grey>>[client] <<yellow>>Trying to connect to command server...', verbosity);
253
254 var client = net.connect({port: command.port}, function() {
255 client.write(command.line);
256 }),
257 standalone = false
258 ;
259
260 client.on('error', function(error) {
261 // Execute a standalone command if no command server is listening.
262 if ('ECONNREFUSED' === error.code) {
263 standalone = true;
264
265 logger.log('<<grey>>[client] <<red>>Failed to connect.', verbosity)
266 logger.log('<<grey>>[client] <<yellow>>You are executing a standalone command. To maximize the performances, start a command server with `node danf serve`.', verbosity);
267
268 // Execute a standalone command.
269 var danf = self.prepareBuilder(false);
270
271 danf.buildServer(function(app) {
272 app.executeCmd(command.line, function() {
273 logger.log('<<grey>>[client]<</grey>> <<yellow>>Command processing ended.', verbosity);
274 done();
275
276 // Wait for all stdout to be sent to parent process.
277 setTimeout(
278 function() {
279 process.exit(0);
280 },
281 2000
282 );
283 });
284 });
285 } else {
286 throw error;
287 }
288 });
289 client.on('data', function(data) {
290 logger.log('<<grey>>[server]<</grey>> {0}'.format(data.toString()), verbosity);
291 });
292 client.on('close', function() {
293 logger.log('<<grey>>[client]<</grey>> <<yellow>>Command processing ended.', verbosity);
294
295 if (!standalone) {
296 done();
297 }
298 });
299}
300
301Gulp.prototype.buildServer = function(callback) {
302 var danf = this.prepareBuilder();
303
304 danf.buildServer(callback);
305}
306
307Gulp.prototype.buildClient = function(callback) {
308 var danf = this.prepareBuilder(false);
309
310 danf.buildClient(callback);
311}
312
313Gulp.prototype.prepareBuilder = function(clustered) {
314 var command = this.parseCommandLine();
315
316 if (!clustered && undefined !== clustered) {
317 if (null == command.app.server.context.cluster) {
318 command.app.server.context.cluster = {};
319 }
320 command.app.server.context.cluster = null;
321 }
322
323 return this.getAppBuilder(command);
324}
325
326Gulp.prototype.getAppBuilder = function(command) {
327 return require('./index')(
328 command.app.server.configuration,
329 command.app.client.configuration,
330 command.app.server.context,
331 command.app.client.context
332 )
333 ;
334}
335
336Gulp.prototype.parseCommandLine = function() {
337 var line = process.argv.slice(4).join(' ').replace(' ', ''),
338 envOption = line.match(/\s--env\s([^\s]+)+/),
339 portOption = line.match(/\s--port\s([^\s]+)/),
340 environment = envOption ? envOption[1].replace(/^---/, '') : 'dev',
341 port = portOption ? portOption[1].replace(/^---/, '') : 3111,
342 silent = line.match(/\s--silent/)
343 ;
344
345 return {
346 line: line
347 .replace(/\s--env\s([^\s])+/, '')
348 .replace(/\s--port\s([^\s])+/, '')
349 .replace(/\s--colors/, '')
350 .replace(/\s--silent/, '')
351 ,
352 app: require(path.join(
353 process.cwd(),
354 'app-{0}'.format(environment)
355 )),
356 env: environment,
357 port: port,
358 silent: silent
359 };
360}
\No newline at end of file