UNPKG

27.1 kBJavaScriptView Raw
1#!/usr/bin/env node
2var CoffeeScript, CookieParser, Generate, about, build, buildAutoImport, buildProduction, capitalizeFirstLetter, clean, colors, compileFile, create, deleteFolderRecursive, dirCheck, fs, getDirectories, indent, launch, makeID, mkdirp, openurl, path, program, prompt, reload, reloadServer, reorderFiles, restify, uglify, walk, watch, watcher;
3
4console.error = function() {};
5
6prompt = require('prompt');
7
8program = require('commander');
9
10colors = require('colors');
11
12fs = require('fs-extra');
13
14walk = require('walk');
15
16path = require('path');
17
18watcher = require('node-watch');
19
20Generate = require('./lib/Generate');
21
22CoffeeScript = require('coffee-script');
23
24uglify = require('uglify-js');
25
26restify = require('restify');
27
28CookieParser = require('restify-cookies');
29
30mkdirp = require('mkdirp');
31
32openurl = require('openurl');
33
34reload = require('reload');
35
36prompt.message = 'MagiX';
37
38reloadServer = void 0;
39
40Array.prototype.move = function(old_index, new_index) {
41 var k;
42 if (new_index >= this.length) {
43 k = new_index - this.length;
44 while (k-- + 1) {
45 this.push(void 0);
46 }
47 }
48 this.splice(new_index, 0, this.splice(old_index, 1)[0]);
49 return this;
50};
51
52reorderFiles = function(files) {
53 var id, index, item, item2, new_files, no_match, _i, _len;
54 new_files = JSON.parse(JSON.stringify(files));
55 no_match = [];
56 for (item in files) {
57 index = -1;
58 for (item2 in new_files) {
59 if (new_files[item2].name === files[item]["extends"]) {
60 index = item2;
61 }
62 }
63 if (index > -1) {
64 if (index > item) {
65 new_files = new_files.move(index, item);
66 }
67 } else {
68 no_match.push(files[item].id);
69 }
70 }
71 for (_i = 0, _len = no_match.length; _i < _len; _i++) {
72 id = no_match[_i];
73 if (id !== void 0) {
74 for (item in new_files) {
75 if (new_files[item].id === id) {
76 new_files.move(item, 0);
77 }
78 }
79 }
80 }
81 return new_files;
82};
83
84capitalizeFirstLetter = function(string) {
85 return string.charAt(0).toUpperCase() + string.slice(1);
86};
87
88getDirectories = function(srcpath) {
89 return fs.readdirSync(srcpath).filter(function(file) {
90 return fs.statSync(path.join(srcpath, file)).isDirectory();
91 });
92};
93
94indent = function(str, numOfIndents, opt_spacesPerIndent) {
95 str = str.replace(/^(?=.)/gm, new Array(numOfIndents + 1).join('\t'));
96 numOfIndents = new Array(opt_spacesPerIndent + 1 || 0).join(' ');
97 if (opt_spacesPerIndent) {
98 return str.replace(/^\t+/g, (function(tabs) {
99 return tabs.replace(/./g, numOfIndents);
100 }));
101 } else {
102 return str;
103 }
104};
105
106deleteFolderRecursive = function(path) {
107 if (fs.existsSync(path)) {
108 fs.readdirSync(path).forEach(function(file, index) {
109 var curPath;
110 curPath = path + '/' + file;
111 if (fs.lstatSync(curPath).isDirectory()) {
112 deleteFolderRecursive(curPath);
113 } else {
114 fs.unlinkSync(curPath);
115 }
116 });
117 fs.rmdirSync(path);
118 }
119};
120
121makeID = function() {
122 var i, possible, text;
123 text = '';
124 possible = 'abcdefghijklmnopqrstuvwxyz0123456789';
125 i = 0;
126 while (i < 8) {
127 text += possible.charAt(Math.floor(Math.random() * possible.length));
128 i++;
129 }
130 return text;
131};
132
133about = function() {
134 console.log('\n');
135 console.log(' d8bY88b d88P ');
136 console.log(' Y8P Y88b d88P ');
137 console.log(' Y88o88P ');
138 console.log('88888b.d88b. 8888b. .d88b. 888 Y888P ');
139 console.log('888 "888 "88b "88bd88P"88b888 d888b ');
140 console.log('888 888 888.d888888888 888888 d88888b ');
141 console.log('888 888 888888 888Y88b 888888 d88P Y88b ');
142 console.log('888 888 888"Y888888 "Y88888888d88P Y88b ');
143 console.log(' 888 ');
144 console.log(' Y8b d88P ');
145 console.log(' "Y88P" ');
146 console.log('MagiX | magixjs.com'.green);
147 console.log('Beyond magical.'.green);
148 console.log('Created by Etienne Pinchon (@etiennepinchon)'.green);
149 console.log('Copyright ©2016'.green);
150 console.log('\n');
151 console.log('Usage:'.green);
152 console.log('* create [name] | Create a new project.');
153 console.log('* launch [dir] [port] | Create a new project.');
154 console.log('* build [dir] [env] | Build a project.');
155 console.log('* clean [dir] | Clear the build of a project.');
156 console.log('* watch [dir] | Observe change on a project and compile on the fly.');
157 console.log('\n');
158};
159
160create = function(name) {
161 var appCS, appJS, appNameCS, createCatalog, createIndexJS, createJSON, dirBuild, dirSources, dir_project, done, htmlContent;
162 if (!name || !/^[a-zA-Z0-9\_\s\-]{1,100}$/.test(name)) {
163 console.log('MagiX: [ERR] Name must be only letters, numbers, underscores, spaces or dashes.'.red);
164 return;
165 }
166 dir_project = './' + name;
167 if (!fs.existsSync(dir_project)) {
168 fs.mkdirSync(dir_project);
169 }
170 appJS = Generate.JS();
171 appCS = Generate.CS();
172 done = function() {
173 process.chdir(dir_project);
174 return console.log('MagiX: Project created successfully.'.green);
175 };
176 createJSON = function() {
177 var packageFile;
178 packageFile = {
179 name: name,
180 version: '0.1.0',
181 description: '',
182 tags: '',
183 created_at: new Date
184 };
185 return fs.writeFile(dir_project + '/package.json', JSON.stringify(packageFile, null, 2), function(err) {
186 if (err) {
187 return console.log(err);
188 }
189 return done();
190 });
191 };
192 createIndexJS = function() {
193 var indexJS;
194 indexJS = Generate.indexJS();
195 return fs.writeFile(dir_project + '/build/index.js', indexJS, function(err) {
196 if (err) {
197 return console.log(err);
198 }
199 return createCatalog();
200 });
201 };
202 createCatalog = function() {
203 var catalog;
204 catalog = Generate.catalog();
205 return fs.writeFile(dir_project + '/build/catalog.js', catalog, function(err) {
206 if (err) {
207 return console.log(err);
208 }
209 return createJSON();
210 });
211 };
212 dirBuild = dir_project + '/build';
213 dirSources = dir_project + '/documents';
214 if (!fs.existsSync(dir_project)) {
215 fs.mkdirSync(dir_project);
216 }
217 if (!fs.existsSync(dirBuild)) {
218 fs.mkdirSync(dirBuild);
219 }
220 if (!fs.existsSync(dirSources)) {
221 fs.mkdirSync(dirSources);
222 }
223 htmlContent = Generate.HTML(name, '', '', false);
224 appNameCS = '/App.coffee';
225 appJS = Generate.appRunJS(indent(appJS, 1));
226 fs.writeFile(dir_project + '/index.html', htmlContent, function(err) {
227 if (err) {
228 return console.log(err);
229 }
230 fs.writeFile(dirBuild + '/App.js', appJS, function(err) {
231 if (err) {
232 return console.log(err);
233 }
234 fs.writeFile(dirSources + appNameCS, appCS, function(err) {
235 if (err) {
236 return console.log(err);
237 }
238 createIndexJS();
239 });
240 });
241 });
242};
243
244launch = function(dir, server_port, env) {
245 var i, isProd, prod, server;
246 prod = ['production', 'prod', 'p'];
247 isProd = false;
248 if (!env) {
249 if (prod.indexOf(dir) > -1) {
250 isProd = true;
251 dir = void 0;
252 } else if (prod.indexOf(server_port) > -1) {
253 isProd = true;
254 server_port = void 0;
255 }
256 } else {
257 if (prod.indexOf(env) > -1) {
258 isProd = true;
259 }
260 }
261 if (!dir) {
262 dir = void 0;
263 }
264 i = parseInt(dir);
265 if (Number.isInteger(i) && i > 0) {
266 server_port = dir;
267 dir = void 0;
268 }
269 if (!dir) {
270 dir = process.cwd();
271 }
272 if (!fs.existsSync(dir)) {
273 console.log('MagiX: [ERR] Given folder does not exist.'.red);
274 return;
275 }
276 if (dir.endsWith('/')) {
277 dir = dir.slice(0, -1);
278 }
279 if (!server_port) {
280 server_port = 9000;
281 }
282 server = restify.createServer({
283 name: 'server',
284 version: '1.0.0'
285 });
286 server.use(restify.acceptParser(server.acceptable));
287 server.use(restify.queryParser());
288 server.use(restify.bodyParser());
289 server.use(CookieParser.parse);
290 server.use(restify.gzipResponse());
291 server.get(/^\/build\/?.*/, restify.serveStatic({
292 directory: dir
293 }));
294 server.get(/^\/documents\/?.*/, restify.serveStatic({
295 directory: dir
296 }));
297 server.get(/\/?/, function(req, res, next) {
298 res.writeHead(200);
299 fs.createReadStream(dir + '/index.html').pipe(res);
300 return next();
301 });
302 if (!isProd) {
303 reloadServer = reload(server, server, false);
304 }
305 server.__port = server_port;
306 server.start = function(message) {
307 return server.listen(server.__port, 'localhost', function() {
308 var url;
309 if (message) {
310 url = server.url.replace('127.0.0.1', 'localhost');
311 if (!isProd) {
312 console.log(('MagiX: Project launched! Running! Address ' + url).green);
313 openurl.open(url);
314 } else {
315 console.log(('MagiX: Project launched in Production mode! Running! Address ' + url).green);
316 }
317 }
318 });
319 };
320 server.start(true);
321 if (!isProd) {
322 if (fs.existsSync(dir + '/documents')) {
323 return watch(dir, server);
324 }
325 }
326};
327
328build = function(dir, env) {
329 var files, isProd, prod, startA, walker;
330 prod = ['production', 'prod', 'p'];
331 isProd = false;
332 if (!env) {
333 if (prod.indexOf(dir) > -1) {
334 isProd = true;
335 dir = void 0;
336 }
337 } else {
338 if (prod.indexOf(env) > -1) {
339 isProd = true;
340 }
341 }
342 if (!dir) {
343 dir = '.';
344 }
345 if (!dirCheck(dir)) {
346 return;
347 }
348 files = [];
349 startA = +new Date();
350 walker = walk.walk(dir + '/documents', {
351 followLinks: false
352 });
353 walker.on('file', function(root, stat, next) {
354 var file, file_build, filename, name;
355 filename = stat.name;
356 if (filename.endsWith('.coffee')) {
357 files.push(root + '/' + filename);
358 name = filename.split('/');
359 name = name[name.length - 1];
360 name = name.replace('.coffee', '');
361 compileFile(name, root, next);
362 } else if (filename && (filename.endsWith('.js') || filename.endsWith('.css'))) {
363 file = root + '/' + filename;
364 file_build = file.replace('documents', 'build');
365 files.push(file);
366 console.log(('MagiX: Copy ' + filename).magenta);
367 fs.copy(file, file_build, function(err) {
368 if (err) {
369 return console.error(err);
370 }
371 return next();
372 });
373 } else {
374 next();
375 }
376 });
377 return walker.on('end', function() {
378 var endA;
379 buildAutoImport(dir);
380 endA = +new Date();
381 console.log(("MagiX: Done: " + files.length + " files built in " + (endA - startA) + " ms.").green);
382 if (isProd) {
383 buildProduction(dir);
384 }
385 });
386};
387
388watch = function(dir, server) {
389 if (!dir) {
390 dir = '.';
391 }
392 if (!dirCheck(dir)) {
393 return;
394 }
395 console.log('MagiX: Now observing changes in your project..'.green);
396 return watcher(dir + '/documents', function(filename) {
397 var file_build, name;
398 if (reloadServer) {
399 reloadServer.reload();
400 }
401 if (filename && filename.endsWith('.coffee')) {
402 name = filename.split('/');
403 name = name[name.length - 1];
404 name = name.replace('.coffee', '');
405 path = filename.split('/');
406 path.pop();
407 path = path.join('/');
408 if (fs.existsSync(filename)) {
409 compileFile(name, path, void 0, true);
410 buildAutoImport(dir);
411 }
412 } else if (filename && (filename.endsWith('.js') || filename.endsWith('.css'))) {
413 name = filename.split('/');
414 name = name[name.length - 1];
415 file_build = filename.replace('documents', 'build');
416 if (fs.existsSync(filename)) {
417 console.log(('MagiX: Updating ' + name).magenta);
418 fs.copy(filename, file_build, function(err) {
419 if (err) {
420 return console.error(err);
421 }
422 });
423 } else if (fs.existsSync(file_build)) {
424 name = file_build.split('/');
425 name = name[name.length - 1];
426 console.log(('MagiX: Removing ' + name).magenta);
427 fs.unlink(file_build, function(err) {
428 if (err) {
429 return console.log(err);
430 }
431 });
432 }
433 }
434 if (server && server.close) {
435 server.close();
436 server.start(false);
437 }
438 });
439};
440
441clean = function(dir) {
442 var pathBuild;
443 if (!dir) {
444 dir = '.';
445 }
446 if (!dirCheck(dir)) {
447 return;
448 }
449 console.log('MagiX: Cleaning..'.magenta);
450 pathBuild = dir + '/build';
451 deleteFolderRecursive(pathBuild);
452 build(dir);
453 console.log("MagiX: Done: build cleaned.".green);
454};
455
456dirCheck = function(dir) {
457 var dirBuild, dir_build_check, dir_documents_check, directories, directory, _i, _len;
458 if (!dir) {
459 dir = '.';
460 }
461 dir_build_check = false;
462 dir_documents_check = false;
463 if (!fs.existsSync(dir)) {
464 console.log('MagiX: [ERR] Given folder does not exist.'.red);
465 return;
466 }
467 directories = getDirectories(dir);
468 for (_i = 0, _len = directories.length; _i < _len; _i++) {
469 directory = directories[_i];
470 if (directory === 'build') {
471 dir_build_check = true;
472 } else if (directory === 'documents') {
473 dir_documents_check = true;
474 }
475 }
476 if (!dir_build_check || !dir_documents_check) {
477 if (!dir_build_check && !dir_documents_check) {
478 console.log('MagiX: [ERR] Cannot find the "documents" directory.'.red);
479 console.log('MagiX: [HELP] Are you sure you are in the right folder? (cd magix-yourProjectName ;) ).'.magenta);
480 } else {
481 if (!dir_build_check) {
482 dirBuild = __dirname + '/build';
483 if (!fs.existsSync(dirBuild)) {
484 fs.mkdirSync(dirBuild);
485 }
486 return true;
487 }
488 if (!dir_documents_check) {
489 console.log('MagiX: [ERR] Cannot find the "documents" directory.'.red);
490 }
491 }
492 return false;
493 }
494 return true;
495};
496
497compileFile = function(name, dir, next, notification) {
498 console.log(('MagiX: Processing ' + name + ' ..').magenta);
499 return fs.readFile(dir + '/' + name + '.coffee', 'utf8', function(err, data) {
500 var addClass, classFile, classes, contentCopy, convert_error, converted, dirBuild, file, nextStep;
501 if (err) {
502 return console.log(err);
503 }
504 contentCopy = data;
505 file = {};
506 if (name !== 'App') {
507 if (/(Extends )\w+[ ]*\n/.test(contentCopy)) {
508 contentCopy = contentCopy.replace(/(Extends )\w+[ ]*\n/, function(match) {
509 file.type = match.replace('Extends ', '');
510 file.type = file.type.replace(/[ ]*\n/, '');
511 return '';
512 });
513 if (/(Kind )([-a-zA-Z0-9])*\n/.test(contentCopy)) {
514 contentCopy = params.contentCopy.replace(/(Kind )([-a-zA-Z0-9])*\n/, function(match) {
515 file.kind = match.replace('Kind ', '');
516 file.kind = file.kind.replace(/\n/, '');
517 return '';
518 });
519 }
520 if (/(Element )([-a-zA-Z0-9])*\n/.test(contentCopy)) {
521 contentCopy = contentCopy.replace(/(Element )([-a-zA-Z0-9])*\n/, function(match) {
522 file.element = match.replace('Element ', '');
523 file.element = file.element.replace(/\n/, '');
524 return '';
525 });
526 }
527 addClass = true;
528 contentCopy = indent(contentCopy, 2);
529 classes = ['Page', 'View', 'Text', 'Button', 'Link', 'CheckBox', 'Dropdown', 'RadioButton', 'Image', 'List', 'ListItem', 'TextInput', 'SpeechRecognition', 'Say', 'FileInput', 'Player', 'Slider', 'ProgressBar', 'Canvas', 'WebView'];
530 if (classes.indexOf(file.type) > -1) {
531 classFile = 'class ' + name + ' extends ' + file.type + '\n\t';
532 if (file.kind) {
533 classFile += '_kind : "' + file.kind + '"\n\t';
534 }
535 if (file.element) {
536 classFile += '_elementType : "' + file.element + '"\n\t';
537 }
538 classFile += 'constructor: (options) ->\n\t\tsuper\n' + contentCopy + '\n\t\tif not @_didAppear and @parent and @didAppear\n\t\t\t@_didAppear = true\n\t\t\t@didAppear(@__options)';
539 } else {
540 if (file.type === 'None') {
541 classFile = "class " + name + "\n\t";
542 if (file.kind) {
543 classFile += '_kind : "' + file.kind + '"\n\t';
544 }
545 if (file.element) {
546 classFile += '_elementType : "' + file.element + '"\n\t';
547 }
548 classFile += "constructor: (options) ->\n\t\tsuper\n" + contentCopy;
549 } else {
550 classFile = 'class ' + name + ' extends ' + file.type + '\n\t';
551 if (file.kind) {
552 classFile += '_kind : "' + file.kind + '"\n\t';
553 }
554 if (file.element) {
555 classFile += '_elementType : "' + file.element + '"\n\t';
556 }
557 classFile += 'constructor: (options) ->\n\t\tsuper\n' + contentCopy + '\n\t\tif not @_didAppear and @parent and @didAppear\n\t\t\t@_didAppear = true\n\t\t\t@didAppear(@__options)';
558 }
559 }
560 } else if (/(class)\s+\w+\s+(extends)\s+\w+/.test(contentCopy)) {
561 file.element = contentCopy.match(/(class)\s+\w+\s+(extends)\s+\w+/)[0].replace(/(class)\s+\w+\s+(extends)\s+/, '');
562 classFile = contentCopy;
563 } else {
564 classFile = contentCopy;
565 }
566 } else {
567 classFile = contentCopy;
568 }
569 converted = null;
570 try {
571 converted = CoffeeScript.compile(classFile, {
572 'bare': true
573 });
574 } catch (_error) {
575 err = _error;
576 convert_error = err;
577 }
578 dirBuild = dir.replace('documents', 'build');
579 nextStep = function() {
580 var convertedFinal, error, filePathBuild, lines_info, notifier;
581 filePathBuild = dirBuild + '/' + name + '.js';
582 if (converted) {
583 if (name === 'App') {
584 convertedFinal = Generate.appRunJS(indent(converted, 1));
585 } else {
586 convertedFinal = converted;
587 }
588 return fs.writeFile(filePathBuild, convertedFinal, function(err) {
589 console.log('MagiX: ↳ success'.green);
590 if (next) {
591 return next();
592 }
593 });
594 } else {
595 lines_info = String(convert_error).replace('[stdin]:', '').split(':');
596 error = capitalizeFirstLetter("" + convert_error.message + " at line " + lines_info[0] + " column " + lines_info[1]);
597 console.log(("MagiX: ↳ " + error).red);
598 if (notification) {
599 notifier = require('node-notifier');
600 path = require('path');
601 return notifier.notify({
602 title: 'MagiX | Error on ' + name,
603 message: error,
604 icon: path.join(__dirname, 'images/icon.png'),
605 sound: false,
606 wait: false
607 }, function(err, response) {});
608 }
609 }
610 };
611 if (!fs.existsSync(dirBuild)) {
612 return mkdirp(dirBuild, function(err) {
613 if (err) {
614 return console.error(err);
615 } else {
616 return nextStep();
617 }
618 });
619 } else {
620 return nextStep();
621 }
622 });
623};
624
625buildAutoImport = function(dir) {
626 var autoImport, catalog, documents, walker;
627 autoImport = [];
628 catalog = [];
629 documents = [];
630 walker = walk.walk(dir + '/documents', {
631 followLinks: false
632 });
633 walker.on('file', function(root, stat, next) {
634 var doc;
635 if (stat.name.endsWith('.coffee')) {
636 doc = {};
637 doc.name = stat.name.split('/');
638 doc.name = doc.name[doc.name.length - 1];
639 doc.name = doc.name.replace('.coffee', '');
640 fs.readFile(root + '/' + doc.name + '.coffee', 'utf8', function(err, data) {
641 if (err) {
642 return console.log(err);
643 }
644 if (data[0] !== '!') {
645 root = root.substring(root.indexOf("/documents") + 1);
646 path = '/' + root.replace('documents', 'build') + '/' + stat.name.replace('coffee', 'js');
647 if (path !== '/build/App.js') {
648 if (/(Element )([-a-zA-Z0-9])*\n/.test(data)) {
649 doc["extends"] = data.match(/(Element )([-a-zA-Z0-9])*\n/)[0].replace('Element ', '');
650 doc["extends"] = doc["extends"].replace(/\n/, '');
651 } else if (/(class)\s+\w+\s+(extends)\s+\w+/.test(data)) {
652 doc["extends"] = data.match(/(class)\s+\w+\s+(extends)\s+\w+/)[0].replace(/(class)\s+\w+\s+(extends)\s+/, '');
653 } else {
654 doc["extends"] = null;
655 }
656 doc.path = path;
657 doc.id = makeID();
658 documents.push(doc);
659 }
660 }
661 return next();
662 });
663 } else if (stat.name.endsWith('.png') || stat.name.endsWith('.svg') || stat.name.endsWith('.jpg') || stat.name.endsWith('.jpeg') || stat.name.endsWith('.gif') || stat.name.endsWith('.webm') || stat.name.endsWith('.ogg') || stat.name.endsWith('.mpeg') || stat.name.endsWith('.mp3') || stat.name.endsWith('.wav') || stat.name.endsWith('.webm') || stat.name.endsWith('.mp4') || stat.name.endsWith('.ogg')) {
664 catalog.push((root.substring(root.indexOf("/documents") + 1)).replace('documents/', '') + '/' + stat.name);
665 next();
666 } else {
667 next();
668 }
669 });
670 return walker.on('end', function() {
671 var file, indexJS, _i, _len;
672 documents = reorderFiles(documents);
673 for (_i = 0, _len = documents.length; _i < _len; _i++) {
674 file = documents[_i];
675 autoImport.push(file.path);
676 }
677 autoImport.push('/build/App.js');
678 indexJS = Generate.indexJS(JSON.stringify(autoImport));
679 fs.writeFile(dir + '/build/index.js', indexJS, function(err) {
680 if (err) {
681 return console.log(err);
682 }
683 return fs.writeFile(dir + '/build/catalog.js', Generate.catalog(catalog), function(err) {
684 if (err) {
685 return console.log(err);
686 }
687 });
688 });
689 });
690};
691
692buildProduction = function(dir) {
693 var cleaning, config, dirName, files, folder, magixJSON, minify, paths_to_remove, prodFolder, scriptID;
694 if (!dir) {
695 dir = process.cwd();
696 }
697 dirName = dir.split('/');
698 dirName = dirName[dirName.length - 1];
699 files = [];
700 folder = path.dirname(dir) + '/' + dirName;
701 paths_to_remove = [];
702 magixJSON = fs.readFileSync(folder + '/package.json', 'utf8');
703 config = JSON.parse(magixJSON);
704 if (!config.name) {
705 console.log('MagiX: [ERR] Invalid JSON project file, name missing.'.red);
706 return;
707 }
708 prodFolder = folder + ("/../magix-" + config.name + "-production");
709 scriptID = makeID();
710 if (!fs.existsSync(prodFolder)) {
711 console.log('MagiX: Cloning working project..'.magenta);
712 fs.mkdirSync(prodFolder);
713 }
714 if (fs.existsSync(prodFolder + '/build')) {
715 deleteFolderRecursive(prodFolder + '/build');
716 }
717 fs.copy(folder, prodFolder, function(err) {
718 if (err) {
719 return console.error(err);
720 }
721 console.log(('MagiX: Production path: ' + prodFolder).green);
722 fs.writeFile(prodFolder + '/build/index.js', Generate.indexJS(JSON.stringify('/build/' + scriptID + '.js')), function(err) {
723 if (err) {
724 return console.log(err);
725 }
726 minify();
727 });
728 });
729 minify = function() {
730 var walker;
731 walker = walk.walk(prodFolder + '/documents', {
732 followLinks: false
733 });
734 walker.on('file', function(root, stat, next) {
735 var name;
736 name = stat.name.split('/');
737 name = name[name.length - 1];
738 if (stat.name.endsWith('.DS_Store')) {
739 fs.unlinkSync(root + '/' + stat.name);
740 }
741 if (stat.name.endsWith('.coffee') || stat.name.endsWith('.js') || stat.name.endsWith('.css')) {
742 name = name.replace('.coffee', '').replace('.js', '').replace('.css', '');
743 if (name !== 'App') {
744 paths_to_remove.push(root + '/' + stat.name);
745 }
746 }
747 if (stat.name.endsWith('.coffee')) {
748 name = name.replace('.coffee', '');
749 fs.readFile(root + '/' + name + '.coffee', 'utf8', function(err, data) {
750 var uglified;
751 if (err) {
752 return console.log(err);
753 }
754 path = root.replace('documents', 'build') + '/' + stat.name.replace('coffee', 'js');
755 if (data[0] !== '!') {
756 if (path !== prodFolder + '/build/App.js') {
757 files.push(path);
758 return next();
759 } else {
760 return next();
761 }
762 } else {
763 uglified = uglify.minify([path]).code;
764 return fs.writeFile(path, uglified, 'utf8', function(err) {
765 if (err) {
766 return console.log(err);
767 }
768 return next();
769 });
770 }
771 });
772 } else {
773 next();
774 }
775 });
776 return walker.on('end', function() {
777 var appPath, uglified;
778 files.push(prodFolder + '/build/App.js');
779 uglified = '/* Made with MagiX (magixjs.com) and a smile :) */ ' + uglify.minify(files).code;
780 console.log('MagiX: Minify script..'.magenta);
781 appPath = prodFolder + '/build/' + scriptID + '.js';
782 fs.writeFile(appPath, uglified, function(err) {
783 console.log('MagiX: Cleaning..'.magenta);
784 return cleaning(function() {
785 return console.log("MagiX: Done: project built for production.".green);
786 });
787 });
788 });
789 };
790 return cleaning = function(cb) {
791 var cleanEmptyFoldersRecursively, e, item, _i, _len;
792 paths_to_remove = paths_to_remove.concat(files);
793 try {
794 for (_i = 0, _len = paths_to_remove.length; _i < _len; _i++) {
795 item = paths_to_remove[_i];
796 if (fs.existsSync(item)) {
797 fs.unlinkSync(item);
798 }
799 }
800 } catch (_error) {
801 e = _error;
802 console.log(e);
803 }
804 cleanEmptyFoldersRecursively = function(folder) {
805 var isDir;
806 fs = require('fs');
807 path = require('path');
808 isDir = fs.statSync(folder).isDirectory();
809 if (!isDir) {
810 return;
811 }
812 files = fs.readdirSync(folder);
813 if (files.length > 0) {
814 files.forEach(function(file) {
815 var fullPath;
816 fullPath = path.join(folder, file);
817 cleanEmptyFoldersRecursively(fullPath);
818 });
819 files = fs.readdirSync(folder);
820 }
821 if (files.length === 0) {
822 console.log(('MagiX: removing: ' + folder).magenta);
823 fs.rmdirSync(folder);
824 return;
825 }
826 };
827 cleanEmptyFoldersRecursively(prodFolder + '/documents/');
828 cleanEmptyFoldersRecursively(prodFolder + '/build/');
829 if (cb) {
830 return cb();
831 }
832 };
833};
834
835program.command('about', {
836 isDefault: true
837}).description('About magiX.').action(about);
838
839program.command('create [name]').description('Create a new project.').action(create);
840
841program.command('launch [dir] [port] [env]').description('Launch a local server to help you code an magix project.').action(launch);
842
843
844/*
845program
846 .command('forever start [dir] [port]')
847 .description('Launch a local server that runs continuously.')
848 .action foreverStart
849program
850 .command('forever stop [dir] [port]')
851 .description('Launch a local server that runs continuously.')
852 .action foreverStop
853 */
854
855program.command('build [dir] [env]').description('Build a project.').action(build);
856
857program.command('clean [dir]').description('Clear the build of a project.').action(clean);
858
859program.command('watch [dir]').description('Observe change on a project and compile on the fly.').action(watch);
860
861program.parse(process.argv);