Created
January 9, 2014 23:03
-
-
Save xt0rted/8343782 to your computer and use it in GitHub Desktop.
A grunt task to generate JSLint style reports for use with TeamCity's XML report processing. The code is based on the built-in tslint report formatters and https://github.com/Bartvds/tslint-path-formatter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<jslint> | |
<file name="App/app.ts"> | |
<issue line="1" char="13" reason="missing whitespace"/> | |
<issue line="2" char="5" reason="comment must start with a space"/> | |
</file> | |
<file name="App/some-folder/data.ts"> | |
<issue line="1" char="13" reason="missing whitespace"/> | |
<issue line="2" char="19" reason="missing whitespace"/> | |
<issue line="2" char="20" reason="missing whitespace"/> | |
<issue line="2" char="21" reason="expected variableDeclarator: 'SOME_VARIABLE' to have a typedef."/> | |
<issue line="3" char="9" reason="variable name must be in camelcase or uppercase"/> | |
<issue line="3" char="25" reason="missing whitespace"/> | |
<issue line="3" char="26" reason="" should be '"/> | |
<issue line="3" char="26" reason="missing whitespace"/> | |
<issue line="3" char="33" reason="expected variableDeclarator: 'ANOTHER_variable' to have a typedef."/> | |
<issue line="3" char="37" reason="missing whitespace"/> | |
<issue line="3" char="38" reason="missing whitespace"/> | |
<issue line="3" char="44" reason="expected variableDeclarator: 'yup' to have a typedef."/> | |
</file> | |
</jslint> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
var XMLWriter = require('xml-writer'); | |
var Linter = require('tslint'); | |
var hasProp = Object.prototype.hasOwnProperty; | |
module.exports = function (grunt) { | |
grunt.registerMultiTask('tslint-teamcity', 'A linter for TypeScript', function () { | |
var options = this.options({ | |
formatter: 'json' | |
}); | |
if (grunt.file.exists(options.logLocation)) { | |
grunt.file.delete(options.logLocation); | |
} | |
var result = true; | |
var output = new XMLWriter(true); | |
output.startElement('jslint'); | |
this.filesSrc.forEach(function (filepath) { | |
if (!grunt.file.exists(filepath)) { | |
grunt.log.warn('Source file "' + filepath + '" not found.'); | |
} else { | |
var contents = grunt.file.read(filepath); | |
var linter = new Linter(filepath, contents, options); | |
var lintResult = linter.lint(); | |
if (lintResult.failureCount > 0) { | |
appendErrors(output, lintResult.output); | |
result = false; | |
} | |
} | |
}); | |
output.endElement(); | |
if (!result) { | |
var xmlResult = output.toString(); | |
grunt.log.error(xmlResult); | |
grunt.file.write(options.logLocation, xmlResult); | |
} | |
return result; | |
}); | |
function appendErrors(output, failures) { | |
var files = {}; | |
var data = []; | |
if (typeof failures === 'string') { | |
failures = JSON.parse(failures); | |
} | |
failures.forEach(function (failure) { | |
var fileName = failure.name; | |
var res; | |
if (hasProp.call(files, fileName)) { | |
res = files[fileName]; | |
} else { | |
files[fileName] = res = { | |
file: fileName, | |
errors: [] | |
}; | |
data.push(res); | |
} | |
res.errors.push({ | |
reason: failure.failure, | |
line: failure.startPosition.line + 1, | |
character: failure.startPosition.character + 1 | |
}); | |
}); | |
data.forEach(function (res) { | |
var errors = res.errors; | |
output.startElement('file'); | |
output.writeAttribute('name', res.file); | |
errors.sort(function (a, b) { | |
if (a && !b) { | |
return -1; | |
} else if (!a && b) { | |
return 1; | |
} | |
if (a.line < b.line) { | |
return -1; | |
} else if (a.line > b.line) { | |
return 1; | |
} | |
if (a.character < b.character) { | |
return -1; | |
} else if (a.character > b.character) { | |
return 1; | |
} | |
return 0; | |
}); | |
errors.forEach(function (error) { | |
output.startElement('issue') | |
.writeAttribute('line', '' + error.line) | |
.writeAttribute('char', '' + error.character) | |
.writeAttribute('reason', '' + error.reason) | |
.endElement(); | |
}); | |
output.endElement(); | |
}); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment