UNPKG

3.68 kBJavaScriptView Raw
1'use strict';
2
3const fs = require('fs');
4const path = require('path');
5const lcovParse = require('lcov-parse');
6const logger = require('./logger')();
7
8const detailsToCoverage = (length, details) => {
9 const coverage = new Array(length);
10
11 details.forEach(obj => {
12 coverage[obj.line - 1] = obj.hit;
13 });
14
15 return coverage;
16};
17
18const detailsToBranches = details => {
19 const branches = [];
20
21 details.forEach(obj => {
22 ['line', 'block', 'branch', 'taken'].forEach(key => {
23 branches.push(obj[key] || 0);
24 });
25 });
26
27 return branches;
28};
29
30const convertLcovFileObject = (file, filepath) => {
31 const rootpath = filepath;
32 filepath = path.resolve(rootpath, file.file);
33 const source = fs.readFileSync(filepath, 'utf8');
34 const lines = source.split('\n');
35 const coverage = detailsToCoverage(lines.length, file.lines.details);
36 const branches = detailsToBranches(file.branches.details);
37
38 return {
39 name: path.relative(rootpath, path.resolve(rootpath, file.file)).split(path.sep).join('/'),
40 source,
41 coverage,
42 branches
43 };
44};
45
46const cleanFilePath = file => {
47 if (file.includes('!')) {
48 const regex = /^(.*!)(.*)$/g;
49 const matches = regex.exec(file);
50 return matches[matches.length - 1];
51 }
52
53 return file;
54};
55
56const convertLcovToCoveralls = (input, options, cb) => {
57 let filepath = options.filepath || '';
58 logger.debug('in: ', filepath);
59 filepath = path.resolve(process.cwd(), filepath);
60 lcovParse(input, (err, parsed) => {
61 if (err) {
62 logger.error('error from lcovParse: ', err);
63 logger.error('input: ', input);
64 return cb(err);
65 }
66
67 const postJson = {
68 source_files: []
69 };
70
71 if (options.flag_name) {
72 postJson.flag_name = options.flag_name;
73 }
74
75 if (options.git) {
76 postJson.git = options.git;
77 }
78
79 if (options.run_at) {
80 postJson.run_at = options.run_at;
81 }
82
83 if (options.service_name) {
84 postJson.service_name = options.service_name;
85 }
86
87 if (options.service_number) {
88 postJson.service_number = options.service_number;
89 }
90
91 if (options.service_job_id) {
92 postJson.service_job_id = options.service_job_id;
93 }
94
95 if (options.service_job_number) {
96 postJson.service_job_number = options.service_job_number;
97 }
98
99 if (options.service_pull_request) {
100 postJson.service_pull_request = options.service_pull_request;
101 }
102
103 if (options.repo_token) {
104 postJson.repo_token = options.repo_token;
105 }
106
107 if (options.parallel) {
108 postJson.parallel = options.parallel;
109 }
110
111 parsed.forEach(file => {
112 file.file = cleanFilePath(file.file);
113 const currentFilePath = path.resolve(filepath, file.file);
114 if (fs.existsSync(currentFilePath)) {
115 postJson.source_files.push(convertLcovFileObject(file, filepath));
116 }
117 });
118
119 return cb(null, postJson);
120 });
121};
122
123module.exports = convertLcovToCoveralls;
124
125/* example coveralls json file
126
127{
128 "service_job_id": "1234567890",
129 "service_name": "travis-ci",
130 "source_files": [
131 {
132 "name": "example.rb",
133 "source": "def four\n 4\nend",
134 "coverage": [null, 1, null]
135 },
136 {
137 "name": "two.rb",
138 "source": "def seven\n eight\n nine\nend",
139 "coverage": [null, 1, 0, null]
140 }
141 ]
142}
143
144example output from lcov parser:
145
146[
147 {
148 "file": "index.js",
149 "lines": {
150 "found": 0,
151 "hit": 0,
152 "details": [
153 {
154 "line": 1,
155 "hit": 1
156 },
157 {
158 "line": 2,
159 "hit": 1
160 },
161 {
162 "line": 3,
163 "hit": 1
164 },
165 {
166 "line": 5,
167 "hit": 1
168 }
169 ]
170 }
171 }
172]
173
174*/