Skip to content

Commit 5a229e0

Browse files
committed
Initial commit
0 parents  commit 5a229e0

14 files changed

+348
-0
lines changed

.editorconfig

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
; http://EditorConfig.org
2+
3+
root = true
4+
5+
[*]
6+
indent_style = space
7+
indent_size = 4
8+
end_of_line = lf
9+
charset = utf-8
10+
trim_trailing_whitespace = true
11+
insert_final_newline = true
12+
13+
[*.map]
14+
insert_final_newline = false

.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.DS_Store
2+
.idea
3+
.sass-cache
4+
node_modules
5+
npm-debug.log
6+
tmp

.jshintrc

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"curly": true,
3+
"eqeqeq": true,
4+
"expr": true,
5+
"immed": true,
6+
"latedef": true,
7+
"newcap": true,
8+
"noarg": true,
9+
"sub": true,
10+
"undef": true,
11+
"boss": true,
12+
"eqnull": true,
13+
"node": true
14+
}

.travis.yml

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
language: node_js
2+
node_js:
3+
- "0.10"
4+
before_script:
5+
- npm install -g grunt-cli

CHANGELOG

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
v0.1.0:
2+
data: 2014-09-25
3+
changes:
4+
- First release

Gruntfile.js

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
module.exports = function(grunt) {
2+
3+
'use strict';
4+
5+
require('load-grunt-tasks')(grunt);
6+
require('time-grunt')(grunt);
7+
8+
grunt.initConfig({
9+
jshint: {
10+
all: [
11+
'Gruntfile.js',
12+
'tasks/*.js',
13+
'<%= nodeunit.tests %>',
14+
],
15+
options: {
16+
jshintrc: '.jshintrc',
17+
},
18+
},
19+
20+
clean: {
21+
tests: ['tmp'],
22+
},
23+
24+
postcss: {
25+
dist: {
26+
options: {
27+
map: true,
28+
processors: [require('csswring').postcss]
29+
},
30+
src: 'test/fixtures/a.css',
31+
dest: 'tmp/a.css'
32+
},
33+
},
34+
35+
nodeunit: {
36+
tests: ['test/test.js'],
37+
},
38+
39+
});
40+
41+
grunt.loadTasks('tasks');
42+
43+
grunt.registerTask('test', ['clean', 'postcss', 'nodeunit']);
44+
grunt.registerTask('default', ['jshint', 'test']);
45+
46+
};

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) Dmitry Nikitenko <[email protected]>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.md

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# grunt-postcss
2+
[![Build Status](https://travis-ci.org/nDmitry/grunt-postcss.png?branch=master)](https://travis-ci.org/nDmitry/grunt-postcss)
3+
[![Dependency Status](https://david-dm.org/nDmitry/grunt-postcss.png)](https://david-dm.org/nDmitry/grunt-postcss)
4+
5+
> Apply several post-processors to your CSS using [PostCSS](https://github.com/postcss/postcss).
6+
7+
## Getting Started
8+
This plugin requires Grunt `~0.4.0`
9+
10+
If you haven't used [Grunt](http://gruntjs.com/) before, be sure to check out the [Getting Started](http://gruntjs.com/getting-started) guide, as it explains how to create a [Gruntfile](http://gruntjs.com/sample-gruntfile) as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:
11+
12+
```shell
13+
npm install grunt-postcss --save-dev
14+
```
15+
16+
Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:
17+
18+
```js
19+
grunt.loadNpmTasks('grunt-postcss');
20+
```
21+
22+
## Usage
23+
24+
```js
25+
grunt.initConfig({
26+
postcss: {
27+
options: {
28+
map: true,
29+
processors: [
30+
require('autoprefixer-core')({browsers: 'last 1 version'}).postcss
31+
require('csswring').postcss
32+
]
33+
},
34+
dist: {
35+
src: 'css/*.css'
36+
},
37+
},
38+
});
39+
```
40+
41+
The usage and options are similar with [grunt-autoprefixer](https://github.com/nDmitry/grunt-autoprefixer#options). The only new options is:
42+
43+
#### options.processors
44+
Type: `Array`
45+
Default value: `[]`
46+
47+
An array of PostCSS compatible post-processors.
48+
49+
## Why would I use this?
50+
51+
Unlike the traditional approach with separate plugins, grunt-postcss allows you to parse and save CSS only once applying all post-processors in memory and thus reducing your build time. PostCSS is also a simple tool for writing your own CSS post-processors.

package.json

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"name": "grunt-postcss",
3+
"version": "0.1.0",
4+
"description": "Apply several post-processors to your CSS using PostCSS",
5+
"author": {
6+
"name": "Dmitry Nikitenko",
7+
"email": "[email protected]"
8+
},
9+
"repository": "nDmitry/grunt-postcss",
10+
"license": "MIT",
11+
"engines": {
12+
"node": ">= 0.10.0"
13+
},
14+
"scripts": {
15+
"test": "grunt test"
16+
},
17+
"keywords": [
18+
"gruntplugin",
19+
"css",
20+
"postprocessor",
21+
"postcss"
22+
],
23+
"files": [
24+
"tasks",
25+
"LICENSE"
26+
],
27+
"dependencies": {
28+
"chalk": "^0.5.1",
29+
"diff": "^1.0.8",
30+
"postcss": "^2.2.5"
31+
},
32+
"devDependencies": {
33+
"csswring": "^1.3.0",
34+
"grunt": "^0.4.5",
35+
"grunt-contrib-clean": "^0.6.0",
36+
"grunt-contrib-jshint": "^0.10.0",
37+
"grunt-contrib-nodeunit": "^0.4.0",
38+
"load-grunt-tasks": "^0.6.0",
39+
"time-grunt": "^1.0.0"
40+
},
41+
"peerDependencies": {
42+
"grunt": "^0.4.5"
43+
}
44+
}

tasks/postcss.js

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
'use strict';
2+
3+
var path = require('path');
4+
var postcss = require('postcss');
5+
var diff = require('diff');
6+
var chalk = require('chalk');
7+
8+
module.exports = function(grunt) {
9+
10+
var options;
11+
var processor = postcss();
12+
13+
/**
14+
* Returns an input map contents if a custom map path was specified
15+
* @param {string} from Input CSS path
16+
* @returns {?string}
17+
*/
18+
function getPrevMap(from) {
19+
if (typeof options.map.prev === 'string') {
20+
var mapPath = options.map.prev + path.basename(from) + '.map';
21+
22+
if (grunt.file.exists(mapPath)) {
23+
return grunt.file.read(mapPath);
24+
}
25+
}
26+
}
27+
28+
/**
29+
* @param {string} input Input CSS contents
30+
* @param {string} from Input CSS path
31+
* @param {string} to Output CSS path
32+
* @returns {{css: string, map: ?string}}
33+
*/
34+
function process(input, from, to) {
35+
return processor.process(input, {
36+
map: (typeof options.map === 'boolean') ? options.map : {
37+
prev: getPrevMap(from),
38+
inline: options.map.inline,
39+
annotation: options.map.annotation,
40+
sourcesContent: options.map.sourcesContent
41+
},
42+
from: from,
43+
to: to
44+
});
45+
}
46+
47+
/**
48+
* @param {string} msg Log message
49+
*/
50+
function log(msg) {
51+
if (!options.silent) {
52+
grunt.log.writeln(msg);
53+
}
54+
}
55+
56+
grunt.registerMultiTask('postcss', 'Process CSS files.', function() {
57+
options = this.options({
58+
diff: false,
59+
map: false,
60+
processors: [],
61+
silent: false
62+
});
63+
64+
options.processors.forEach(processor.use.bind(processor));
65+
66+
this.files.forEach(function(f) {
67+
if (!f.src.length) {
68+
return grunt.fail.warn('No source files were found.');
69+
}
70+
71+
f.src
72+
.forEach(function(filepath) {
73+
var dest = f.dest || filepath;
74+
var input = grunt.file.read(filepath);
75+
var output = process(input, filepath, dest);
76+
77+
grunt.file.write(dest, output.css);
78+
log('File ' + chalk.cyan(dest) + ' created.');
79+
80+
if (output.map) {
81+
grunt.file.write(dest + '.map', output.map.toString());
82+
log('File ' + chalk.cyan(dest + '.map') + ' created (source map).');
83+
}
84+
85+
if (options.diff) {
86+
var diffPath = (typeof options.diff === 'string') ? options.diff : dest + '.diff';
87+
88+
grunt.file.write(diffPath, diff.createPatch(dest, input, output.css));
89+
log('File ' + chalk.cyan(diffPath) + ' created (diff).');
90+
}
91+
});
92+
});
93+
});
94+
};

test/expected/a.css

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/expected/a.css.map

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/fixtures/a.css

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
a {
2+
color: blue;
3+
}

test/test.js

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
'use strict';
2+
3+
var grunt = require('grunt');
4+
5+
/*
6+
======== A Handy Little Nodeunit Reference ========
7+
https://github.com/caolan/nodeunit
8+
9+
Test methods:
10+
test.expect(numAssertions)
11+
test.done()
12+
Test assertions:
13+
test.ok(value, [message])
14+
test.equal(actual, expected, [message])
15+
test.notEqual(actual, expected, [message])
16+
test.deepEqual(actual, expected, [message])
17+
test.notDeepEqual(actual, expected, [message])
18+
test.strictEqual(actual, expected, [message])
19+
test.notStrictEqual(actual, expected, [message])
20+
test.throws(block, [error], [message])
21+
test.doesNotThrow(block, [error], [message])
22+
test.ifError(value)
23+
*/
24+
25+
exports.autoprefixer = {
26+
27+
sm: function(test) {
28+
var actual = {
29+
css: grunt.file.read('tmp/a.css'),
30+
map: JSON.parse(grunt.file.read('tmp/a.css.map'))
31+
};
32+
33+
var expected = {
34+
css: grunt.file.read('test/expected/a.css'),
35+
map: JSON.parse(grunt.file.read('test/expected/a.css.map'))
36+
};
37+
38+
test.strictEqual(actual.css, expected.css);
39+
test.deepEqual(actual.map, expected.map);
40+
test.done();
41+
}
42+
43+
};

0 commit comments

Comments
 (0)