Socket
Socket
Sign inDemoInstall

eslint-teamcity

Package Overview
Dependencies
Maintainers
1
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-teamcity - npm Package Compare versions

Comparing version 1.4.0 to 2.0.0

.eslintignore

29

index.js
#!/usr/bin/env node
'use strict';
var fs = require('fs-extra'),
procArg = process.argv;
const fs = require('fs-extra');
const formatter = require('./src/formatter');
const procArg = process.argv;
/**
* The entry point for this project
* @param {string} input The output generated by running ESLint.
* @param {object} [teamcityPropNames] Any user defined config variables.
* @returns {string} The concatenated output of all messages to display in TeamCity
*/
function main(input, teamcityPropNames) {
return formatter(input, teamcityPropNames);
}
if (require.main === module) {
process.stdout.write(main(fs.readJSONSync(procArg[2])))
process.stdout.write(main(fs.readJSONSync(procArg[2])));
} else {
module.exports = main;
}
/**
* main function
* @param {String} input - input data stringify json
* @param {Object} [teamcityPropNames] - names of the vars
* @returns {String} format result
*/
function main(input, teamcityPropNames) {
return require('./src/formatter')(input, teamcityPropNames);
}
{
"name": "eslint-teamcity",
"version": "1.4.0",
"version": "2.0.0",
"description": "An ESLint formatter plugin for TeamCity",
"main": "index.js",
"scripts": {
"test": "./node_modules/mocha/bin/mocha ./test/*.spec.js",
"test-travis": "./node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha -- -R spec ./test/*.spec.js"
"lint": "./node_modules/.bin/eslint .",
"precommit": "lint-staged",
"prettier": "./node_modules/.bin/prettier --write",
"test": "./node_modules/mocha/bin/mocha \"./test/**/*.spec.js\"",
"test-travis": "./node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha -- -R spec \"./test/**/*.spec.js\""
},

@@ -25,14 +28,26 @@ "repository": {

},
"dependencies": {
"fs-extra": "^5.0.0"
},
"devDependencies": {
"chai": "^3.5.0",
"coveralls": "^2.12.0",
"eslint": "^3.18.0",
"chai": "^4.1.0",
"coveralls": "^3.0.0",
"eslint": "^4.12.1",
"eslint-config-airbnb-base": "^12.1.0",
"eslint-plugin-import": "^2.8.0",
"husky": "^0.14.3",
"istanbul": "^0.4.5",
"mocha": "^3.2.0",
"shelljs": "^0.7.8",
"sinon": "^2.1.0"
"lint-staged": "^6.0.0",
"mocha": "^4.1.0",
"prettier": "^1.9.1",
"shelljs": "^0.8.0",
"sinon": "^4.1.5"
},
"dependencies": {
"fs-extra": "^3.0.1"
"lint-staged": {
"*.js": [
"npm run prettier",
"npm run lint",
"git add"
]
}
}

@@ -14,2 +14,4 @@ # eslint-teamcity

**As of v2.0, Node v6+ is required. If you use an older version of Node, please stick with v1.x**
Prerequisite: You must have either [npm](https://docs.npmjs.com/cli/install) or [Yarn](https://yarnpkg.com/en/docs/install) installed.

@@ -22,9 +24,8 @@

## Usage
There are currently 3 ways to use eslint-teamcity:
##### As a regular ESLint formatter plugin:
There are 3 ways to use eslint-teamcity:
##### 1. As a regular ESLint formatter plugin:
```sh
eslint --format ./node_modules/eslint-teamcity/index.js myfiletolint.js
```
##### Running against a generated ESLint JSON report:
##### 2. Running against a generated ESLint JSON report:
Generate an ESLint JSON report:

@@ -34,18 +35,69 @@ ```sh

```
Run eslint-teamcity against the new report:
Run eslint-teamcity against your new report:
```sh
node ./node_modules/eslint-teamcity/index.js result.json
```
##### 3. Requiring and running directly from inside your JavaScript code:
```javascript
const eslintTeamcity = require('eslint-teamcity');
console.log(eslintTeamcity(eslintOutput));
```
##### Requiring and running directly from inside your JavaScript code:
## Configuration
As of version 2.0, there are two different formatters you can use to report with. They have no material
impact on the output - they're just different ways of viewing the same data. The "Code Inspection" tab will only
appear if you have configured eslint-teamcity to use the inspections reporter.
Errors (default) | Inspections
:-------------------------:|:-------------------------:
![Example Errors Report](https://i.imgur.com/3AzQeMy.png) | ![Example Inspections Report](https://i.imgur.com/JXzBuaV.png)
There are several ways that you can configure eslint-teamcity. **You don't have to configure anything by default**, you just have the option to if you would like.
Settings are looked for in the following priority:
##### 1. As a second argument
If you run eslint-teamcity by requiring it in JavaScript, you can pass a second argument to the function:
```javascript
var eslintTeamcity = require('eslint-teamcity');
console.log(eslintTeamcity(result));
const eslintTeamcity = require('eslint-teamcity');
const options = {
reporter: 'inspections', // default: 'errors'
reportName: 'My ESLint Violations', // default: 'ESLint Violations'
errorStatisticsName: 'My ESLint Error Count', // default: 'ESLint Error Count'
warningStatisticsName: 'My ESLint Warning Count', // default: 'ESLint Warning Count'
};
console.log(eslintTeamcity(eslintOutput, options));
```
##### 2. From your package.json
If you have a package.json file in the **current directory**, you can add an extra "eslint-teamcity" property to it:
```json
...,
"eslint-teamcity": {
"reporter": "inspections",
"report-name": "My ESLint Violations",
"error-statistics-name": "My ESLint Error Count",
"warning-statistics-name": "My ESLint Warning Count"
},
...
```
##### 3. ENV variables
```bash
export ESLINT_TEAMCITY_REPORTER=inspections
export ESLINT_TEAMCITY_REPORT_NAME="My Formatting Problems"
export ESLINT_TEAMCITY_ERROR_STATISTICS_NAME="My Error Count"
export ESLINT_TEAMCITY_WARNING_STATISTICS_NAME="My Warning Count"
```
You can also output your current settings to the log if you set:
```bash
export ESLINT_TEAMCITY_DISPLAY_CONFIG=true
```
## [gulp-eslint](https://github.com/adametry/gulp-eslint) integration
```javascript
var gulp = require('gulp');
var eslint = require('gulp-eslint');
var teamcity = require('eslint-teamcity');
const gulp = require('gulp');
const eslint = require('gulp-eslint');
const teamcity = require('eslint-teamcity');

@@ -63,26 +115,44 @@ gulp.task('lint', function () {

## TeamCity usage (with [gulp-eslint](http://github.com/adametry/gulp-eslint))
Add a gulp task to run ESLint (see above)
## TeamCity Usage
The simplest way to run eslint-teamcity is from an npm script in a build step. You could setup a script similar to this:
```json
"scripts": {
"lint:teamcity": "node node_modules/.bin/eslint app/src -f './node_modules/eslint-teamcity/index.js'"
}
```
Setup a TeamCity build step, similar to the below screenshot:
You could also run it as a gulp task (if you use [gulp](https://github.com/gulpjs/gulp) and [gulp-eslint](https://github.com/adametry/gulp-eslint)):
![Example TeamCity Setup](https://i.imgur.com/j7qMSYg.jpg)
![Example TeamCity Setup](https://i.imgur.com/R3ypYXu.png)
Kick off a new build, by deploying again, and you should see your build errors - assuming you have any!
#### Screenshot with TeamCity
![Example TeamCity Output](https://i.imgur.com/DkwEPEN.jpg)
## Extras
eslint-teamcity will also output statistic values which you can use in TeamCity to track your progress in resolving errors!
Graphs can be setup from the Builds -> Statistics tab.
Graphs can be setup from the Build -> Statistics tab.
![Example Statistics Output](http://i.imgur.com/oHbiuZE.png)
## Development
The quickest way to get a TeamCity server setup is to use Docker:
```shell
docker run -itd --name teamcity-server \
-v <path to data directory>:/data/teamcity_server/datadir \
-v <path to logs directory>:/opt/teamcity/logs \
-p 8111:8111 \
jetbrains/teamcity-server
docker run -itd -e SERVER_URL="<your ip4 address>:8111" \
-v <path to agent config folder>:/data/teamcity_agent/conf \
jetbrains/teamcity-agent
```
If you fork the repo and are testing on your local TeamCity instance, it may help to run `rm -rf node_modules` in a
build step as TeamCity seems to cache versions between commits.
## Issues
I will try keep this project up to date, but please log any issues
[here](https://github.com/andreogle/eslint-teamcity/issues).
Any pull requests are also welcome!

@@ -1,99 +0,78 @@

/**
* @fileoverview TeamCity report formatter plugin for ESLint
* @author Andre Ogle
*/
const utils = require('./utils');
const formatErrors = require('./formatters/errors');
const formatInspections = require('./formatters/inspections');
'use strict';
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Escape special characters with the respective TeamCity escaping.
* See below link for list of special characters:
* https://confluence.jetbrains.com/display/TCD9/Build+Script+Interaction+with+TeamCity
* @param {string} str An error message to display in TeamCity.
* @returns {string} An error message formatted for display in TeamCity
* Determines the config to be used by the respective formatter
* Config is selected based on the following priority:
* 1. Any user defined props when running eslint-teamcity
* 2. package.json settings
* 3. ENV variables
* 4. Default value
* @param {object} propNames Optional config variables that will override all other config settings
* @returns {object} The final config settings to be used
*/
function escapeTeamCityString(str) {
if (!str) {
return '';
}
function getUserConfig(propNames) {
// Attempt to load package.json from current directory
const config = JSON.parse(utils.loadPackageJson())['eslint-teamcity'] || {};
return str.replace(/\|/g, '||')
.replace(/\'/g, '|\'')
.replace(/\n/g, '|n')
.replace(/\r/g, '|r')
.replace(/\u0085/g, '|x') // TeamCity 6
.replace(/\u2028/g, '|l') // TeamCity 6
.replace(/\u2029/g, '|p') // TeamCity 6
.replace(/\[/g, '|[')
.replace(/\]/g, '|]');
}
const reporter =
propNames.reporter || config.reporter || process.env.ESLINT_TEAMCITY_REPORTER || 'errors';
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
module.exports = function(results, teamcityPropNames) {
var output = '';
var errorCount = 0;
var warningCount = 0;
var reportName;
var errorCountName;
var warningCountName;
var varNames = teamcityPropNames || {};
const reportName =
propNames.reportName ||
config['report-name'] ||
process.env.ESLINT_TEAMCITY_REPORT_NAME ||
'ESLint Violations';
reportName = varNames.reportName || 'ESLint Violations';
errorCountName = varNames.errorCountName || 'ESLintErrorCount';
warningCountName = varNames.warningCountName || 'ESLintWarningCount';
const errorStatisticsName =
propNames.errorStatisticsName ||
config['error-statistics-name'] ||
process.env.ESLINT_TEAMCITY_ERROR_STATISTICS_NAME ||
'ESLint Error Count';
output += '##teamcity[testSuiteStarted name=\'' + reportName + '\']\n';
const warningStatisticsName =
propNames.warningStatisticsName ||
config['warning-statistics-name'] ||
process.env.ESLINT_TEAMCITY_WARNING_STATISTICS_NAME ||
'ESLint Warning Count';
results.forEach(function(result) {
var messages = result.messages;
return {
reporter,
reportName: utils.escapeTeamCityString(reportName),
errorStatisticsName: utils.escapeTeamCityString(errorStatisticsName),
warningStatisticsName: utils.escapeTeamCityString(warningStatisticsName)
};
}
if (messages.length === 0) {
return;
}
/**
* Determines the formatter to use and any config variables to use
* @param {array} results The output generated by running ESLint.
* @param {object} [propNames] Optional config variables that will override all other
* config settings
* @returns {string} The concatenated output of all messages to display in TeamCity
*/
function getTeamCityOutput(results, propNames) {
const config = getUserConfig(propNames || {});
output += '##teamcity[testStarted name=\'' + reportName + ': ' +
escapeTeamCityString(result.filePath) + '\']\n';
if (process.env.ESLINT_TEAMCITY_DISPLAY_CONFIG) {
console.info(`Running ESLint Teamcity with config: ${JSON.stringify(config, null, 4)}`);
}
var errorsList = [];
var warningsList = [];
messages.forEach(function(message) {
var userMessage = 'line ' + (message.line || 0) +
', col ' + (message.column || 0) +
', ' + message.message + (message.ruleId ? ' (' + message.ruleId + ')' : '');
if (message.fatal || message.severity === 2) {
errorsList.push(userMessage);
errorCount++;
} else {
warningsList.push(userMessage);
warningCount++;
}
});
if (errorsList.length) {
output += '##teamcity[testFailed name=\'' + reportName + ': ' +
escapeTeamCityString(result.filePath) + '\' message=\'' +
escapeTeamCityString(errorsList.join('\n')) + '\']\n';
} else if (warningsList.length) {
output += '##teamcity[testStdOut name=\'' + reportName + ': ' +
escapeTeamCityString(result.filePath) + '\' out=\'warning: ' +
escapeTeamCityString(warningsList.join('\n')) + '\']\n';
let outputMessages = [];
switch (config.reporter.toLowerCase()) {
case 'inspections': {
outputMessages = formatInspections(results, config);
break;
}
output += '##teamcity[testFinished name=\'' + reportName + ': ' +
escapeTeamCityString(result.filePath) + '\']\n';
});
case 'errors':
default: {
outputMessages = formatErrors(results, config);
break;
}
}
output += '##teamcity[testSuiteFinished name=\'' + reportName + '\']\n';
return outputMessages.join('\n');
}
output += '##teamcity[buildStatisticValue key=\'' + errorCountName + '\' value=\'' + errorCount +'\' ]\n';
output += '##teamcity[buildStatisticValue key=\'' + warningCountName + '\' value=\'' + warningCount +'\' ]\n';
return output;
};
module.exports = getTeamCityOutput;

@@ -1,52 +0,61 @@

var expect = require('chai').expect;
var sinon = require('sinon');
var sh = require('shelljs');
var path = require('path');
var basePath = path.resolve(__dirname, '..');
var eslintResultGenerator = require('./eslintResultGenerator');
var fs = require('fs-extra');
var pathToTestJson = path.resolve(__dirname, 'result.json');
var pathToIndex = path.resolve(__dirname, '..', 'index.js');
var input = [];
var result;
describe('support interface',function() {
/* global it, describe, beforeEach, afterEach */
before(function() {
input.push(eslintResultGenerator.createDummyError());
});
const { expect } = require('chai');
const sh = require('shelljs');
const path = require('path');
const fs = require('fs-extra');
const { createDummyError } = require('./helpers/eslint-factory');
describe('cmd',function() {
it('as eslint formatter', function() {
result = sh.exec('eslint --format ' + '\'' + pathToIndex + '\' ' + pathToIndex);
expect(result.stdout).to.contain('##teamcity');
});
const basePath = path.resolve(__dirname, '..');
const pathToTestJson = path.resolve(__dirname, 'result.json');
const pathToIndex = path.resolve(__dirname, '..', 'index.js');
it('as standalone',function() {
fs.writeJSONSync(pathToTestJson, input);
result = sh.exec('cd ' + basePath + '; node ' + 'index.js ' + pathToTestJson);
expect(result.stdout).to.contain('##teamcity');
expect(result.stderr).to.equal('');
describe('smoke tests', function() {
describe('support interface', function() {
let esLintOutput = [];
sh.rm(pathToTestJson);
beforeEach(function() {
esLintOutput.push(createDummyError());
});
});
describe('requirejs',function() {
it('basic', function() {
result = require(pathToIndex)(input);
expect(result).to.contain('##teamcity');
afterEach(function() {
esLintOutput = [];
});
it('with parameters', function() {
var teamcityPropNames = {
errorCountName: 'EslintInspectionStatsE',
warningCountName: 'EslintInspectionStatsW'
};
describe('cmd', function() {
it('as eslint formatter plugin', function() {
this.timeout(8000);
const result = sh.exec(`eslint --format '${pathToIndex}' ${pathToIndex}`);
expect(result.stdout).to.contain('##teamcity');
});
result = require(pathToIndex)(input, teamcityPropNames);
expect(result).to.contain('ESLint Violations');
expect(result).to.contain('EslintInspectionStatsE');
expect(result).to.contain('EslintInspectionStatsW');
it('as standalone', function() {
fs.writeJSONSync(pathToTestJson, esLintOutput);
const result = sh.exec(`cd ${basePath}; node index.js ${pathToTestJson}`);
expect(result.stdout).to.contain('##teamcity');
expect(result.stderr).to.equal('');
sh.rm(pathToTestJson);
});
});
describe('requirejs', function() {
it('basic', function() {
const result = require(pathToIndex)(esLintOutput);
expect(result).to.contain('##teamcity');
});
it('with parameters', function() {
const teamcityPropNames = {
errorStatisticsName: 'EslintInspectionStatsE',
warningStatisticsName: 'EslintInspectionStatsW'
};
const result = require(pathToIndex)(esLintOutput, teamcityPropNames);
expect(result).to.contain('ESLint Violations');
expect(result).to.contain('EslintInspectionStatsE');
expect(result).to.contain('EslintInspectionStatsW');
});
});
});
});
});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc