UNPKG

45.5 kBJavaScriptView Raw
1var __t;
2
3__t = function(ns) {
4 var curr, index, part, parts, _i, _len;
5 curr = null;
6 parts = [].concat = ns.split(".");
7 for (index = _i = 0, _len = parts.length; _i < _len; index = ++_i) {
8 part = parts[index];
9 if (curr === null) {
10 curr = eval(part);
11 continue;
12 } else {
13 if (curr[part] == null) {
14 curr = curr[part] = {};
15 } else {
16 curr = curr[part];
17 }
18 }
19 }
20 return curr;
21};
22
23var toaster = exports.toaster = {};
24
25(function() {
26 var Toaster, debug, error, exec, fs, growl, icon_error, icon_warn, interval, log, msgs, os, path, process_msgs, queue_msg, start_worker, stop_worker, warn,
27 __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
28 __slice = [].slice,
29 __hasProp = {}.hasOwnProperty,
30 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
31
32 __t('toaster').Toast = (function() {
33 var colors, cs, exec, fs, fsu, path;
34
35 fs = require("fs");
36
37 fsu = require("fs-util");
38
39 path = require("path");
40
41 exec = (require("child_process")).exec;
42
43 colors = require('colors');
44
45 cs = require("coffee-script");
46
47 Toast.prototype.builders = null;
48
49 function Toast(toaster) {
50 var code, config, config_file, contents, filepath, fix_scope, item, watcher, _i, _len, _ref,
51 _this = this;
52 this.toaster = toaster;
53 this.toast = __bind(this.toast, this);
54
55 this.basepath = this.toaster.basepath;
56 this.builders = [];
57 if ((config = this.toaster.cli.argv["config"]) != null) {
58 if (!(config instanceof Object)) {
59 config = JSON.parse(config);
60 }
61 _ref = [].concat(config);
62 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
63 item = _ref[_i];
64 this.toast(item);
65 }
66 } else {
67 config_file = this.toaster.cli.argv["config-file"];
68 filepath = config_file || path.join(this.basepath, "toaster.coffee");
69 if (this.toaster.cli.argv.w) {
70 watcher = fsu.watch(filepath);
71 watcher.on('change', function(f) {
72 var now;
73 now = (("" + (new Date)).match(/[0-9]{2}\:[0-9]{2}\:[0-9]{2}/))[0];
74 log(("[" + now + "] " + 'Changed'.bold + " " + filepath).cyan);
75 watcher.close();
76 return _this.toaster.reset();
77 });
78 }
79 if (fs.existsSync(filepath)) {
80 contents = fs.readFileSync(filepath, "utf-8");
81 try {
82 code = cs.compile(contents, {
83 bare: 1
84 });
85 } catch (err) {
86 error(err.message + " at 'toaster.coffee' config file.");
87 }
88 fix_scope = /(^[\s\t]?)(toast)+(\()/mg;
89 code = code.replace(fix_scope, "$1this.$2$3");
90 eval(code);
91 } else {
92 error("File not found: ".yellow + (" " + filepath.red + "\n") + "Try running:".yellow + " toaster -i".green + " or type".yellow + (" " + 'toaster -h'.green + " ") + "for more info".yellow);
93 }
94 }
95 }
96
97 Toast.prototype.toast = function(srcpath, params) {
98 var alias, builder, config, debug, dir, folder, i, item, v, vpath, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9;
99 if (params == null) {
100 params = {};
101 }
102 if (srcpath instanceof Object) {
103 params = srcpath;
104 } else if (path.resolve(srcpath !== srcpath)) {
105 folder = path.join(this.basepath, srcpath);
106 }
107 if (params.release === null) {
108 error('Release path not informed in config.');
109 return process.exit();
110 } else {
111 dir = path.dirname(params.release);
112 if (!fs.existsSync(path.join(this.basepath, dir))) {
113 error("Release folder does not exist:\n\t" + dir.yellow);
114 return process.exit();
115 }
116 }
117 if (params.debug) {
118 debug = path.join(this.basepath, params.debug);
119 } else {
120 debug = null;
121 }
122 config = {
123 is_building: false,
124 basepath: this.basepath,
125 src_folders: [],
126 files: [],
127 vendors: (_ref = params.vendors) != null ? _ref : [],
128 exclude: (_ref1 = params.exclude) != null ? _ref1 : [],
129 bare: (_ref2 = params.bare) != null ? _ref2 : false,
130 packaging: (_ref3 = params.packaging) != null ? _ref3 : true,
131 expose: (_ref4 = params.expose) != null ? _ref4 : null,
132 minify: (_ref5 = params.minify) != null ? _ref5 : true,
133 httpfolder: (_ref6 = params.httpfolder) != null ? _ref6 : "",
134 release: path.join(this.basepath, params.release),
135 debug: debug
136 };
137 _ref7 = config.vendors;
138 for (i = _i = 0, _len = _ref7.length; _i < _len; i = ++_i) {
139 v = _ref7[i];
140 vpath = config.vendors[i] = path.resolve(v);
141 if ((path.resolve(vpath)) !== vpath) {
142 config.vendors[i] = path.join(this.basepath, v);
143 }
144 }
145 if (!(srcpath instanceof Object)) {
146 srcpath = path.resolve(path.join(this.basepath, srcpath));
147 config.src_folders.push({
148 path: srcpath,
149 alias: params.alias || null
150 });
151 }
152 if (params.folders != null) {
153 _ref8 = params.folders;
154 for (folder in _ref8) {
155 alias = _ref8[folder];
156 if ((path.resolve(folder)) !== folder) {
157 folder = path.join(this.basepath, folder);
158 }
159 config.src_folders.push({
160 path: folder,
161 alias: alias
162 });
163 }
164 }
165 _ref9 = config.src_folders;
166 for (_j = 0, _len1 = _ref9.length; _j < _len1; _j++) {
167 item = _ref9[_j];
168 if (!fs.existsSync(item.path)) {
169 error(("Source folder doens't exist:\n\t" + item.path.red + "\n") + ("Check your " + 'toaster.coffee'.yellow + " and try again.") + "\n\t" + (path.join(this.basepath, "toaster.coffee")).yellow);
170 return process.exit();
171 }
172 }
173 builder = new toaster.core.Builder(this.toaster, this.toaster.cli, config);
174 return this.builders.push(builder);
175 };
176
177 return Toast;
178
179 })();
180
181 __t('toaster.generators').Question = (function() {
182
183 function Question() {}
184
185 Question.prototype.ask = function(question, format, fn) {
186 var stdin, stdout,
187 _this = this;
188 stdin = process.stdin;
189 stdout = process.stdout;
190 stdout.write("" + question + " ");
191 return stdin.once('data', function(data) {
192 var msg, rule;
193 data = data.toString().trim();
194 if (format.test(data)) {
195 return fn(data.trim());
196 } else {
197 msg = "" + 'Invalid entry, it should match:'.red;
198 rule = "" + (format.toString().cyan);
199 stdout.write("\t" + msg + " " + rule + "\n");
200 return _this.ask(question, format, fn);
201 }
202 }).resume();
203 };
204
205 return Question;
206
207 })();
208
209 __t('toaster.utils').ArrayUtil = (function() {
210
211 function ArrayUtil() {}
212
213 ArrayUtil.find = function(source, search, by_property) {
214 var k, p, v, _i, _j, _k, _len, _len1, _len2;
215 if (!by_property) {
216 for (k = _i = 0, _len = source.length; _i < _len; k = ++_i) {
217 v = source[k];
218 if (v === search) {
219 return {
220 item: v,
221 index: k
222 };
223 }
224 }
225 } else {
226 by_property = [].concat(by_property);
227 for (k = _j = 0, _len1 = source.length; _j < _len1; k = ++_j) {
228 v = source[k];
229 for (_k = 0, _len2 = by_property.length; _k < _len2; _k++) {
230 p = by_property[_k];
231 if (search === v[p]) {
232 return {
233 item: v,
234 index: k
235 };
236 }
237 }
238 }
239 }
240 return null;
241 };
242
243 ArrayUtil.find_all = function(source, search, by_property, regexp, unique) {
244 var item, k, p, v, _i, _j, _k, _len, _len1, _len2, _output, _unique;
245 _output = [];
246 _unique = {};
247 if (by_property === null) {
248 for (k = _i = 0, _len = source.length; _i < _len; k = ++_i) {
249 v = source[k];
250 if (regexp) {
251 if (search.test(v)) {
252 item = {
253 item: v,
254 index: k
255 };
256 }
257 } else {
258 if (search === v) {
259 item = {
260 item: v,
261 index: k
262 };
263 }
264 }
265 if (item) {
266 _output.push(item);
267 }
268 }
269 } else {
270 by_property = [].concat(by_property);
271 for (k = _j = 0, _len1 = source.length; _j < _len1; k = ++_j) {
272 v = source[k];
273 for (_k = 0, _len2 = by_property.length; _k < _len2; _k++) {
274 p = by_property[_k];
275 item = null;
276 if (regexp) {
277 if (search.test(v[p])) {
278 if (unique && !_unique[k]) {
279 item = {
280 item: v,
281 index: k
282 };
283 } else if (unique === !true) {
284 item = {
285 item: v,
286 index: k
287 };
288 }
289 }
290 } else {
291 if (search === v[p]) {
292 item = {
293 item: v,
294 index: k
295 };
296 }
297 }
298 if (item) {
299 _unique[k] = true;
300 _output.push(item);
301 }
302 }
303 }
304 }
305 return _output;
306 };
307
308 ArrayUtil.diff = function(a, b, by_property) {
309 var diff, item, search, _i, _j, _len, _len1;
310 if (a == null) {
311 a = [];
312 }
313 if (b == null) {
314 b = [];
315 }
316 diff = [];
317 for (_i = 0, _len = a.length; _i < _len; _i++) {
318 item = a[_i];
319 search = by_property != null ? item[by_property] : item;
320 if (!ArrayUtil.has(b, search, by_property)) {
321 diff.push({
322 item: item,
323 action: "deleted"
324 });
325 }
326 }
327 for (_j = 0, _len1 = b.length; _j < _len1; _j++) {
328 item = b[_j];
329 search = by_property != null ? item[by_property] : item;
330 if (!ArrayUtil.has(a, search, by_property)) {
331 diff.push({
332 item: item,
333 action: "created"
334 });
335 }
336 }
337 return diff;
338 };
339
340 ArrayUtil.has = function(source, search, by_property) {
341 return ArrayUtil.find(source, search, by_property) != null;
342 };
343
344 ArrayUtil.replace_into = function(src, index, items) {
345 items = [].concat(items);
346 src.splice(index, 1);
347 while (items.length) {
348 src.splice(index++, 0, items.shift());
349 }
350 return src;
351 };
352
353 return ArrayUtil;
354
355 })();
356
357 __t('toaster.utils').FnUtil = (function() {
358
359 function FnUtil() {}
360
361 FnUtil.proxy = function() {
362 var fn, params;
363 fn = arguments[0], params = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
364 return function() {
365 var inner_params;
366 inner_params = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
367 return fn.apply(null, params.concat(inner_params));
368 };
369 };
370
371 return FnUtil;
372
373 })();
374
375 os = require('os');
376
377 growl = os.platform() === 'win32' ? null : require('growl');
378
379 icon_warn = __dirname + '/../images/warning.png';
380
381 icon_error = __dirname + '/../images/error.png';
382
383 log = function(msg, send_to_growl) {
384 if (send_to_growl == null) {
385 send_to_growl = false;
386 }
387 console.log(msg);
388 return msg;
389 };
390
391 debug = function(msg, send_to_growl) {
392 if (send_to_growl == null) {
393 send_to_growl = false;
394 }
395 msg = log("" + msg.magenta);
396 return msg;
397 };
398
399 error = function(msg, send_to_growl, file) {
400 if (send_to_growl == null) {
401 send_to_growl = true;
402 }
403 if (file == null) {
404 file = null;
405 }
406 msg = log("ERROR ".bold.red + msg);
407 if (send_to_growl && (growl != null)) {
408 msg = msg.replace(/\[\d{2}m/g, "");
409 msg = msg.replace(/(\[\dm)([^\s]+)/ig, "<$2>$3");
410 queue_msg({
411 msg: msg,
412 opts: {
413 title: 'Coffee Toaster',
414 image: icon_error
415 }
416 });
417 }
418 return msg;
419 };
420
421 warn = function(msg, send_to_growl) {
422 if (send_to_growl == null) {
423 send_to_growl = true;
424 }
425 msg = log("WARNING ".bold.yellow + msg);
426 if (send_to_growl && (growl != null)) {
427 msg = msg.replace(/\[\d{2}m/g, "");
428 msg = msg.replace(/(\[\dm)([^\s]+)/ig, "<$2>$3");
429 queue_msg({
430 msg: msg,
431 opts: {
432 title: 'Coffee Toaster',
433 image: icon_warn
434 }
435 });
436 }
437 return msg;
438 };
439
440 msgs = [];
441
442 interval = null;
443
444 start_worker = function() {
445 if (interval == null) {
446 interval = setInterval(process_msgs, 150);
447 return process_msgs();
448 }
449 };
450
451 stop_worker = function() {
452 if (interval != null) {
453 clearInterval(interval);
454 return interval = null;
455 }
456 };
457
458 queue_msg = function(msg) {
459 msgs.push(msg);
460 return start_worker();
461 };
462
463 process_msgs = function() {
464 var msg;
465 if (msgs.length) {
466 msg = msgs.shift();
467 return growl.notify(msg.msg, msg.opts);
468 } else {
469 return stop_worker();
470 }
471 };
472
473 __t('toaster.utils').StringUtil = (function() {
474
475 function StringUtil() {}
476
477 StringUtil.titleize = function(str) {
478 var index, word, words, _i, _len;
479 words = str.match(/[a-z]+/gi);
480 for (index = _i = 0, _len = words.length; _i < _len; index = ++_i) {
481 word = words[index];
482 words[index] = StringUtil.ucasef(word);
483 }
484 return words.join(" ");
485 };
486
487 StringUtil.ucasef = function(str) {
488 var output;
489 output = str.substr(0, 1).toUpperCase();
490 return output += str.substr(1).toLowerCase();
491 };
492
493 return StringUtil;
494
495 })();
496
497 __t('toaster.core').Script = (function() {
498 var ArrayUtil, cs, fs, path;
499
500 fs = require("fs");
501
502 path = require('path');
503
504 cs = require("coffee-script");
505
506 ArrayUtil = toaster.utils.ArrayUtil;
507
508 function Script(builder, folderpath, realpath, alias, opts) {
509 this.builder = builder;
510 this.folderpath = folderpath;
511 this.realpath = realpath;
512 this.alias = alias;
513 this.opts = opts;
514 this.getinfo();
515 }
516
517 Script.prototype.getinfo = function(declare_ns) {
518 var baseclass, decl, extending, item, klass, name, repl, requirements, rgx, rgx_ext, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _results;
519 if (declare_ns == null) {
520 declare_ns = true;
521 }
522 this.raw = fs.readFileSync(this.realpath, "utf-8");
523 this.dependencies_collapsed = [];
524 this.baseclasses = [];
525 this.filepath = this.realpath.replace(this.folderpath, '');
526 if (this.alias != null) {
527 this.filepath = path.join(path.sep, this.alias, this.filepath);
528 }
529 this.filename = path.basename(this.filepath);
530 this.filefolder = path.dirname(this.filepath);
531 this.namespace = "";
532 if (this.filepath.indexOf(path.sep) === -1) {
533 this.filefolder = "";
534 }
535 this.namespace = this.filefolder.replace(new RegExp("\\" + path.sep, "g"), ".");
536 this.namespace = this.namespace.replace(/^\.?(.*)\.?$/g, "$1");
537 rgx = /^(class)+\s+([^\s]+)+(\s(extends)\s+([\w.]+))?/mg;
538 rgx_ext = /(^|=\s*)(class)\s(\w+)\s(extends)\s(\\w+)\s*$/gm;
539 if (this.raw.match(rgx) != null) {
540 if (this.namespace !== "" && this.builder.packaging) {
541 _ref = [].concat(this.raw.match(rgx));
542 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
543 decl = _ref[_i];
544 name = decl.match(/class\s([^\s]+)/);
545 name = (name[1].split('.')).pop();
546 extending = decl.match(/(\sextends\s[^\s]+$)/m);
547 if (extending) {
548 extending = extending[0];
549 }
550 extending || (extending = "");
551 repl = "class " + this.namespace + "." + name + extending;
552 if (decl !== repl) {
553 this.raw = this.raw.replace(decl, repl);
554 fs.writeFileSync(this.realpath, this.raw);
555 }
556 }
557 this.classpath = "" + this.namespace + "." + this.classname;
558 }
559 this.classname = this.raw.match(rgx)[3];
560 _ref2 = (_ref1 = this.raw.match(rgx_ext)) != null ? _ref1 : [];
561 for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
562 klass = _ref2[_j];
563 baseclass = klass.match(rgx_ext)[5];
564 this.baseclasses.push(baseclass);
565 }
566 }
567 if (/(#<<\s)(.*)/g.test(this.raw)) {
568 requirements = this.raw.match(/(#<<\s)(.*)/g);
569 _results = [];
570 for (_k = 0, _len2 = requirements.length; _k < _len2; _k++) {
571 item = requirements[_k];
572 item = /(#<<\s)(.*)/.exec(item)[2];
573 item = item.replace(/\s/g, "");
574 if (path.sep === "\\") {
575 item = item.replace(/(\/)/g, "\\");
576 }
577 _results.push(this.dependencies_collapsed = this.dependencies_collapsed.concat(item));
578 }
579 return _results;
580 }
581 };
582
583 Script.prototype.expand_dependencies = function() {
584 var dependency, expanded, files, found, index, reg, _i, _j, _len, _len1, _ref;
585 files = this.builder.files;
586 this.dependencies = [];
587 _ref = this.dependencies_collapsed;
588 for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) {
589 dependency = _ref[index];
590 if ((dependency.substr(0, 1)) === path.sep) {
591 dependency = dependency.substr(1);
592 }
593 if (dependency.substr(-1) !== "*") {
594 this.dependencies.push("" + path.sep + dependency + ".coffee");
595 continue;
596 }
597 reg = new RegExp(dependency.replace(/(\/|\\)/g, "\\$1"));
598 found = ArrayUtil.find_all(files, reg, "filepath", true, true);
599 if (found.length <= 0) {
600 warn(("Nothing found inside " + ("'" + dependency).white + "'").yellow);
601 continue;
602 }
603 for (_j = 0, _len1 = found.length; _j < _len1; _j++) {
604 expanded = found[_j];
605 if (expanded.item.filepath !== this.filepath) {
606 this.dependencies.push(expanded.item.filepath);
607 }
608 }
609 }
610 return this.dependencies;
611 };
612
613 return Script;
614
615 })();
616
617 __t('toaster').Cli = (function() {
618 var optimist;
619
620 optimist = require('optimist');
621
622 function Cli() {
623 var usage;
624 usage = "" + 'CoffeeToaster'.bold + "\n";
625 usage += " Minimalist build system for CoffeeScript\n\n".grey;
626 usage += "" + 'Usage:' + "\n";
627 usage += " toaster [" + 'options'.green + "] [" + 'path'.green + "]\n\n";
628 usage += "" + 'Examples:' + "\n";
629 usage += " toaster -n myawsomeapp (" + 'required'.red + ")\n";
630 usage += " toaster -i [myawsomeapp] (" + 'optional'.green + ")\n";
631 usage += " toaster -w [myawsomeapp] (" + 'optional'.green + ")\n";
632 usage += " toaster -wd [myawsomeapp] (" + 'optional'.green + ")";
633 this.argv = (this.opts = optimist.usage(usage).alias('n', 'new').describe('n', "Scaffold a very basic new App").alias('i', 'init').describe('i', "Create a config (toaster.coffee) file").alias('w', 'watch').describe('w', "Start watching/compiling your project").alias('c', 'compile').describe('c', "Compile the entire project, without watching it.").alias('d', 'debug').describe('d', 'Debug mode (compile js files individually)').alias('a', 'autorun').describe('a', 'Execute the script in node.js after compilation').alias('j', 'config').string('j').describe('j', "Config file formatted as a json-string.").alias('f', 'config-file').string('f').describe('f', "Path to a different config file.").alias('v', 'version').describe('v', '').alias('h', 'help').describe('h', '')).argv;
634 }
635
636 return Cli;
637
638 })();
639
640 __t('toaster.core').Builder = (function() {
641 var ArrayUtil, FnUtil, Script, StringUtil, cp, cs, fs, fsu, missing, path, uglify, uglify_parser, _ref;
642
643 fs = require('fs');
644
645 fsu = require('fs-util');
646
647 path = require('path');
648
649 cs = require("coffee-script");
650
651 cp = require("child_process");
652
653 uglify = require("uglify-js").uglify;
654
655 uglify_parser = require("uglify-js").parser;
656
657 Script = toaster.core.Script;
658
659 _ref = toaster.utils, FnUtil = _ref.FnUtil, ArrayUtil = _ref.ArrayUtil, StringUtil = _ref.StringUtil;
660
661 Builder.prototype.watchers = null;
662
663 Builder.prototype._include_tmpl = "document.write('<scri'+'pt src=\"%SRC%\"></scr'+'ipt>')";
664
665 function Builder(toaster, cli, config) {
666 this.toaster = toaster;
667 this.cli = cli;
668 this.config = config;
669 this.merge_vendors = __bind(this.merge_vendors, this);
670
671 this.on_fs_change = __bind(this.on_fs_change, this);
672
673 this.build = __bind(this.build, this);
674
675 this.vendors = this.config.vendors;
676 this.bare = this.config.bare;
677 this.packaging = this.config.packaging;
678 this.expose = this.config.expose;
679 this.minify = this.config.minify;
680 this.exclude = [].concat(this.config.exclude);
681 this.httpfolder = this.config.httpfolder;
682 this.release = this.config.release;
683 this.debug = this.config.debug;
684 this.init();
685 if (this.cli.argv.w) {
686 this.watch();
687 }
688 }
689
690 Builder.prototype.init = function() {
691 var falias, file, folder, fpath, include, item, result, s, _i, _len, _ref1, _results;
692 this.files = this.config.files;
693 _ref1 = this.config.src_folders;
694 _results = [];
695 for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
696 folder = _ref1[_i];
697 result = fsu.find(folder.path, /.coffee$/m);
698 fpath = folder.path;
699 falias = folder.alias;
700 _results.push((function() {
701 var _j, _k, _len1, _len2, _ref2, _results1;
702 _results1 = [];
703 for (_j = 0, _len1 = result.length; _j < _len1; _j++) {
704 file = result[_j];
705 include = true;
706 _ref2 = this.exclude;
707 for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
708 item = _ref2[_k];
709 include &= !(new RegExp(item).test(file));
710 }
711 if (include) {
712 s = new Script(this, fpath, file, falias, this.cli);
713 _results1.push(this.files.push(s));
714 } else {
715 _results1.push(void 0);
716 }
717 }
718 return _results1;
719 }).call(this));
720 }
721 return _results;
722 };
723
724 Builder.prototype.reset = function() {
725 var watcher, _i, _len, _ref1, _results;
726 _ref1 = this.watchers;
727 _results = [];
728 for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
729 watcher = _ref1[_i];
730 _results.push(watcher.close());
731 }
732 return _results;
733 };
734
735 Builder.prototype.build = function(header_code, footer_code) {
736 var args, ast, contents, f, files, i, include, namespaces, now, tmpl, vendors, _i, _j, _len, _ref1;
737 if (header_code == null) {
738 header_code = "";
739 }
740 if (footer_code == null) {
741 footer_code = "";
742 }
743 namespaces = this.build_namespaces();
744 vendors = this.merge_vendors();
745 contents = [];
746 if (vendors !== "") {
747 contents.push(vendors);
748 }
749 if (this.packaging) {
750 contents.push(namespaces);
751 }
752 if (header_code !== "") {
753 contents.push(header_code);
754 }
755 contents.push(this.compile());
756 if (header_code !== "") {
757 contents.push(footer_code);
758 }
759 contents = contents.join('\n');
760 if (this.minify) {
761 ast = uglify_parser.parse(contents);
762 ast = uglify.ast_mangle(ast);
763 ast = uglify.ast_squeeze(ast);
764 contents = uglify.gen_code(ast);
765 }
766 fs.writeFileSync(this.release, contents);
767 now = (("" + (new Date)).match(/[0-9]{2}\:[0-9]{2}\:[0-9]{2}/))[0];
768 log(("[" + now + "] " + 'Compiled'.bold + " " + this.release).green);
769 if (this.cli.argv.d && (this.debug != null) && !this.cli.argv.a) {
770 files = this.compile_for_debug();
771 for (i = _i = 0, _len = files.length; _i < _len; i = ++_i) {
772 f = files[i];
773 include = path.normalize("" + this.httpfolder + "/toaster/" + f);
774 if (path.sep === "\\") {
775 include = include.replace(/\\/g, "\/");
776 }
777 tmpl = this._include_tmpl.replace("%SRC%", include);
778 files[i] = tmpl;
779 }
780 contents = [];
781 if (vendors !== "") {
782 contents.push(vendors);
783 }
784 if (this.packaging) {
785 contents.push(namespaces);
786 }
787 if (header_code !== "") {
788 contents.push(header_code);
789 }
790 contents.push(files.join("\n"));
791 if (header_code !== "") {
792 contents.push(footer_code);
793 }
794 contents = contents.join('\n');
795 fs.writeFileSync(this.debug, contents);
796 log(("[" + now + "] " + 'Compiled'.bold + " " + this.debug).green);
797 }
798 if (this.cli.argv.a) {
799 args = [];
800 if (process.argv.length > 3) {
801 for (i = _j = 3, _ref1 = process.argv.length; _j < _ref1; i = _j += 1) {
802 args.push(process.argv[i]);
803 }
804 }
805 if (this.child != null) {
806 log("Application restarted:".blue);
807 this.child.kill('SIGHUP');
808 } else {
809 log("Application started:".blue);
810 }
811 if (this.cli.argv.d) {
812 return this.child = cp.fork(this.release, args, {
813 execArgv: ['--debug-brk']
814 });
815 } else {
816 return this.child = cp.fork(this.release, args);
817 }
818 }
819 };
820
821 Builder.prototype.build_namespaces = function() {
822 var buffer, folder, name, scope, t, tree, _i, _len, _ref1;
823 tree = {};
824 _ref1 = this.config.src_folders;
825 for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
826 folder = _ref1[_i];
827 if (folder.alias != null) {
828 t = (tree[folder.alias] = {});
829 }
830 this.build_ns_tree(t || tree, folder.path);
831 }
832 buffer = "";
833 for (name in tree) {
834 scope = tree[name];
835 buffer += "var " + name + " = ";
836 if (this.expose != null) {
837 buffer += "" + this.expose + "." + name + " = ";
838 }
839 buffer += (JSON.stringify(scope, null, '')).replace(/\"/g, "'");
840 buffer += ";\n";
841 }
842 return buffer;
843 };
844
845 Builder.prototype.build_ns_tree = function(tree, folderpath) {
846 var folder, folders, include, item, _i, _j, _len, _len1, _ref1, _results;
847 folders = fsu.ls(folderpath);
848 _results = [];
849 for (_i = 0, _len = folders.length; _i < _len; _i++) {
850 folder = folders[_i];
851 include = true;
852 _ref1 = this.exclude;
853 for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
854 item = _ref1[_j];
855 include &= !(new RegExp(item).test(folder));
856 }
857 if (include) {
858 _results.push(this.build_ns_tree((tree[folder.match(/[^\/\\]+$/m)] = {}), folder));
859 } else {
860 _results.push(void 0);
861 }
862 }
863 return _results;
864 };
865
866 Builder.prototype.watch = function() {
867 var src, temp, vendor, watcher, _i, _j, _len, _len1, _ref1, _ref2, _results;
868 this.watchers = [];
869 _ref1 = this.config.src_folders;
870 for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
871 src = _ref1[_i];
872 this.watchers.push((watcher = fsu.watch(src.path, /.coffee$/m)));
873 watcher.on('create', FnUtil.proxy(this.on_fs_change, src, 'create'));
874 watcher.on('change', FnUtil.proxy(this.on_fs_change, src, 'change'));
875 watcher.on('delete', FnUtil.proxy(this.on_fs_change, src, 'delete'));
876 }
877 _ref2 = this.vendors;
878 _results = [];
879 for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
880 vendor = _ref2[_j];
881 temp = fsu.watch(vendor);
882 temp.on('create', FnUtil.proxy(this.on_fs_change, src, 'create'));
883 temp.on('change', FnUtil.proxy(this.on_fs_change, src, 'change'));
884 _results.push(temp.on('delete', FnUtil.proxy(this.on_fs_change, src, 'delete')));
885 }
886 return _results;
887 };
888
889 Builder.prototype.on_fs_change = function(src, ev, f) {
890 var falias, file, fpath, include, item, msg, now, relative_path, s, spath, type, _i, _len, _ref1;
891 if (f.type === "dir" && ev === "create") {
892 return;
893 }
894 fpath = f.location;
895 spath = src.path;
896 if (src.alias != null) {
897 falias = path.sep + src.alias;
898 } else {
899 falias = '';
900 }
901 include = true;
902 _ref1 = this.exclude;
903 for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
904 item = _ref1[_i];
905 include &= !(new RegExp(item).test(fpath));
906 }
907 if (!include) {
908 return;
909 }
910 type = StringUtil.titleize(f.type);
911 relative_path = fpath.replace(spath, falias);
912 now = (("" + (new Date)).match(/[0-9]{2}\:[0-9]{2}\:[0-9]{2}/))[0];
913 switch (ev) {
914 case "create":
915 if (f.type === "file") {
916 s = new Script(this, spath, fpath, falias, this.cli);
917 this.files.push(s);
918 }
919 msg = "" + ('New ' + f.type + ' created').bold;
920 log(("[" + now + "] " + msg + " " + f.location).cyan);
921 break;
922 case "delete":
923 file = ArrayUtil.find(this.files, relative_path, "filepath");
924 if (file === null) {
925 return;
926 }
927 this.files.splice(file.index, 1);
928 msg = "" + (type + ' deleted, stop watching').bold;
929 log(("[" + now + "] " + msg + " " + f.location).red);
930 break;
931 case "change":
932 file = ArrayUtil.find(this.files, relative_path, "filepath");
933 if (file === null) {
934 warn("CHANGED FILE IS APPARENTLY NULL...");
935 } else {
936 file.item.getinfo();
937 msg = "" + (type + ' changed').bold;
938 log(("[" + now + "] " + msg + " " + f.location).cyan);
939 }
940 }
941 if (this.toaster.before_build === null || this.toaster.before_build()) {
942 return this.build();
943 }
944 };
945
946 Builder.prototype.compile = function() {
947 var file, msg, output, _i, _j, _len, _len1, _ref1, _ref2;
948 _ref1 = this.files;
949 for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
950 file = _ref1[_i];
951 try {
952 cs.compile(file.raw);
953 } catch (err) {
954 msg = err.message.replace('"', '\\"');
955 msg = ("" + msg.white + " at file: ") + ("" + file.filepath).bold.red;
956 error(msg);
957 return null;
958 }
959 }
960 _ref2 = this.files;
961 for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
962 file = _ref2[_j];
963 file.expand_dependencies();
964 }
965 this.reorder();
966 output = ((function() {
967 var _k, _len2, _ref3, _results;
968 _ref3 = this.files;
969 _results = [];
970 for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) {
971 file = _ref3[_k];
972 _results.push(file.raw);
973 }
974 return _results;
975 }).call(this)).join("\n");
976 return output = cs.compile(output, {
977 bare: this.bare
978 });
979 };
980
981 Builder.prototype.compile_for_debug = function() {
982 var absolute_path, file, files, find, folder_path, index, relative_path, release_path, _i, _len, _ref1;
983 release_path = path.dirname(this.debug);
984 release_path = path.join(release_path, "toaster");
985 if (fs.existsSync(release_path)) {
986 fsu.rm_rf(release_path);
987 }
988 fsu.mkdir_p(release_path);
989 files = [];
990 _ref1 = this.files;
991 for (index = _i = 0, _len = _ref1.length; _i < _len; index = ++_i) {
992 file = _ref1[index];
993 find = "" + this.toaster.basepath + path.sep;
994 relative_path = file.filepath.replace(find, "");
995 relative_path = relative_path.replace(".coffee", ".js");
996 absolute_path = path.resolve(path.join(release_path, relative_path));
997 folder_path = path.dirname(absolute_path);
998 if (!fs.existsSync(folder_path)) {
999 fsu.mkdir_p(folder_path);
1000 }
1001 try {
1002 fs.writeFileSync(absolute_path, cs.compile(file.raw, {
1003 bare: this.bare
1004 }));
1005 } catch (err) {
1006 continue;
1007 }
1008 files.push(relative_path);
1009 }
1010 return files;
1011 };
1012
1013 missing = {};
1014
1015 Builder.prototype.reorder = function(cycling) {
1016 var bc, dependency, dependency_index, file, file_index, filepath, found, i, index, not_found, _i, _j, _len, _len1, _ref1, _ref2, _results;
1017 if (cycling == null) {
1018 cycling = false;
1019 }
1020 if (cycling === false) {
1021 this.missing = {};
1022 }
1023 _ref1 = this.files;
1024 _results = [];
1025 for (i = _i = 0, _len = _ref1.length; _i < _len; i = ++_i) {
1026 file = _ref1[i];
1027 if (!file.dependencies.length && !file.baseclasses.length) {
1028 continue;
1029 }
1030 _ref2 = file.dependencies;
1031 for (index = _j = 0, _len1 = _ref2.length; _j < _len1; index = ++_j) {
1032 filepath = _ref2[index];
1033 dependency = ArrayUtil.find(this.files, filepath, "filepath");
1034 if (dependency != null) {
1035 dependency_index = dependency.index;
1036 }
1037 if (dependency_index < i && (dependency != null)) {
1038 continue;
1039 }
1040 if (dependency != null) {
1041 if (ArrayUtil.has(dependency.item.dependencies, file.filepath)) {
1042 file.dependencies.splice(index, 1);
1043 warn("Circular dependency found between ".yellow + filepath.grey.bold + " and ".yellow + file.filepath.grey.bold);
1044 continue;
1045 } else {
1046 this.files.splice(index, 0, dependency.item);
1047 this.files.splice(dependency.index + 1, 1);
1048 this.reorder(true);
1049 break;
1050 }
1051 } else if (this.missing[filepath] !== true) {
1052 this.missing[filepath] = true;
1053 file.dependencies.push(filepath);
1054 file.dependencies.splice(index, 1);
1055 warn(("" + 'Dependency'.yellow + " " + filepath.bold.grey + " ") + ("" + 'not found for file'.yellow + " ") + file.filepath.grey.bold);
1056 }
1057 }
1058 file_index = ArrayUtil.find(this.files, file.filepath, "filepath");
1059 file_index = file_index.index;
1060 _results.push((function() {
1061 var _k, _len2, _ref3, _results1;
1062 _ref3 = file.baseclasses;
1063 _results1 = [];
1064 for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) {
1065 bc = _ref3[_k];
1066 found = ArrayUtil.find(this.files, bc, "classname");
1067 not_found = (found === null) || (found.index > file_index);
1068 if (not_found && !this.missing[bc]) {
1069 this.missing[bc] = true;
1070 _results1.push(warn("Base class ".yellow + ("" + bc + " ").bold.grey + "not found for class ".yellow + ("" + file.classname + " ").bold.grey + "in file ".yellow + file.filepath.bold.grey));
1071 } else {
1072 _results1.push(void 0);
1073 }
1074 }
1075 return _results1;
1076 }).call(this));
1077 }
1078 return _results;
1079 };
1080
1081 Builder.prototype.merge_vendors = function() {
1082 var buffer, vendor, _i, _len, _ref1;
1083 buffer = [];
1084 _ref1 = this.vendors;
1085 for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
1086 vendor = _ref1[_i];
1087 if (fs.existsSync(vendor)) {
1088 buffer.push(fs.readFileSync(vendor, 'utf-8'));
1089 } else {
1090 warn("Vendor not found at ".white + vendor.yellow.bold);
1091 }
1092 }
1093 return buffer.join("\n");
1094 };
1095
1096 return Builder;
1097
1098 })();
1099
1100 __t('toaster.generators').Config = (function(_super) {
1101 var fs, path;
1102
1103 __extends(Config, _super);
1104
1105 path = require("path");
1106
1107 fs = require("fs");
1108
1109 Config.prototype.tpl = "# => SRC FOLDER\ntoast '%src%'\n\n # EXCLUDED FOLDERS (optional)\n # exclude: ['folder/to/exclude', 'another/folder/to/exclude', ... ]\n\n # => VENDORS (optional)\n # vendors: ['vendors/x.js', 'vendors/y.js', ... ]\n\n # => OPTIONS (optional, default values listed)\n # bare: false\n # packaging: true\n # expose: ''\n # minify: true\n\n # => HTTPFOLDER (optional), RELEASE / DEBUG (required)\n httpfolder: '%httpfolder%'\n release: '%release%'\n debug: '%debug%'";
1110
1111 function Config(basepath) {
1112 this.basepath = basepath;
1113 this.write = __bind(this.write, this);
1114
1115 this.create = __bind(this.create, this);
1116
1117 }
1118
1119 Config.prototype.create = function() {
1120 var q1, q2, q3,
1121 _this = this;
1122 q1 = "Path to your src folder? [src] : ";
1123 q2 = "Path to your release file? [www/js/app.js] : ";
1124 q3 = "Starting from your webroot '/', what's the folderpath to " + "reach your release file? (i.e. js) (optional) : ";
1125 return this.ask(q1.magenta, /.+/, function(src) {
1126 return _this.ask(q2.magenta, /.+/, function(release) {
1127 return _this.ask(q3.cyan, /.*/, function(httpfolder) {
1128 return _this.write(src, release, httpfolder);
1129 });
1130 });
1131 });
1132 };
1133
1134 Config.prototype.write = function(src, release, httpfolder) {
1135 var buffer, filename, filepath, parts, question, rgx,
1136 _this = this;
1137 filepath = path.join(this.basepath, "toaster.coffee");
1138 rgx = /(\/)?((\w+)(\.*)(\w+$))/;
1139 parts = rgx.exec(release);
1140 filename = parts[2];
1141 if (filename.indexOf(".") > 0) {
1142 debug = release.replace(rgx, "$1$3-debug$4$5");
1143 } else {
1144 debug = "" + release + "-debug";
1145 }
1146 buffer = this.tpl.replace("%src%", src.replace(/\\/g, "\/"));
1147 buffer = buffer.replace("%release%", release.replace(/\\/g, "\/"));
1148 buffer = buffer.replace("%debug%", debug.replace(/\\/g, "\/"));
1149 buffer = buffer.replace("%httpfolder%", httpfolder.replace(/\\/g, "\/"));
1150 if (fs.existsSync(filepath)) {
1151 question = "\tDo you want to overwrite the file: " + filepath.yellow;
1152 question += " ? [y/N] : ".white;
1153 return this.ask(question, /.*?/, function(overwrite) {
1154 if (overwrite.match(/y/i)) {
1155 _this.save(filepath, buffer);
1156 return process.exit();
1157 }
1158 });
1159 } else {
1160 this.save(filepath, buffer);
1161 return process.exit();
1162 }
1163 };
1164
1165 Config.prototype.save = function(filepath, contents) {
1166 fs.writeFileSync(filepath, contents);
1167 log("" + 'Created'.green.bold + " " + filepath);
1168 return process.exit();
1169 };
1170
1171 return Config;
1172
1173 })(toaster.generators.Question);
1174
1175 __t('toaster.generators').Project = (function(_super) {
1176 var FsUtil, fs, fsu, path;
1177
1178 __extends(Project, _super);
1179
1180 path = require("path");
1181
1182 fs = require("fs");
1183
1184 fsu = require('fs-util');
1185
1186 FsUtil = toaster.utils.FsUtil;
1187
1188 function Project(basepath) {
1189 this.basepath = basepath;
1190 this.scaffold = __bind(this.scaffold, this);
1191
1192 }
1193
1194 Project.prototype.create = function(folderpath, name, src, release) {
1195 var error_msg, q1, q2, q3,
1196 _this = this;
1197 if ((typeof folderpath) !== 'string') {
1198 error_msg = "You need to inform a target path!\n";
1199 error_msg += "\ttoaster -n myawesomeapp".green;
1200 return error(error_msg);
1201 }
1202 if ((name != null) && (src != null) && (release != null)) {
1203 return this.scaffold(folderpath, name, src, release);
1204 }
1205 q1 = "Path to your src folder? [src] : ";
1206 q2 = "Path to your release file? [www/js/app.js] : ";
1207 q3 = "Starting from your webroot '/', what's the folderpath to " + "reach your release file? (i.e. js) (optional) : ";
1208 return this.ask(q1.magenta, /.*/, function(src) {
1209 if (src == null) {
1210 src = null;
1211 }
1212 return _this.ask(q2.magenta, /.*/, function(release) {
1213 if (release == null) {
1214 release = null;
1215 }
1216 return _this.ask(q3.cyan, /.*/, function(httpfolder) {
1217 var $httpfolder, $release, $src;
1218 if (httpfolder == null) {
1219 httpfolder = null;
1220 }
1221 $src = src || "src";
1222 $release = release || "www/js/app.js";
1223 if (src === '' && release === '' && httpfolder === '') {
1224 $httpfolder = 'js';
1225 } else {
1226 $httpfolder = httpfolder || "";
1227 }
1228 _this.scaffold(folderpath, $src, $release, $httpfolder);
1229 return process.exit();
1230 });
1231 });
1232 });
1233 };
1234
1235 Project.prototype.scaffold = function(target, src, release, httpfolder) {
1236 var config, releasedir, releasefile, srcdir, vendorsdir;
1237 target = path.resolve(target);
1238 srcdir = path.join(target, src);
1239 vendorsdir = path.join(target, "vendors");
1240 releasefile = path.join(target, release);
1241 releasedir = path.dirname(releasefile);
1242 if (fsu.mkdir_p(target)) {
1243 log("" + 'Created'.green.bold + " " + target);
1244 }
1245 if (fsu.mkdir_p(srcdir)) {
1246 log("" + 'Created'.green.bold + " " + srcdir);
1247 }
1248 if (fsu.mkdir_p(vendorsdir)) {
1249 log("" + 'Created'.green.bold + " " + vendorsdir);
1250 }
1251 if (fsu.mkdir_p(releasedir)) {
1252 log("" + 'Created'.green.bold + " " + releasedir);
1253 }
1254 srcdir = srcdir.replace(target, "").substr(1);
1255 releasefile = releasefile.replace(target, "").substr(1);
1256 config = new toaster.generators.Config(target);
1257 return config.write(srcdir, releasefile, httpfolder);
1258 };
1259
1260 return Project;
1261
1262 })(toaster.generators.Question);
1263
1264 fs = require('fs');
1265
1266 path = require('path');
1267
1268 exec = (require("child_process")).exec;
1269
1270 __t('toaster.misc').InjectNS = (function() {
1271
1272 function InjectNS(builders) {
1273 var builder, f, _i, _j, _len, _len1, _ref, _ref1;
1274 this.builders = builders;
1275 console.log("Declaring namespaces for files...");
1276 _ref = this.builders;
1277 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1278 builder = _ref[_i];
1279 _ref1 = builder.files;
1280 for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
1281 f = _ref1[_j];
1282 f.getinfo(true);
1283 fs.writeFileSync(f.realpath, f.raw);
1284 f.getinfo(false);
1285 console.log(f.realpath);
1286 }
1287 }
1288 console.log("...done.");
1289 }
1290
1291 return InjectNS;
1292
1293 })();
1294
1295 exports.run = function() {
1296 return new Toaster;
1297 };
1298
1299 exports.toaster = toaster;
1300
1301 exports.Toaster = Toaster = (function() {
1302 var colors, fsu;
1303
1304 fs = require("fs");
1305
1306 fsu = require("fs-util");
1307
1308 path = require("path");
1309
1310 exec = (require("child_process")).exec;
1311
1312 colors = require('colors');
1313
1314 Toaster.prototype.before_build = null;
1315
1316 function Toaster(basedir, options, skip_initial_build) {
1317 var base, config, contents, filepath, flag, k, schema, v, _i, _len, _ref;
1318 if (options == null) {
1319 options = null;
1320 }
1321 if (skip_initial_build == null) {
1322 skip_initial_build = false;
1323 }
1324 this.basepath = path.resolve(basedir || ".");
1325 this.cli = new toaster.Cli(options);
1326 _ref = 'nicwd'.split('');
1327 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1328 flag = _ref[_i];
1329 if (typeof (base = this.cli.argv[flag]) === 'string') {
1330 this.basepath = path.resolve(base);
1331 break;
1332 }
1333 }
1334 if (options != null) {
1335 for (k in options) {
1336 v = options[k];
1337 this.cli.argv[k] = v;
1338 }
1339 }
1340 if (this.cli.argv.v) {
1341 filepath = path.join(__dirname, "/../package.json");
1342 contents = fs.readFileSync(filepath, "utf-8");
1343 schema = JSON.parse(contents);
1344 return log(schema.version);
1345 } else if (this.cli.argv.n) {
1346 new toaster.generators.Project(this.basepath).create(this.cli.argv.n);
1347 } else if (this.cli.argv.i) {
1348 new toaster.generators.Config(this.basepath).create();
1349 } else if (this.cli.argv.ns) {
1350 this.toast = new toaster.Toast(this);
1351 new toaster.misc.InjectNS(this.toast.builders);
1352 } else if ((base = this.cli.argv.w || this.cli.argv.c || this.cli.argv.a)) {
1353 config = options && options.config ? options.config : null;
1354 this.toast = new toaster.Toast(this);
1355 if (!skip_initial_build) {
1356 this.build();
1357 }
1358 } else {
1359 return log(this.cli.opts.help());
1360 }
1361 }
1362
1363 Toaster.prototype.build = function(header_code, footer_code) {
1364 var builder, _i, _len, _ref, _results;
1365 if (header_code == null) {
1366 header_code = "";
1367 }
1368 if (footer_code == null) {
1369 footer_code = "";
1370 }
1371 _ref = this.toast.builders;
1372 _results = [];
1373 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1374 builder = _ref[_i];
1375 _results.push(builder.build(header_code, footer_code));
1376 }
1377 return _results;
1378 };
1379
1380 Toaster.prototype.reset = function() {
1381 var builder, _i, _len, _ref;
1382 _ref = this.toast.builders;
1383 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1384 builder = _ref[_i];
1385 builder.reset();
1386 }
1387 return exports.run();
1388 };
1389
1390 return Toaster;
1391
1392 })();
1393
1394}).call(this);