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);
|