UNPKG

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