Skip to content
This repository was archived by the owner on Feb 19, 2020. It is now read-only.

Commit 749f3f4

Browse files
authored
Merge pull request #41 from codacy/detect-files-language
Detect files language and send separate reports per language
2 parents 8b149e6 + c31dadf commit 749f3f4

File tree

9 files changed

+132
-68
lines changed

9 files changed

+132
-68
lines changed

.editorconfig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# This file is for unifying the coding style for different editors and IDEs
2+
# editorconfig.org
3+
4+
root = true
5+
6+
[*]
7+
end_of_line = lf
8+
charset = utf-8
9+
insert_final_newline = true
10+
trim_trailing_whitespace = true
11+
indent_style = space
12+
indent_size = 4
13+
max_line_length = 120
14+
15+
[Makefile]
16+
indent_style = tab

lib/handleInput.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
var commit = opts.commit;
88
var format = opts.format || 'lcov';
99
var pathPrefix = opts.prefix || '';
10-
var language = opts.language || 'javascript';
10+
var language = opts.language;
1111
var loggerImpl;
1212

1313
loggerImpl = logger({

lib/reporter.js

Lines changed: 109 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
(function (request, Joi, Promise, util, logger) {
1+
(function(request, Joi, Promise, util, lodash, logger) {
22
'use strict';
33

44
var optionsValidation = Joi.object({
@@ -15,7 +15,96 @@
1515
}).required())
1616
}).example({total: 50, fileReports: [{filename: 'filename', total: 10, coverage: {1: 1, 2: 3}}]});
1717

18-
module.exports = function (options) {
18+
var languageMap = {
19+
js: 'javascript',
20+
jsx: 'javascript',
21+
ts: 'typescript',
22+
tsx: 'typescript',
23+
coffee: 'coffeescript'
24+
}
25+
26+
function sendByLanguage(endpoint, commitId, token, data) {
27+
var reportsByLanguage = lodash.groupBy(data.fileReports, function(elem) {
28+
return languageMap[lodash.head(lodash.takeRight(elem.filename.split('.'), 1))] || 'javascript';
29+
});
30+
31+
var languageResponses = lodash.map(reportsByLanguage, function(fileReports, language) {
32+
var weighedCoverage = lodash.reduce(fileReports, function(accom, elem) {
33+
return accom + (elem.total * Object.keys(elem.coverage).length);
34+
}, 0);
35+
36+
var coveredLines = lodash.reduce(fileReports, function(accom, elem) {
37+
return accom + Object.keys(elem.coverage).length;
38+
}, 0);
39+
40+
var finalCoverage = weighedCoverage / coveredLines;
41+
42+
var dataPerLanguage = lodash.clone(data);
43+
dataPerLanguage.fileReports = fileReports;
44+
dataPerLanguage.total = Math.floor(finalCoverage);
45+
46+
return sendLanguage(endpoint, commitId, language, token, dataPerLanguage);
47+
});
48+
49+
return Promise.all(languageResponses)
50+
.then(function(errs) {
51+
errs = lodash.filter(errs, function(e) {
52+
return !lodash.isUndefined(e)
53+
});
54+
55+
if (errs.length) {
56+
return Promise.reject(errs[0]);
57+
}
58+
59+
logger.trace('All languages sent successfully');
60+
return Promise.resolve();
61+
}, function(err) {
62+
logger.trace('Failed to send some languages');
63+
return Promise.reject(err);
64+
});
65+
}
66+
67+
function sendForLanguage(endpoint, commitId, language, token, data) {
68+
return sendLanguage(endpoint, commitId, language, token, data)
69+
.then(function(err) {
70+
if (err) {
71+
return Promise.reject(err);
72+
}
73+
return Promise.resolve();
74+
}, function(err) {
75+
return Promise.reject(err);
76+
});
77+
}
78+
79+
function sendLanguage(endpoint, commitId, language, token, data) {
80+
var url = endpoint.replace(':commitId', commitId).replace(':language', language);
81+
logger.trace(util.format('Sending POST to %s', url));
82+
return request({
83+
url: url,
84+
method: 'POST',
85+
json: data,
86+
headers: {
87+
// jscs:disable
88+
project_token: token
89+
// jscs:enable
90+
},
91+
resolveWithFullResponse: true
92+
}).then(function(res) {
93+
if (res.statusCode !== 200) {
94+
var err = new Error(util.format('Expected Status Code of 200, but got [%s]', res.statusCode));
95+
logger.error(util.format('Status Code [%s] - Error [%j]', res.statusCode, res.error));
96+
return Promise.reject(err);
97+
}
98+
logger.debug('Successfully sent coverage data');
99+
return Promise.resolve();
100+
}, function(res) {
101+
var err = new Error(util.format('Expected Successful Status Code, but got [%s]', res.statusCode));
102+
logger.error(util.format('Status Code [%s] - Error [%j]', res.statusCode, res.error));
103+
return Promise.reject(err);
104+
});
105+
}
106+
107+
module.exports = function(options) {
19108
logger.trace(util.format('Creating reporter for %j', options));
20109
var optionsValid = Joi.validate(options, optionsValidation, {
21110
stripUnknown: true
@@ -31,48 +120,25 @@
31120

32121
return {
33122
sendCoverage: function sendCoverage(token, commitId, language, data) {
34-
return new Promise(function (resolve, reject) {
35-
logger.trace(util.format('Sending Coverage for token [%s] and commitId [%s]', token, commitId));
36-
var tokenValid = Joi.validate(token, tokenValidation);
37-
var commitIdValid = Joi.validate(commitId, commitIdValidation);
38-
var dataValid = Joi.validate(data, coverageDataValidation, {
39-
stripUnknown: true
40-
});
41-
var validationErr = tokenValid.error || commitIdValid.error || dataValid.error;
42-
43-
if (validationErr) {
44-
logger.error(validationErr);
45-
return reject(validationErr);
46-
}
47-
48-
var url = endpoint.replace(':commitId', commitId).replace(':language', language);
49-
logger.trace(util.format('Sending POST to %s', url));
50-
51-
return request({
52-
url: url,
53-
method: 'POST',
54-
json: data,
55-
headers: {
56-
// jscs:disable
57-
project_token: token
58-
// jscs:enable
59-
},
60-
resolveWithFullResponse: true
61-
}).then(function (res) {
62-
if (res.statusCode !== 200) {
63-
var err = new Error(util.format('Expected Status Code of 200, but got [%s]', res.statusCode));
64-
logger.error(util.format('Status Code [%s] - Error [%j]', res.statusCode, res.error));
65-
return reject(err);
66-
}
67-
logger.debug('Successfully sent coverage data');
68-
resolve();
69-
}, function (res) {
70-
var err = new Error(util.format('Expected Successful Status Code, but got [%s]', res.statusCode));
71-
logger.error(util.format('Status Code [%s] - Error [%j]', res.statusCode, res.error));
72-
reject(err);
73-
});
123+
logger.trace(util.format('Sending Coverage for token [%s] and commitId [%s]', token, commitId));
124+
var tokenValid = Joi.validate(token, tokenValidation);
125+
var commitIdValid = Joi.validate(commitId, commitIdValidation);
126+
var dataValid = Joi.validate(data, coverageDataValidation, {
127+
stripUnknown: true
74128
});
129+
var validationErr = tokenValid.error || commitIdValid.error || dataValid.error;
130+
131+
if (validationErr) {
132+
logger.error(validationErr);
133+
return Promise.reject(validationErr);
134+
}
135+
136+
if (language) {
137+
return sendForLanguage(endpoint, commitId, language, token, data);
138+
}
139+
140+
return sendByLanguage(endpoint, commitId, token, data);
75141
}
76142
};
77143
};
78-
}(require('request-promise'), require('joi'), require('bluebird'), require('util'), require('./logger')()));
144+
}(require('request-promise'), require('joi'), require('bluebird'), require('util'), require('lodash'), require('./logger')()));

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"commander": "^2.x",
3333
"joi": "^6.4.x",
3434
"lcov-parse": "0.x",
35+
"lodash": "^4.17.4",
3536
"log-driver": "^1.x",
3637
"request-promise": "^0.x"
3738
},

test/cli.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
}
6363

6464
expect(res).to.match(/Started with: token \["1234"], commitId \["4321"], language \[undefined], endpoint \["something"], format \["lcov"], path prefix \["asdf\/"], verbose \[true], debug \[true]/);
65-
expect(res).to.match(/Handling input for: token \["1234"], commitId \["4321"], language \["javascript"], endpoint \["something"], format \["lcov"], path prefix \["asdf\/"], verbose \[true], debug \[true]/);
65+
expect(res).to.match(/Handling input for: token \["1234"], commitId \["4321"], language \[undefined], endpoint \["something"], format \["lcov"], path prefix \["asdf\/"], verbose \[true], debug \[true]/);
6666
done();
6767
});
6868
});

