Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
*.iml

coverage/
test-output.xml
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,56 @@ gulp.task('lint', function() {
});
```

### Reporter options
You can also pass options to the built-in formatter, by passing a second option to `reporter`.

```js
gulp.task('lint', function() {
gulp.files('lib/*.css')
.pipe(csslint())
.pipe(csslint.reporter('junit-xml', options));
});
```

See the documentation for the formatters regarding what options they support.

This plugin supports one option outside of that, called `logger`, allowing you to specify how to log out the report.
Default is using `process.stdout.write`, but you can use e.g. `console.log`, or `gutil.log`.

```js
gulp.task('lint', function() {
gulp.files('lib/*.css')
.pipe(csslint())
.pipe(csslint.reporter('junit-xml', {logger: console.log.bind(console)}));
});
```

```js
gulp.task('lint', function() {
gulp.files('lib/*.css')
.pipe(csslint())
.pipe(csslint.reporter('junit-xml', {logger: gutil.log.bind(null, 'gulp-csslint:')}));
});
```

`logger` is called once for the starting format of the reporter, then once for each file containing violations, then
lastly once for the ending format. Instead of writing to `stdout`, you can write to file using this option.

```js
gulp.task('lint', function(cb) {
var fs = require('fs');
var output = '';

gulp.files('lib/*.css')
.pipe(csslint())
.pipe(csslint.reporter('junit-xml', {logger: function(str) { output += str; }}));

fs.writeFile('some/path/junit.xml', output, cb);
});
```

This functionality is only available when not using custom reporters.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This small note could be removed when #29 comes in, dropping support for custom


## Custom rules

Use the `csslint.addRule(rule)` method to define custom rules that run in addition to the rules defined in the csslintrc file. See [Working with Rules](https://github.com/CSSLint/csslint/wiki/Working-with-Rules) for details.
Expand Down
18 changes: 11 additions & 7 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,15 @@ var cssLintPlugin = function(options) {
});
};

cssLintPlugin.reporter = function(customReporter) {
cssLintPlugin.reporter = function(customReporter, options) {
var reporter = csslint.getFormatter('text');
var builtInReporter = true;
var output;

options = options || {};

var logger = options.logger || process.stdout.write.bind(process.stdout);

if (typeof customReporter === 'function') {
reporter = customReporter;
builtInReporter = false;
Expand All @@ -101,7 +105,7 @@ cssLintPlugin.reporter = function(customReporter) {
// Only report if CSSLint was ran and errors were found
if (file.csslint && !file.csslint.success) {
if (builtInReporter) {
output.push(reporter.formatResults(file.csslint.originalReport, file.path));
output.push(reporter.formatResults(file.csslint.originalReport, file.path, options));
}
else {
reporter(file);
Expand All @@ -111,14 +115,14 @@ cssLintPlugin.reporter = function(customReporter) {
return cb(null, file);
},
function(cb) {
var report;

if (builtInReporter) {
output.push(reporter.endFormat());
report = output.join('');

// Only print report if the report is not empty
report && gutil.log(report);
output
.filter(function(str) {
return str;
})
.forEach(logger);
}

return cb();
Expand Down
2 changes: 1 addition & 1 deletion test/expected/checkstyle-xml.xml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?xml version="1.0" encoding="utf-8"?><checkstyle><file name="test/fixtures/usingImportant.css"><error line="2" column="1" severity="warning" message="Bad naming: .mybox" source="net.csslint.OOCSS"/><error line="3" column="3" severity="warning" message="Use of !important" source="net.csslint.Disallow!important"/></file></checkstyle>
<file name="test/fixtures/usingImportant.css"><error line="2" column="1" severity="warning" message="Bad naming: .mybox" source="net.csslint.OOCSS"/><error line="3" column="3" severity="warning" message="Use of !important" source="net.csslint.Disallow!important"/></file>
76 changes: 61 additions & 15 deletions test/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ var getFile = function(filePath) {

var getContents = function(filePath) {
filePath = 'test/' + filePath;
return fs.readFileSync(filePath, 'utf8');
return fs.readFileSync(filePath, 'utf8').trim();
};

describe('gulp-csslint', function() {
Expand Down Expand Up @@ -276,16 +276,15 @@ describe('gulp-csslint', function() {
});

describe('cssLintPlugin.reporter()', function() {
it('should support built-in CSSLint formatters', sinon.test(function(done) {
it('should support built-in CSSLint formatters', function(done) {
var a = 0;

var file = getFile('fixtures/usingImportant.css');
var expected = getContents('expected/checkstyle-xml.xml');
var callback = sinon.spy();

var lintStream = cssLintPlugin();
var reporterStream = cssLintPlugin.reporter('checkstyle-xml');

sinon.stub(gutil, 'log');
var reporterStream = cssLintPlugin.reporter('checkstyle-xml', {logger: callback});

reporterStream.on('data', function() {
++a;
Expand All @@ -299,27 +298,75 @@ describe('gulp-csslint', function() {

reporterStream.once('end', function() {
a.should.equal(1);
sinon.assert.calledOnce(gutil.log);
sinon.assert.calledWith(gutil.log, expected);
sinon.assert.calledThrice(callback);
callback.firstCall.args[0].should.equal('<?xml version="1.0" encoding="utf-8"?><checkstyle>');
callback.secondCall.args[0].should.equal(expected);
callback.thirdCall.args[0].should.equal('</checkstyle>');

gutil.log.restore();
done();
});

lintStream.write(file);
lintStream.end();
}));
});

it('should not print empty output by built-in CSSLint formatters', sinon.test(function(done) {
it('should write report to disk', function(done) {
var a = 0;
var output = '';

var file = getFile('fixtures/validCSS.css');
var file = getFile('fixtures/usingImportant.css');
var expected = getContents('expected/checkstyle-xml.xml');

var lintStream = cssLintPlugin();
var reporterStream = cssLintPlugin.reporter('text');
var reporterStream = cssLintPlugin.reporter('checkstyle-xml', {
logger: function(str) {
output += str;
}
});

sinon.stub(gutil, 'log');

reporterStream.on('data', function() {
++a;
});
lintStream.on('data', function(file) {
reporterStream.write(file);
});
lintStream.once('end', function() {
reporterStream.end();
});

reporterStream.once('end', function() {
fs.writeFile('test-output.xml', output, function() {
a.should.equal(1);
sinon.assert.notCalled(gutil.log);

gutil.log.restore();

fs.readFile('test-output.xml', function(err, content) {
(err === null).should.be.true;

var toString = content.toString();

toString.should.equal('<?xml version="1.0" encoding="utf-8"?><checkstyle>' + expected + '</checkstyle>');
done();
});
});
});

lintStream.write(file);
lintStream.end();
});

it('should not print empty output by built-in CSSLint formatters', function(done) {
var a = 0;

var file = getFile('fixtures/validCSS.css');
var callback = sinon.spy();

var lintStream = cssLintPlugin();
var reporterStream = cssLintPlugin.reporter('text', {logger: callback});

reporterStream.on('data', function() {
++a;
});
Expand All @@ -333,15 +380,14 @@ describe('gulp-csslint', function() {
});

reporterStream.once('end', function() {
sinon.assert.notCalled(callback);
a.should.equal(1);
sinon.assert.callCount(gutil.log, 0);

gutil.log.restore();
done();
});

lintStream.write(file);
lintStream.end();
}));
});
});
});