diff --git a/.gitignore b/.gitignore index 12eb472..611cbac 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,6 @@ npm-debug.log # directory creating by the Sass conversion which is done when testing grunt task # against Compass stylesheets. .sass-cache/ + +# convenient directory for storing files that should be ignored by Git. +ignore/ diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..a5a7b55 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,47 @@ +### 0.6.2 (28th April 2014) + +* Updated grunt dependency to 0.4.2. +* Fixed example in README of outputting analysis to a file. +* Fixed issue causing task to crash when processing files with large amounts of duplication. + +### 0.6.1 (September 13th 2013) + +* Fixed typo in documentation example courtesy of [joshmatz](https://github.com/joshmatz). ([#9](https://github.com/peterkeating/grunt-csscss/pull/9)) + +### 0.6.0 (August 17th 2013) + +* Removed `compassConfig` option. +* Refactored task to use [`this.files` instead of `this.data`](http://dontkry.com/posts/code/2013-04-24-use-this-files.html). +* Added ability to write output from CSSCSS to a file. ([#8](https://github.com/peterkeating/grunt-csscss/issues/8)) + +### 0.5.0 (June 4th 2013) + +* Specifying which files CSSCSS should analyse now supports glob patterns. ([#7](https://github.com/peterkeating/grunt-csscss/issues/7)) +* Fixed typos in the documentation. ([#5](https://github.com/peterkeating/grunt-csscss/issues/5)) +* Added `bundleExec` option to run CSSCSS in the context of a bundle. ([#6](https://github.com/peterkeating/grunt-csscss/issues/6)) + +### 0.4.0 (April 21st 2013) + +* Added `ignoreSassMixins` option to ignore matches in Sass mixins. +* Added `require` option for loading Ruby file before running CSSCSS. +* Updated the `compassConfig` option to use the `--require` argument instead of the now deprecated `--compass-with-config` argument. +* Deprecated `compassConfig` option. + +### 0.3.1 (April 17th 2013) + +* Fixed bug with grunt task failing when CSSCSS outputs JSON even though duplicates weren't found. ([#3](https://github.com/peterkeating/grunt-csscss/issues/3)) +* Performance improvements by moving re-used argument construction outside the file loop. + +### 0.3.0 (April 16th 2013) + +* Added `failWhenDuplicates` option to fail Grunt task when CSSCSS finds rule sets with duplicate declarations. ([#2](https://github.com/peterkeating/grunt-csscss/issues/2)) + +### 0.2.0 (April 13th 2013) + +* Added `showParserErrors` option to output parser errors. +* Added `shorthand` option to determined whether shorthand should be parsed. +* Added `compassConfig` option to specify path to Compass config file. + +### 0.1.0 (April 12th 2013) + +* Initial release supporting all options for CSSCSS v1.0.0. diff --git a/README.md b/README.md index fc07e7c..587109a 100644 --- a/README.md +++ b/README.md @@ -50,16 +50,6 @@ Enables Compass extensions when parsing Sass. *[Compass](http://compass-style.org/) must be installed in order to use this option.* -### compassConfig - DEPRECATED - -Type: `String` - -Enables Compass extension and specifies path to a config file. - -**This option is deprecated, the require option should be used.** - -*[Compass](http://compass-style.org/) must be installed in order to use this option.* - ### failWhenDuplicates Type: `Boolean` @@ -209,39 +199,26 @@ csscss: { } ``` -## Release History - -### 0.5.0 (June 4th 2013) - -* Specifying which files CSSCSS should analyse now supports glob patterns. ([#7](https://github.com/peterkeating/grunt-csscss/issues/7)) -* Fixed typos in the documentation. ([#5](https://github.com/peterkeating/grunt-csscss/issues/5)) -* Added `bundleExec` option to run CSSCSS in the context of a bundle. ([#6](https://github.com/peterkeating/grunt-csscss/issues/6)) - -### 0.4.0 (April 21st 2013) - -* Added `ignoreSassMixins` option to ignore matches in Sass mixins. -* Added `require` option for loading Ruby file before running CSSCSS. -* Updated the `compassConfig` option to use the `--require` argument instead of the now deprecated `--compass-with-config` argument. -* Deprecated `compassConfig` option. +### Outputting analysis to a file. -### 0.3.1 (April 17th 2013) +Example of using the Grunt task to output the analysis from CSSCSS to a local file. The example below will create (if necessary) `output.json` file, where it will write the output from CSSCSS. If the `outputJson` property is set to true (like in the example below) then valid JSON will be written to the file. -* Fixed bug with grunt task failing when CSSCSS outputs JSON even though duplicates weren't found. ([#3](https://github.com/peterkeating/grunt-csscss/issues/3)) -* Performance improvements by moving re-used argument construction outside the file loop. - -### 0.3.0 (April 16th 2013) - -* Added `failWhenDuplicates` option to fail Grunt task when CSSCSS finds rule sets with duplicate declarations. ([#2](https://github.com/peterkeating/grunt-csscss/issues/2)) - -### 0.2.0 (April 13th 2013) - -* Added `showParserErrors` option to output parser errors. -* Added `shorthand` option to determined whether shorthand should be parsed. -* Added `compassConfig` option to specify path to Compass config file. +```js +csscss: { + dist: { + options: { + outputJson: true + }, + files: { + 'output.json': ['css/style.css'] + } + } +} +``` -### 0.1.0 (April 12th 2013) +## Release History -* Initial release supporting all options for CSSCSS v1.0.0. +See [CHANGELOG](https://github.com/peterkeating/grunt-csscss/blob/master/CHANGELOG.md). ## Credits diff --git a/gruntfile.js b/gruntfile.js index b9ed37b..69499a1 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -64,9 +64,20 @@ module.exports = function(grunt) { */ globbing: { src: ['test/example/*.css'] + }, + + /** + * Tests outputting CSSCSS findings to a file. + */ + outputToFile: { + options: { + outputJson: true + }, + files: { + 'ignore/output.json': ['test/example/style.css', 'test/example/shorthand.css'] + } } } - }); /** diff --git a/package.json b/package.json index 31bc5ad..cba9f46 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "grunt-csscss", - "version": "0.5.0", + "version": "0.6.2", "description": "Grunt task that executes CSSCSS.", "homepage": "https://github.com/peterkeating/grunt-csscss", "author": { @@ -28,11 +28,8 @@ "scripts": { "test": "grunt" }, - "dependencies": { - "glob": "3.2.1" - }, "devDependencies": { - "grunt": "~0.4.1", + "grunt": "~0.4.2", "grunt-contrib-jshint": "~0.4.3" }, "keywords": [ diff --git a/tasks/csscss.js b/tasks/csscss.js index b41febc..2126400 100644 --- a/tasks/csscss.js +++ b/tasks/csscss.js @@ -8,62 +8,108 @@ module.exports = function(grunt) { grunt.registerMultiTask('csscss', 'CSSCSS redundancy analyzer.', function() { - var glob = require('glob'); - /** * Asynchronously loops through the provided files and puts them through the * CSSCSS tool. */ - function analyzeFiles(files) { - grunt.util.async.forEachSeries(files, function(f, next) { + function analyze(files) { - /** - * adds the file path as the final argument, this goes into a new array so - * the file doesn't get used in the next iteration. - */ - var cmdArgs = args.concat([f]); + /** + * Loops over all the files specified in the src array. + */ + grunt.util.async.forEachSeries(files, function(file, next) { /** - * Outputs the file that is being analysed. + * Stores the output that is to be written to the file.dest, if one is + * specified. */ - grunt.log.writeln(f); - grunt.verbose.writeln('csscss ' + cmdArgs.join(' ')); + var output = options.outputJson ? '{' : ''; /** - * Executes the csscss command. + * Loops over all the matches files in the src in case there are multiple. */ - var child = grunt.util.spawn({ - cmd: cmdArgs.shift(), - args: cmdArgs - }, function(error, result, code) { - if (code === 127) { - return grunt.warn('Ruby and csscss have to be installed and in your PATH for this task to run.'); - } + grunt.util.async.forEachSeries(file.src, function (fileToBeAnalyzed, innerNext) { - next(error); - }); + /** + * adds the file path as the final argument, this goes into a new array so + * the file doesn't get used in the next iteration. + */ + var cmdArgs = args.concat([fileToBeAnalyzed]), - /** - * displays the output and error streams via the parent process. - */ - child.stdout.on('data', function(buf) { - var output = String(buf); - grunt.log.writeln(output); + /** + * Stores the output from CSSCSS. + */ + childOutput = ''; /** - * When outputting JSON from CSSCSS an empty array will be outputted, this - * should be ignored and shouldn't cause the grunt task to fail if no other - * duplicates are found. + * Outputs the file that is being analysed. */ - if (!(options.outputJson && JSON.parse(output).length === 0)) { - hasDuplicates = true; + grunt.log.writeln(fileToBeAnalyzed); + + output += (options.outputJson) ? '\n\t"' + fileToBeAnalyzed + '": ' : fileToBeAnalyzed + '\n'; + + grunt.verbose.writeln('csscss ' + cmdArgs.join(' ')); + + /** + * Executes the csscss command. + */ + var child = grunt.util.spawn({ + cmd: cmdArgs.shift(), + args: cmdArgs + }, function(error, result, code) { + if (code === 127) { + return grunt.warn('Ruby and csscss have to be installed and in your PATH for this task to run.'); + } + + grunt.log.writeln(childOutput); + + /** + * Substring removes the carriage return from CSSCSS. + */ + output += (options.outputJson) ? childOutput.substring(0, childOutput.length - 2) + ',' : childOutput; + + /** + * When outputting JSON from CSSCSS an empty array will be outputted, this + * should be ignored and shouldn't cause the grunt task to fail if no other + * duplicates are found. + */ + if (!(options.outputJson && JSON.parse(childOutput).length === 0)) { + hasDuplicates = true; + } + + innerNext(error); + }); + + /** + * Displays the output and error streams via the parent process. + */ + child.stdout.on('data', function(buf) { + childOutput += String(buf); + }); + + child.stderr.on('data', function(buf) { + grunt.log.writeln(String(buf)); + }); + + }, function () { + + /** + * Removes the final comma so valid JSON is outputted. Also the end brace + * for the JSON object is included. + */ + if (options.outputJson) { + output = output.substring(0, output.length - 1); + output += '\n}'; } - }); - child.stderr.on('data', function(buf) { - grunt.log.writeln(String(buf)); + /** + * Write the output to the destination file if one was specified. + */ + if (file.dest) { + grunt.file.write(file.dest, output); + } + next(); }); - }, function () { /** @@ -127,20 +173,6 @@ module.exports = function(grunt) { args.push('--compass'); } - /** - * Enables Compass extensions when parsing Sass files and specifies the path - * to the config file. - * The compassConfig option is deprecated and will be removed in a future release. - * The require option should be used instead. - */ - if (options.compassConfig && !options.require) { - args.push('--compass'); - args.push('--require'); - args.push(options.compassConfig); - - grunt.log.writeln('WARNING: compassConfig is DEPRECATED, please use the "require" option.'); - } - /** * Enables Compass extensions when parsing Sass files and specifies the path * to the config file. @@ -203,28 +235,6 @@ module.exports = function(grunt) { args.push('--no-match-shorthand'); } - /** - * Array of files that are to be analyzed by CSSCSS. - */ - var filesToBeAnalyzed = []; - - grunt.util.async.forEachSeries(this.data.src, function(f, next) { - glob(f, options, function (er, files) { - /** - * Loops through the matched files and ensures that each file is only - * processed once. - */ - for (var j = 0; j < files.length; j++) { - if (filesToBeAnalyzed.indexOf(files[j]) < 0) { - filesToBeAnalyzed.push(files[j]); - } - } - - next(); - }); - }, function () { - analyzeFiles(filesToBeAnalyzed); - }); + analyze(this.files); }); - };