Skip to content

Commit

Permalink
Create Sass task
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed Sep 22, 2012
1 parent 71bfab9 commit 38320df
Show file tree
Hide file tree
Showing 11 changed files with 309 additions and 20 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
npm-debug.log
tmp
.sass-cache
164 changes: 162 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
# grunt-contrib-sass (not released)
> Your description here (part of the [grunt-contrib](https://github.com/gruntjs/grunt-contrib) collection). Submitted by [Sindre Sorhus](/sindresorhus).

> Compile Sass to CSS (part of the [grunt-contrib](https://github.com/gruntjs/grunt-contrib) collection). Submitted by [Sindre Sorhus](http://sindresorhus.com).

## Getting Started

This task requires you to have Ruby and Sass installed `gem install sass`

Install this grunt plugin next to your project's [grunt.js gruntfile][getting_started] with: `npm install grunt-contrib-sass`

Then add this line to your project's `grunt.js` gruntfile:
Expand All @@ -13,7 +18,162 @@ grunt.loadNpmTasks('grunt-contrib-sass');
[grunt]: https://github.com/cowboy/grunt
[getting_started]: https://github.com/cowboy/grunt/blob/master/docs/getting_started.md

### Overview

## Documentation


### Example config

```javascript
grunt.initConfig({
sass: { // Task
dist: { // Target
files: { // Dictionary of files
'main.css': 'main.scss', // 'destination': 'source'
'widgets.css': 'widgets.scss'
}
},
dev: { // Another target
options: { // Target options
style: 'expanded'
},
files: {
'main.css': 'main.scss',
'widgets.css': [
'button.scss',
'tab.scss',
'debug.scss' // Maybe you need one extra file in dev
]
}
}
}
});

grunt.loadNpmTasks('grunt-contrib-sass');

grunt.registerTask('default', 'lint sass');
```


### Example usage


#### Compile

```javascript
grunt.initConfig({
sass: {
files: {
'main.css': 'main.scss'
}
}
});
```


#### Concat and compile

If you specify an array of `src` paths they will be concatenated. However, in most cases you would want to just `@import` them into `main.scss`.

```javascript
grunt.initConfig({
sass: {
files: {
'main.css': [
'reset.scss',
'main.scss'
]
}
}
});
```


#### Compile multiple files

You can specify multiple `destination: source` items in `files`.

```javascript
grunt.initConfig({
sass: {
files: {
'main.css': 'main.scss',
'widgets.css': 'widgets.scss'
}
}
});
```


### Parameters

#### files ```object```

This defines what files this task will process and should contain key:value pairs.

The key (destination) should be an unique filepath (supports [grunt.template](https://github.com/cowboy/grunt/blob/master/docs/api_template.md)) and the value (source) should be a filepath or an array of filepaths (supports [minimatch](https://github.com/isaacs/minimatch)).

Note: When the value contains an array of multiple filepaths, the contents are concatenated in the order passed.

#### options ```object```

This controls how this task (and its helpers) operate and should contain key:value pairs, see options below.


### Options

#### trace ```boolean```

Show a full traceback on error.

#### unixNewlines ```boolean```

Force Unix newlines in written files.

#### check ```boolean```

Just check syntax, don't evaluate.

#### style ```string```

Output style. Can be `nested` (default), `compact`, `compressed`, or `expanded`.

#### precision ```number```

How many digits of precision to use when outputting decimal numbers. Defaults to 3.

#### quiet ```boolean```

Silence warnings and status messages during compilation.

#### compass ```boolean```

Make Compass imports available and load project configuration.

#### debugInfo ```boolean```

Emit extra information in the generated CSS that can be used by the FireSass Firebug plugin.

#### lineNumbers ```boolean```

Emit comments in the generated CSS indicating the corresponding source line.

#### loadPath ```string|array```

Add a (or multiple) Sass import path.

#### require ```string|array```

Require a (or multiple) Ruby library before running Sass.

#### cacheLocation ```string```

The path to put cached Sass files. Defaults to `.sass-cache`.

#### noCache ```boolean```

Don't cache to sassc files.



## Release History
Expand Down
20 changes: 16 additions & 4 deletions grunt.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
lint: {
all: ['grunt.js', 'tasks/*.js', '<config:nodeunit.tasks>']
all: [
'grunt.js',
'tasks/*.js',
'<config:nodeunit.tasks>'
]
},

jshint: {
Expand All @@ -35,14 +39,18 @@ module.exports = function(grunt) {

// Before generating any new files, remove any previously-created files.
clean: {
test: ['tmp']
test: [
'tmp',
'.sass-cache'
]
},

// Configuration to be run (and then tested).
sass: {
compile: {
files: {
'tmp/compile.css': ['test/fixtures/compile.sass']
'tmp/scss.css': ['test/fixtures/compile.scss'],
'tmp/sass.css': ['test/fixtures/compile.sass']
}
}
},
Expand All @@ -62,8 +70,12 @@ module.exports = function(grunt) {
// Whenever the "test" task is run, first clean the "tmp" dir, then run this
// plugin's task(s), then test the result.
grunt.renameTask('test', 'nodeunit');
grunt.registerTask('test', 'clean sass nodeunit');
grunt.registerTask('test', 'clean mkdir:tmp sass nodeunit clean');

// By default, lint and run all tests.
grunt.registerTask('default', 'lint test');

grunt.registerTask('mkdir', function(dir) {
require('fs').mkdirSync(dir);
});
};
14 changes: 10 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"name": "grunt-contrib-sass",
"description": "Your description here.",
"description": "Grunt task to compile Sass",
"version": "0.2.0",
"homepage": "https://github.com/gruntjs/grunt-contrib-sass",
"author": {
"name": "Sindre Sorhus",
"url": "http://github.com/sindresorhus"
"url": "http://sindresorhus.com"
},
"repository": {
"type": "git",
Expand All @@ -22,7 +22,7 @@
],
"main": "grunt.js",
"engines": {
"node": "*"
"node": ">=0.6.0"
},
"scripts": {
"test": "grunt test"
Expand All @@ -35,6 +35,12 @@
"grunt-contrib-clean": "~0.2.0"
},
"keywords": [
"gruntplugin"
"gruntplugin",
"scss",
"sass",
"css",
"compile",
"preprocessor",
"style"
]
}
66 changes: 61 additions & 5 deletions tasks/sass.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,76 @@ module.exports = function(grunt) {
// TODO: ditch this when grunt v0.4 is released
grunt.util = grunt.util || grunt.utils;

var path = require('path');
var _ = grunt.util._;
var helpers = require('grunt-contrib-lib').init(grunt);

grunt.registerMultiTask('sass', '', function() {
var async = grunt.util.async;

grunt.registerMultiTask('sass', 'Compile Sass', function() {
var helpers = require('grunt-contrib-lib').init(grunt);
var options = helpers.options(this, {namespace: 'JST'});
var options = helpers.options(this);
var cb = this.async();
var args = ['--stdin'];

grunt.verbose.writeflags(options, 'Options');

// TODO: ditch this when grunt v0.4 is released
this.files = this.files || helpers.normalizeMultiTaskFiles(this.data, this.target);

// Options -> CLI parameters
Object.keys(options).forEach(function(el) {
var val = '' + options[ el ];

});
el = el.replace(/[A-Z]/g, function(match) {
return '-' + match.toLowerCase();
});

if (val === true) {
args.push('--' + el);
}

if (_.isString(val)) {
args.push('--' + el, val);
}

if (_.isNumber(val)) {
args.push('--' + el, '' + val);
}

if (_.isArray(val)) {
val.forEach(function(arrVal) {
args.push('--' + el, arrVal);
});
}
});

async.forEachSeries(this.files, function(el, cb2) {
var elArgs = [el.dest];
var src = el.src;
var files = grunt.file.expandFiles(src);
var max = grunt.helper('concat', files);

if (path.extname(src) === '.scss') {
elArgs.push('--scss');
}

// Add dirs of specified files to the sass path
files.forEach(function(el) {
elArgs.push('--load-path', path.dirname(el));
});

var sass = grunt.util.spawn({
cmd: 'sass',
args: elArgs.concat(args)
}, function(error, result, code) {
cb2(code > 0);
});

sass.stdin.write(new Buffer(max));
sass.stdin.end();
sass.stdout.pipe(process.stdout);
sass.stderr.pipe(process.stderr);
}, function(error) {
cb(!error);
});
});
};
14 changes: 13 additions & 1 deletion test/expected/compile.css
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
body{}
li {
font-family: serif;
font-weight: bold;
font-size: 1.2em; }

.content-navigation {
border-color: #3bbfce;
color: #2ca2af; }

.border {
padding: 8px;
margin: 8px;
border-color: #3bbfce; }
14 changes: 13 additions & 1 deletion test/fixtures/compile.sass
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
body{}
@import 'imported'

$blue: #3bbfce
$margin: 16px

.content-navigation
border-color: $blue
color: darken($blue, 9%)

.border
padding: $margin / 2
margin: $margin / 2
border-color: $blue
16 changes: 16 additions & 0 deletions test/fixtures/compile.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
@import 'imported';

$blue: #3bbfce;
$margin: 16px;

.content-navigation {
border-color: $blue;
color:
darken($blue, 9%);
}

.border {
padding: $margin / 2;
margin: $margin / 2;
border-color: $blue;
}
Loading

0 comments on commit 38320df

Please sign in to comment.