UNPKG

32.7 kBJavaScriptView Raw
1(function() {
2 var Buildr, caterpillar, coffee, csslint, cwd, fs, jshint, jsp, less, path, pro, pulverizr, uglify, util, watchTree, _base,
3 __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
4 __slice = [].slice;
5
6 fs = require('fs');
7
8 path = require('path');
9
10 util = require('bal-util');
11
12 coffee = require('coffee-script');
13
14 less = require('less');
15
16 pulverizr = require('pulverizr');
17
18 csslint = require('csslint').CSSLint;
19
20 jshint = require('jshint').JSHINT;
21
22 uglify = require('uglify-js');
23
24 jsp = uglify.parser;
25
26 pro = uglify.uglify;
27
28 cwd = process.cwd();
29
30 watchTree = false;
31
32 caterpillar = require('caterpillar');
33
34 (_base = Array.prototype).has || (_base.has = function(value2) {
35 var value1, _i, _len;
36 for (_i = 0, _len = this.length; _i < _len; _i++) {
37 value1 = this[_i];
38 if (value1 === value2) {
39 return true;
40 }
41 }
42 return false;
43 });
44
45 Buildr = (function() {
46
47 Buildr.prototype.config = {
48 name: null,
49 log: true,
50 watch: false,
51 buildHandler: false,
52 rebuildHandler: false,
53 successHandler: false,
54 srcPath: false,
55 outPath: false,
56 checkScripts: false,
57 checkStyles: false,
58 jshintOptions: false,
59 csslintOptions: false,
60 compressScripts: false,
61 compressStyles: false,
62 compressImages: false,
63 scriptsOrder: false,
64 stylesOrder: false,
65 bundleScriptPath: false,
66 bundleStylePath: false,
67 deleteBundledFiles: true,
68 srcLoaderHeader: false,
69 srcLoaderPath: false
70 };
71
72 Buildr.prototype.filesToClean = [];
73
74 Buildr.prototype.errors = [];
75
76 Buildr.prototype.watching = false;
77
78 Buildr.prototype.processing = false;
79
80 Buildr.prototype.logger = false;
81
82 function Buildr(options) {
83 var key, tmp, value, _base1, _base2, _ref,
84 _this = this;
85 if (options == null) {
86 options = {};
87 }
88 this.log = __bind(this.log, this);
89
90 this.filesToClean = [];
91 this.errors = [];
92 tmp = {};
93 _ref = this.config;
94 for (key in _ref) {
95 value = _ref[key];
96 tmp[key] = value;
97 }
98 for (key in options) {
99 value = options[key];
100 tmp[key] = value;
101 }
102 this.config = tmp;
103 (_base1 = this.config).buildHandler || (_base1.buildHandler = function(err) {
104 if (err) {
105 _this.log('error', err);
106 throw err;
107 }
108 _this.log('info', 'Building completed');
109 if (_this.config.successHandler) {
110 return _this.config.successHandler.call(_this);
111 }
112 });
113 (_base2 = this.config).rebuildHandler || (_base2.rebuildHandler = function(err) {
114 if (err) {
115 _this.log('error', err);
116 throw err;
117 }
118 _this.log('info', 'ReBuilding completed');
119 if (_this.config.successHandler) {
120 return _this.config.successHandler.call(_this);
121 }
122 });
123 if (this.config.log === true) {
124 this.config.log = 6;
125 }
126 this.logger || (this.logger = this.config.logger || new caterpillar.Logger({
127 level: this.config.log || 6,
128 transports: {
129 level: this.config.log || 6,
130 formatter: {
131 module: module
132 }
133 }
134 }));
135 true;
136 }
137
138 Buildr.prototype.log = function() {
139 var args, type;
140 args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
141 if (this.config.name) {
142 type = args.shift();
143 args.unshift("[" + this.config.name + "]");
144 args.unshift(type);
145 }
146 return this.logger.log.apply(this.logger, args);
147 };
148
149 Buildr.prototype.watch = function(next) {
150 var buildr, log, watcher;
151 if (this.watching) {
152 return;
153 } else {
154 this.watching = true;
155 }
156 if (!watchTree) {
157 watchTree = require('watch-tree-maintained');
158 }
159 buildr = this;
160 log = this.log;
161 next || (next = this.config.rebuildHandler || this.config.buildHandler);
162 log('debug', 'Setting up watching...');
163 watcher = watchTree.watchTree(this.config.srcPath);
164 watcher.on('fileDeleted', function(path) {
165 return buildr.process(function() {
166 log('info', 'Rebuilt due to file delete at ' + (new Date()).toLocaleString());
167 return next.apply(next, arguments);
168 });
169 });
170 watcher.on('fileCreated', function(path, stat) {
171 return buildr.process(function() {
172 log('info', 'Rebuilt due to file create at ' + (new Date()).toLocaleString());
173 return next.apply(next, arguments);
174 });
175 });
176 watcher.on('fileModified', function(path, stat) {
177 return buildr.process(function() {
178 log('info', 'Rebuilt due to file change at ' + (new Date()).toLocaleString());
179 return next.apply(next, arguments);
180 });
181 });
182 log('debug', 'Watching setup');
183 return next(false);
184 };
185
186 Buildr.prototype.process = function(next) {
187 var log,
188 _this = this;
189 log = this.log;
190 next || (next = this.config.buildHandler);
191 if (this.processing) {
192 log('info', 'Processing postponed');
193 return;
194 }
195 this.processing = true;
196 log('info', 'Processing started');
197 if (this.config.watch) {
198 this.watch();
199 }
200 return this.checkConfiguration(function(err) {
201 if (err) {
202 return next(err);
203 }
204 return _this.checkFiles(function(err) {
205 if (err) {
206 return next(err);
207 }
208 return _this.cpSrcToOut(function(err) {
209 if (err) {
210 return next(err);
211 }
212 return _this.generateFiles(function(err) {
213 if (err) {
214 return next(err);
215 }
216 return _this.cleanOutPath(function(err) {
217 if (err) {
218 return next(err);
219 }
220 return _this.compressFiles(function(err) {
221 _this.processing = false;
222 log('info', 'Processing finished');
223 return next(err);
224 });
225 });
226 });
227 });
228 });
229 });
230 };
231
232 Buildr.prototype.checkConfiguration = function(next) {
233 var log, tasks, _base1,
234 _this = this;
235 if (!this.config.srcPath) {
236 return next(new Error('srcPath is required'));
237 }
238 log = this.log;
239 tasks = new util.Group(function(err) {
240 log('debug', 'Checked configuration');
241 return next(err);
242 });
243 tasks.total = 6;
244 log('debug', 'Checking configuration');
245 (_base1 = this.config).outPath || (_base1.outPath = this.config.srcPath);
246 this.config.srcPath = path.resolve(this.config.srcPath);
247 tasks.complete(null);
248 this.config.outPath = path.resolve(this.config.outPath);
249 tasks.complete(null);
250 if (this.config.bundleScriptPath) {
251 this.config.bundleScriptPath = path.resolve(this.config.bundleScriptPath);
252 tasks.complete(null);
253 } else {
254 tasks.complete(false);
255 }
256 if (this.config.bundleStylePath) {
257 this.config.bundleStylePaths = path.resolve(this.config.bundleStylePath);
258 tasks.complete(null);
259 } else {
260 tasks.complete(false);
261 }
262 if (this.config.srcLoaderPath) {
263 this.config.srcLoaderPath = path.resolve(this.config.srcLoaderPath);
264 tasks.complete(null);
265 } else {
266 tasks.complete(false);
267 }
268 if (this.config.srcPath === this.config.outPath) {
269 this.config.deleteBundledFiles = false;
270 if (this.config.compressScripts) {
271 this.config.compressScripts = this.config.bundleScriptPath ? [this.config.bundleScriptPath] : false;
272 }
273 if (this.config.compressStyles) {
274 this.config.compressStyles = this.config.bundleStylePath ? [this.config.bundleStylePath] : false;
275 }
276 if (this.config.compressImages) {
277 this.config.compressImages = false;
278 }
279 }
280 if (this.config.bundleScripts === true) {
281 this.config.bundleScripts = false;
282 }
283 if (this.config.bundleStyles === true) {
284 this.config.bundleStyles = false;
285 }
286 return tasks.complete(false);
287 };
288
289 Buildr.prototype.checkFiles = function(next, config) {
290 var log,
291 _this = this;
292 log = this.log;
293 config || (config = this.config);
294 if (!(config.checkScripts || config.checkStyles)) {
295 return next(false);
296 }
297 log('debug', 'Check files');
298 this.forFilesInDirectory(config.srcPath, function(fileFullPath, fileRelativePath, next) {
299 return _this.checkFile(fileFullPath, next);
300 }, function(err) {
301 if (err) {
302 return next(err);
303 }
304 log('debug', 'Checked files');
305 return next(err);
306 });
307 return true;
308 };
309
310 Buildr.prototype.cpSrcToOut = function(next, config) {
311 var log;
312 log = this.log;
313 config || (config = this.config);
314 if (config.outPath === config.srcPath) {
315 return next(false);
316 }
317 log('debug', "Copying " + config.srcPath + " to " + config.outPath);
318 util.rmdir(config.outPath, function(err) {
319 if (err) {
320 return next(err);
321 }
322 return fs.mkdir(config.outPath, function(mkdirError) {
323 if (mkdirError) {
324 return next(mkdirError);
325 }
326 return fs.readdir(config.srcPath, function(err, files) {
327 var copyableFiles, statTasks;
328 if (err) {
329 return next(err);
330 }
331 copyableFiles = [];
332 statTasks = new util.Group(function(groupError) {
333 var copyTasks;
334 copyTasks = new util.Group(function(groupError) {
335 log('debug', "Copied " + config.srcPath + " to " + config.outPath);
336 return next(err);
337 });
338 copyTasks.total = copyableFiles.length;
339 return copyableFiles.forEach(function(file) {
340 return fs.readFile(config.srcPath + '/' + file, 'utf8', function(err, data) {
341 return fs.writeFile(config.outPath + '/' + file, data, 'utf8', copyTasks.completer());
342 });
343 });
344 });
345 statTasks.total = files.length;
346 return files.forEach(function(file) {
347 return fs.stat(config.srcPath + '/' + file, function(error, stat) {
348 if (stat.isFile()) {
349 copyableFiles.push(file);
350 }
351 return statTasks.completer()();
352 });
353 });
354 });
355 });
356 });
357 return true;
358 };
359
360 Buildr.prototype.generateFiles = function(next) {
361 var log, tasks;
362 log = this.log;
363 tasks = new util.Group(function(err) {
364 log('debug', 'Generated files');
365 return next(err);
366 });
367 tasks.total += 3;
368 log('debug', 'Generating files');
369 this.generateSrcLoaderFile(tasks.completer());
370 this.generateBundledScriptFile(tasks.completer());
371 this.generateBundledStyleFile(tasks.completer());
372 return true;
373 };
374
375 Buildr.prototype.generateSrcLoaderFile = function(next, config) {
376 var loadedInTemplates, log, srcLoaderData, srcLoaderPath, templateTasks, templates,
377 _this = this;
378 config || (config = this.config);
379 if (!config.srcLoaderPath) {
380 return next(false);
381 }
382 log = this.log;
383 log('debug', "Generating " + config.srcLoaderPath);
384 templates = {};
385 srcLoaderData = '';
386 srcLoaderPath = config.srcLoaderPath;
387 loadedInTemplates = null;
388 templateTasks = new util.Group(function(err) {
389 var script, style, _i, _j, _len, _len1, _ref, _ref1;
390 if (err) {
391 next(err);
392 }
393 srcLoaderData += "scripts = [\n";
394 _ref = config.scriptsOrder;
395 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
396 script = _ref[_i];
397 srcLoaderData += "\t'" + script + "'\n";
398 }
399 srcLoaderData += "\]\n\n";
400 srcLoaderData += "styles = [\n";
401 _ref1 = config.stylesOrder;
402 for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
403 style = _ref1[_j];
404 srcLoaderData += "\t'" + style + "'\n";
405 }
406 srcLoaderData += "\]\n\n";
407 srcLoaderData += templates.srcLoader + "\n\n" + templates.srcLoaderHeader;
408 return fs.writeFile(srcLoaderPath, srcLoaderData, function(err) {
409 if (err) {
410 return next(err);
411 }
412 srcLoaderData = coffee.compile(srcLoaderData);
413 return fs.writeFile(srcLoaderPath, srcLoaderData, function(err) {
414 if (err) {
415 return next(err);
416 }
417 log('debug', "Generated " + config.srcLoaderPath);
418 return next(false);
419 });
420 });
421 });
422 templateTasks.total = config.srcLoaderHeader ? 1 : 2;
423 fs.readFile(__dirname + '/templates/srcLoader.coffee', function(err, data) {
424 if (err) {
425 return templateTasks.exit(err);
426 }
427 templates.srcLoader = data.toString();
428 return templateTasks.complete(err);
429 });
430 if (config.srcLoaderHeader) {
431 templates.srcLoaderHeader = config.srcLoaderHeader;
432 } else {
433 fs.readFile(__dirname + '/templates/srcLoaderHeader.coffee', function(err, data) {
434 if (err) {
435 return templateTasks.exit(err);
436 }
437 templates.srcLoaderHeader = data.toString();
438 return templateTasks.complete(err);
439 });
440 }
441 return true;
442 };
443
444 Buildr.prototype.generateBundledStyleFile = function(next, config) {
445 var log, source,
446 _this = this;
447 log = this.log;
448 config || (config = this.config);
449 if (!config.bundleStylePath) {
450 return next(false);
451 }
452 log('debug', "Generating " + config.bundleStylePath);
453 source = '';
454 this.useOrScan(config.stylesOrder, this.config.outPath, function(fileFullPath, fileRelativePath, next) {
455 var bundledRelativePath, extension, _fileFullPath, _fileRelativePath;
456 extension = path.extname(fileRelativePath);
457 switch (extension) {
458 case '.css':
459 _fileRelativePath = fileRelativePath;
460 _fileFullPath = fileFullPath;
461 fileRelativePath = _fileRelativePath.substring(0, _fileRelativePath.length - extension.length) + '.less';
462 fileFullPath = _fileFullPath.substring(0, _fileFullPath.length - extension.length) + '.less';
463 if (config.deleteBundledFiles) {
464 _this.filesToClean.push(_fileFullPath);
465 }
466 _this.filesToClean.push(fileFullPath);
467 bundledRelativePath = path.relative(path.dirname(path.resolve(config.bundleStylePath)), fileFullPath);
468 return fs.exists(fileFullPath, function(exists) {
469 if (exists) {
470 source += "@import \"" + bundledRelativePath + "\";\n";
471 return next(false);
472 } else {
473 return fs.readFile(_fileFullPath, function(err, data) {
474 data = data.toString().replace(/filter: ([^~"])(.*)$/gm, "filter: ~\"$1$2\"");
475 return fs.writeFile(fileFullPath, data, function(err) {
476 if (err) {
477 return next(err);
478 }
479 source += "@import \"" + bundledRelativePath + "\";\n";
480 return next(false);
481 });
482 });
483 }
484 });
485 case '.less':
486 if (config.deleteBundledFiles) {
487 _this.filesToClean.push(fileFullPath);
488 }
489 bundledRelativePath = path.relative(path.dirname(path.resolve(config.bundleStylePath)), fileFullPath);
490 source += "@import \"" + bundledRelativePath + "\";\n";
491 return next(false);
492 default:
493 return next(false);
494 }
495 }, function(err) {
496 if (err) {
497 return next(err);
498 }
499 log('debug', "Compiling " + config.bundleStylePath);
500 return _this.compileStyleData(config.bundleStylePath, source, function(err, result) {
501 if (err) {
502 return next(err);
503 }
504 return fs.writeFile(config.bundleStylePath, result, function(err) {
505 log('debug', "Generated " + config.bundleStylePath);
506 return next(err, result);
507 });
508 });
509 });
510 return true;
511 };
512
513 Buildr.prototype.generateBundledScriptFile = function(next, config) {
514 var log, results,
515 _this = this;
516 log = this.log;
517 config || (config = this.config);
518 if (!config.bundleScriptPath) {
519 return next(false);
520 }
521 log('debug', "Generating " + config.bundleScriptPath);
522 results = {};
523 this.useOrScan(config.scriptsOrder, config.outPath, function(fileFullPath, fileRelativePath, next) {
524 var extension;
525 extension = path.extname(fileRelativePath);
526 switch (extension) {
527 case '.js':
528 case '.coffee':
529 return _this.compileScriptFile(fileFullPath, function(err, result) {
530 if (err) {
531 return next(err);
532 }
533 results[fileRelativePath] = result;
534 if (config.deleteBundledFiles) {
535 _this.filesToClean.push(fileFullPath);
536 }
537 return next(err);
538 }, false);
539 default:
540 return next(false);
541 }
542 }, function(err) {
543 var fileRelativePath, result, _i, _len, _ref;
544 if (err) {
545 return next(err);
546 }
547 result = '';
548 if (config.scriptsOrder.has != null) {
549 _ref = config.scriptsOrder;
550 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
551 fileRelativePath = _ref[_i];
552 if (results[fileRelativePath] == null) {
553 return next(new Error("The file " + fileRelativePath + " failed to compile"));
554 }
555 result += results[fileRelativePath];
556 }
557 }
558 return fs.writeFile(config.bundleScriptPath, result, function(err) {
559 log('debug', "Generated " + config.bundleScriptPath);
560 return next(err);
561 });
562 });
563 return true;
564 };
565
566 Buildr.prototype.cleanOutPath = function(next) {
567 var fileFullPath, log, tasks;
568 if (!(this.filesToClean || []).length) {
569 return next(false);
570 }
571 log = this.log;
572 tasks = new util.Group(function(err) {
573 log('debug', 'Cleaned outPath');
574 return next(err);
575 });
576 tasks.total += this.filesToClean.length;
577 log('debug', 'Cleaning outPath');
578 while (this.filesToClean.length > 0) {
579 fileFullPath = this.filesToClean.shift();
580 log('debug', "Cleaning " + fileFullPath);
581 fs.unlink(fileFullPath, tasks.completer());
582 }
583 return true;
584 };
585
586 Buildr.prototype.compressFiles = function(next, config) {
587 var log, tasks,
588 _this = this;
589 config || (config = this.config);
590 if (!(config.compressScripts || config.compressStyles || config.compressImages)) {
591 return next(false);
592 }
593 log = this.log;
594 tasks = new util.Group(function(err) {
595 log('debug', 'Compressed files');
596 return next(err);
597 });
598 tasks.total += 1;
599 log('debug', 'Compressing files');
600 if (config.compressScripts === true) {
601 if (config.bundleScriptPath) {
602 ++tasks.total;
603 this.compressFile(config.bundleScriptPath, tasks.completer());
604 }
605 if (config.bundleStylePath) {
606 ++tasks.total;
607 this.compressFile(config.bundleStylePath, tasks.completer());
608 }
609 }
610 this.useOrScan(config.compressScripts, config.outPath, function(fileFullPath, fileRelativePath, next) {
611 return _this.compressFile(fileFullPath, next);
612 }, tasks.completer());
613 return true;
614 };
615
616 Buildr.prototype.forFilesInArray = function(files, parentPath, callback, next) {
617 var fileRelativePath, log, tasks, _i, _len,
618 _this = this;
619 if (!(files || []).length) {
620 return next(false);
621 }
622 log = this.log;
623 tasks = new util.Group(function(err) {
624 return next(err);
625 });
626 tasks.total += files.length;
627 for (_i = 0, _len = files.length; _i < _len; _i++) {
628 fileRelativePath = files[_i];
629 callback(path.resolve(parentPath, fileRelativePath), fileRelativePath, tasks.completer());
630 }
631 return true;
632 };
633
634 Buildr.prototype.forFilesInDirectory = function(parentPath, callback, next) {
635 util.scandir(parentPath, callback, false, next);
636 return true;
637 };
638
639 Buildr.prototype.useOrScan = function(files, parentPath, callback, next) {
640 if (files === true) {
641 this.forFilesInDirectory(parentPath, callback, next);
642 } else if (files && files.length) {
643 this.forFilesInArray(files, parentPath, callback, next);
644 } else {
645 next(false);
646 }
647 return true;
648 };
649
650 Buildr.prototype.compileFile = function(fileFullPath, next) {
651 var extension;
652 extension = path.extname(fileFullPath);
653 switch (extension) {
654 case '.coffee':
655 this.compileScriptFile(fileFullPath, next);
656 break;
657 case '.less':
658 this.compileStyleFile(fileFullPath, next);
659 break;
660 default:
661 next(false);
662 }
663 return true;
664 };
665
666 Buildr.prototype.compressFile = function(fileFullPath, next, config) {
667 var extension;
668 config || (config = this.config);
669 extension = path.extname(fileFullPath);
670 switch (extension) {
671 case '.js':
672 if (config.compressScripts === true || (config.compressScripts.has != null) && config.compressScripts.has(fileFullPath)) {
673 this.compressScriptFile(fileFullPath, next);
674 } else {
675 next(false);
676 }
677 break;
678 case '.css':
679 if (config.compressStyles === true || (config.compressStyles.has != null) && config.compressStyles.has(fileFullPath)) {
680 this.compressStyleFile(fileFullPath, next);
681 } else {
682 next(false);
683 }
684 break;
685 case '.gif':
686 case '.jpg':
687 case '.jpeg':
688 case '.png':
689 case '.tiff':
690 case '.bmp':
691 if (config.compressImages === true || (config.compressImages.has != null) && config.compressImages.has(fileFullPath)) {
692 this.compressImageFile(fileFullPath, next);
693 } else {
694 next(false);
695 }
696 break;
697 default:
698 next(false);
699 }
700 return true;
701 };
702
703 Buildr.prototype.checkFile = function(fileFullPath, next, config) {
704 var extension;
705 config || (config = this.config);
706 extension = path.extname(fileFullPath);
707 switch (extension) {
708 case '.js':
709 if (config.checkScripts === true || (config.checkScripts.has != null) && config.checkScripts.has(fileFullPath)) {
710 this.checkScriptFile(fileFullPath, next);
711 } else {
712 next(false);
713 }
714 break;
715 case '.css':
716 if (config.checkStyles === true || (config.checkStyles.has != null) && config.checkStyles.has(fileFullPath)) {
717 this.checkStyleFile(fileFullPath, next);
718 } else {
719 next(false);
720 }
721 break;
722 default:
723 next(false);
724 }
725 return true;
726 };
727
728 Buildr.prototype.compressImageFile = function(fileFullPath, next) {
729 var log;
730 log = this.log;
731 log('debug', "Compressing " + fileFullPath);
732 try {
733 pulverizr.compress(fileFullPath, {
734 quiet: true
735 });
736 log('debug', "Compressed " + fileFullPath);
737 next(false);
738 } catch (err) {
739 next(err);
740 }
741 return true;
742 };
743
744 Buildr.prototype.compileStyleData = function(fileFullPath, src, next) {
745 var log, options, result;
746 log = this.log;
747 result = '';
748 options = {
749 paths: [path.dirname(fileFullPath)],
750 optimization: 1,
751 filename: fileFullPath
752 };
753 new less.Parser(options).parse(src, function(err, tree) {
754 if (err) {
755 log('debug', err);
756 return next(new Error('Less compilation failed'), result);
757 } else {
758 try {
759 result = tree.toCSS({
760 compress: 0
761 });
762 return next(false, result);
763 } catch (err) {
764 return next(err, result);
765 }
766 }
767 });
768 return true;
769 };
770
771 Buildr.prototype.compileStyleFile = function(fileFullPath, next, write) {
772 var log,
773 _this = this;
774 if (write == null) {
775 write = true;
776 }
777 log = this.log;
778 fs.readFile(fileFullPath, function(err, data) {
779 if (err) {
780 return next(err);
781 }
782 return _this.compileStyleData(fileFullPath, data.toString(), function(err, result) {
783 if (err || !write) {
784 return next(err, result);
785 }
786 return fs.writeFile(fileFullPath, result, function(err) {
787 if (err) {
788 return next(err);
789 }
790 return next(err, result);
791 });
792 });
793 });
794 return true;
795 };
796
797 Buildr.prototype.compressStyleData = function(fileFullPath, src, next) {
798 var log, options, result;
799 log = this.log;
800 result = '';
801 options = {
802 paths: [path.dirname(fileFullPath)],
803 optimization: 1,
804 filename: fileFullPath
805 };
806 new less.Parser(options).parse(src, function(err, tree) {
807 if (err) {
808 log('debug', err);
809 return next(new Error('Less compilation failed'), result);
810 } else {
811 try {
812 result = tree.toCSS({
813 compress: 1
814 });
815 return next(false, result);
816 } catch (err) {
817 return next(err, result);
818 }
819 }
820 });
821 return true;
822 };
823
824 Buildr.prototype.compressStyleFile = function(fileFullPath, next, write) {
825 var log,
826 _this = this;
827 if (write == null) {
828 write = true;
829 }
830 log = this.log;
831 log('debug', "Compressing " + fileFullPath);
832 fs.readFile(fileFullPath, function(err, data) {
833 if (err) {
834 return next(err);
835 }
836 return _this.compressStyleData(fileFullPath, data.toString(), function(err, result) {
837 if (err || !write) {
838 return next(err, result);
839 }
840 return fs.writeFile(fileFullPath, result, function(err) {
841 if (err) {
842 return next(err);
843 }
844 log('debug', "Compressed " + fileFullPath);
845 return next(err, result);
846 });
847 });
848 });
849 return true;
850 };
851
852 Buildr.prototype.checkStyleData = function(fileFullPath, src, next, config) {
853 var errord, formatId, log, message, result, _i, _len, _ref;
854 log = this.log;
855 config || (config = this.config);
856 errord = false;
857 result = csslint.verify(src, config.csslintOptions || {});
858 formatId = 'text';
859 if (!result.messages.length) {
860 return next(false, false);
861 }
862 _ref = result.messages;
863 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
864 message = _ref[_i];
865 if (!(message && message.type === 'error')) {
866 continue;
867 }
868 errord = true;
869 }
870 if (errord) {
871 log('error', csslint.getFormatter(formatId).formatResults(result, fileFullPath, formatId));
872 }
873 return next(false, errord);
874 };
875
876 Buildr.prototype.checkStyleFile = function(fileFullPath, next) {
877 var log,
878 _this = this;
879 log = this.log;
880 log('debug', "Checking " + fileFullPath);
881 fs.readFile(fileFullPath, function(err, data) {
882 if (err) {
883 return next(err, false);
884 }
885 return _this.checkStyleData(fileFullPath, data.toString(), function(err, errord) {
886 if (err) {
887 return next(err);
888 }
889 log('debug', "Checked " + fileFullPath);
890 return next(err, errord);
891 });
892 });
893 return true;
894 };
895
896 Buildr.prototype.compileScriptData = function(extension, src, next) {
897 var result;
898 result = false;
899 try {
900 switch (extension) {
901 case '.coffee':
902 result = coffee.compile(src);
903 break;
904 case '.js':
905 result = src;
906 break;
907 default:
908 throw new Error('Unknown script type: ' + extension);
909 }
910 } catch (err) {
911 next(err);
912 }
913 return next(false, result);
914 };
915
916 Buildr.prototype.compileScriptFile = function(fileFullPath, next, write) {
917 var log,
918 _this = this;
919 if (write == null) {
920 write = true;
921 }
922 log = this.log;
923 fs.readFile(fileFullPath, function(err, data) {
924 if (err) {
925 return next(err);
926 }
927 return _this.compileScriptData(path.extname(fileFullPath), data.toString(), function(err, result) {
928 if (err || !write) {
929 return next(err, result);
930 }
931 return fs.writeFile(fileFullPath, result, function(err) {
932 if (err) {
933 return next(err);
934 }
935 return next(err, result);
936 });
937 });
938 });
939 return true;
940 };
941
942 Buildr.prototype.compressScriptData = function(src, next) {
943 var ast, out;
944 ast = jsp.parse(src);
945 ast = pro.ast_mangle(ast);
946 ast = pro.ast_squeeze(ast);
947 out = pro.gen_code(ast);
948 return next(false, out);
949 };
950
951 Buildr.prototype.compressScriptFile = function(fileFullPath, next, write) {
952 var log,
953 _this = this;
954 if (write == null) {
955 write = true;
956 }
957 log = this.log;
958 log('debug', "Compressing " + fileFullPath);
959 fs.readFile(fileFullPath, function(err, data) {
960 if (err) {
961 return next(err);
962 }
963 return _this.compressScriptData(data.toString(), function(err, result) {
964 if (err || !write) {
965 return next(err, result);
966 }
967 return fs.writeFile(fileFullPath, result, function(err) {
968 if (err) {
969 return next(err);
970 }
971 log('debug', "Compressed " + fileFullPath);
972 return next(err, result);
973 });
974 });
975 });
976 return true;
977 };
978
979 Buildr.prototype.checkScriptData = function(fileFullPath, src, next, config) {
980 var error, errord, evidence, log, message, result, _i, _len, _ref;
981 log = this.log;
982 config || (config = this.config);
983 errord = false;
984 jshint(src, config.jshintOptions || {});
985 result = jshint.data();
986 result.errors || (result.errors = []);
987 if (!result.errors.length) {
988 return next(false, false);
989 }
990 log('error', "\n" + fileFullPath + ":");
991 _ref = result.errors;
992 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
993 error = _ref[_i];
994 if (!(error && error.raw)) {
995 continue;
996 }
997 errord = true;
998 message = error.raw.replace(/\.$/, '').replace(/\{([a-z])\}/, function(a, b) {
999 return error[b] || a;
1000 });
1001 evidence = error.evidence ? "\n\t" + error.evidence.replace(/^\s+/, '') : '';
1002 log('warn', "\tLine " + error.line + ": " + message + " " + evidence + "\n");
1003 }
1004 return next(false, errord);
1005 };
1006
1007 Buildr.prototype.checkScriptFile = function(fileFullPath, next) {
1008 var log,
1009 _this = this;
1010 log = this.log;
1011 log('debug', "Checking " + fileFullPath);
1012 fs.readFile(fileFullPath, function(err, data) {
1013 if (err) {
1014 return next(err, false);
1015 }
1016 return _this.checkScriptData(fileFullPath, data.toString(), function(err, errord) {
1017 if (err) {
1018 return next(err);
1019 }
1020 log('debug', "Checked " + fileFullPath);
1021 return next(err, errord);
1022 });
1023 });
1024 return true;
1025 };
1026
1027 return Buildr;
1028
1029 })();
1030
1031 module.exports = {
1032 createInstance: function(options) {
1033 return new Buildr(options);
1034 }
1035 };
1036
1037}).call(this);