test/handleInput.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
var bodyValidator = Joi.object({
1515
total: Joi.number().valid(50),
1616
fileReports: Joi.array().items(Joi.object({
17-
filename: Joi.string().valid('filename'),
17+
filename: Joi.string().valid('filename.js'),
1818
total: Joi.number().valid(10),
1919
coverage: Joi.object({
2020
1: Joi.number().valid(1),
@@ -27,7 +27,7 @@
2727
total: 50,
2828
fileReports: [
2929
{
30-
filename: 'filename',
30+
filename: 'filename.js',
3131
total: 10,
3232
coverage: {
3333
1: 1,

test/lcov.js

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
var expect = helper.chai.expect;
55
var lcovData = fs.readFileSync(__dirname + '/mock/lcov.info').toString();
66
var noStatsLcovData = fs.readFileSync(__dirname + '/mock/no-lines.info').toString();
7-
var nadaLcovData = fs.readFileSync(__dirname + '/mock/nada.info').toString();
87

98
describe('Lcov Parser', function () {
109
it('should be able to parse lcov data', function () {
@@ -105,21 +104,5 @@
105104
return true;
106105
});
107106
});
108-
it('should be able to parse lcov data without anything', function () {
109-
return expect(parser.getParser('lcov').parse('', nadaLcovData))
110-
.to.eventually.satisfy(function (data) {
111-
expect(JSON.stringify(data)).to.equal(JSON.stringify({
112-
total: 0,
113-
fileReports: [
114-
{
115-
filename: '',
116-
coverage: {},
117-
total: 0
118-
}
119-
]
120-
}));
121-
return true;
122-
});
123-
});
124107
});
125108
}(require('fs'), require('../lib/coverageParser'), require('./helper'), require('path')));

test/mock/nada.info

Lines changed: 0 additions & 2 deletions
This file was deleted.

test/reporter.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
bodyValidator = Joi.object({
1212
total: Joi.number().valid(50),
1313
fileReports: Joi.array().items(Joi.object({
14-
filename: Joi.string().valid('filename'),
14+
filename: Joi.string().valid('filename.js'),
1515
total: Joi.number().valid(10),
1616
coverage: Joi.object({
1717
1: Joi.number().valid(1),
@@ -24,7 +24,7 @@
2424
total: 50,
2525
fileReports: [
2626
{
27-
filename: 'filename',
27+
filename: 'filename.js',
2828
total: 10,
2929
coverage: {
3030
1: 1,

0 commit comments

Comments
 (0)