Initial commit
[yaffs-website] / node_modules / grunt-contrib-sass / tasks / sass.js
1 'use strict';
2 var path = require('path');
3 var os = require('os');
4 var dargs = require('dargs');
5 var async = require('async');
6 var chalk = require('chalk');
7 var spawn = require('cross-spawn');
8 var which = require('which');
9 var checkFilesSyntax = require('./lib/check');
10 var concurrencyCount = (os.cpus().length || 1) * 4;
11
12 module.exports = function (grunt) {
13   var checkBinary = function (cmd, errMsg) {
14     try {
15       which.sync(cmd);
16     } catch (err) {
17       return grunt.warn(
18         '\n' + errMsg + '\n' +
19         'More info: https://github.com/gruntjs/grunt-contrib-sass\n'
20       );
21     }
22   };
23
24   grunt.registerMultiTask('sass', 'Compile Sass to CSS', function () {
25     var cb = this.async();
26     var options = this.options();
27
28     if (options.bundleExec) {
29       checkBinary('bundle',
30         'bundleExec options set but no Bundler executable found in your PATH.'
31       );
32     } else {
33       checkBinary('sass',
34         'You need to have Ruby and Sass installed and in your PATH for this task to work.'
35       );
36     }
37
38     if (options.check) {
39       options.concurrencyCount = concurrencyCount;
40       checkFilesSyntax(this.filesSrc, options, cb);
41       return;
42     }
43
44     var passedArgs = dargs(options, {
45       excludes: ['bundleExec'],
46       ignoreFalse: true
47     });
48
49     async.eachLimit(this.files, concurrencyCount, function (file, next) {
50       var src = file.src[0];
51
52       if (path.basename(src)[0] === '_') {
53         return next();
54       }
55
56       var args = [
57         src,
58         file.dest
59       ].concat(passedArgs);
60
61       if (options.update) {
62         // When the source file hasn't yet been compiled SASS will write an empty file.
63         // If this is the first time the file has been written we treat it as if `update` was not passed
64         if (!grunt.file.exists(file.dest)) {
65           // Find where the --update flag is and remove it
66           args.splice(args.indexOf('--update'), 1);
67         } else {
68           // The first two elements in args are the source and destination files,
69           // which are used to build a path that SASS recognizes, i.e. "source:destination"
70           args.push(args.shift() + ':' + args.shift());
71         }
72       }
73
74       var bin = 'sass';
75
76       if (options.bundleExec) {
77         bin = 'bundle';
78         args.unshift('exec', 'sass');
79       }
80
81       // If we're compiling scss or css files
82       if (path.extname(src) === '.css') {
83         args.push('--scss');
84       }
85
86       // Make sure grunt creates the destination folders if they don't exist
87       if (!grunt.file.exists(file.dest)) {
88         grunt.file.write(file.dest, '');
89       }
90
91       grunt.verbose.writeln('Command: ' + bin + ' ' + args.join(' '));
92
93       var cp = spawn(bin, args, {stdio: 'inherit'});
94
95       cp.on('error', grunt.warn);
96
97       cp.on('close', function (code) {
98         if (code > 0) {
99           grunt.warn('Exited with error code ' + code);
100           next();
101           return;
102         }
103
104         grunt.verbose.writeln('File ' + chalk.cyan(file.dest) + ' created');
105         next();
106       });
107     }, cb);
108   });
109 };