sass.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. * grunt-contrib-sass
  3. * http://gruntjs.com/
  4. *
  5. * Copyright (c) 2013 Sindre Sorhus, contributors
  6. * Licensed under the MIT license.
  7. */
  8. 'use strict';
  9. var path = require('path');
  10. var dargs = require('dargs');
  11. var numCPUs = require('os').cpus().length;
  12. var async = require('async');
  13. var chalk = require('chalk');
  14. var spawn = require('win-spawn');
  15. var which = require('which');
  16. module.exports = function (grunt) {
  17. var bannerCallback = function (filename, banner) {
  18. var content;
  19. grunt.log.verbose.writeln('Writing CSS banner for ' + filename);
  20. content = grunt.file.read(filename);
  21. grunt.file.write(filename, banner + grunt.util.linefeed + content);
  22. };
  23. grunt.registerMultiTask('sass', 'Compile Sass to CSS', function () {
  24. var cb = this.async();
  25. var options = this.options();
  26. var passedArgs;
  27. var bundleExec;
  28. var banner;
  29. try {
  30. which.sync('sass');
  31. } catch (err) {
  32. return grunt.warn(
  33. '\nYou need to have Ruby and Sass installed and in your PATH for this task to work.\n' +
  34. 'More info: https://github.com/gruntjs/grunt-contrib-sass\n'
  35. );
  36. }
  37. // Unset banner option if set
  38. if (options.banner) {
  39. banner = options.banner;
  40. delete options.banner;
  41. }
  42. passedArgs = dargs(options, ['bundleExec']);
  43. bundleExec = options.bundleExec;
  44. async.eachLimit(this.files, numCPUs, function (file, next) {
  45. var src = file.src[0];
  46. if (typeof src !== 'string') {
  47. src = file.orig.src[0];
  48. }
  49. if (!grunt.file.exists(src)) {
  50. grunt.log.warn('Source file "' + src + '" not found.');
  51. return next();
  52. }
  53. if (path.basename(src)[0] === '_') {
  54. return next();
  55. }
  56. var args = [
  57. src,
  58. file.dest,
  59. '--load-path', path.dirname(src)
  60. ].concat(passedArgs);
  61. var bin = 'sass';
  62. if (bundleExec) {
  63. bin = 'bundle';
  64. args.unshift('exec', 'sass');
  65. }
  66. // If we're compiling scss or css files
  67. if (path.extname(src) === '.css') {
  68. args.push('--scss');
  69. }
  70. // Make sure grunt creates the destination folders if they don't exist
  71. if(!grunt.file.exists(file.dest)) {
  72. grunt.file.write(file.dest, '');
  73. }
  74. var cp = spawn(bin, args, {stdio: 'inherit'});
  75. cp.on('error', function (err) {
  76. grunt.warn(err);
  77. });
  78. cp.on('close', function (code) {
  79. if (code > 0) {
  80. return grunt.warn('Exited with error code ' + code);
  81. }
  82. // Callback to insert banner
  83. if (banner) {
  84. bannerCallback(file.dest, banner);
  85. }
  86. grunt.log.writeln('File ' + chalk.cyan(file.dest) + ' created.');
  87. next();
  88. });
  89. }, cb);
  90. });
  91. };