1 | 'use strict';
|
2 |
|
3 | const fs = require('fs');
|
4 | const path = require('path');
|
5 | const lcovParse = require('lcov-parse');
|
6 | const logger = require('./logger')();
|
7 |
|
8 | const 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 |
|
18 | const 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 |
|
30 | const 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 |
|
46 | const 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 |
|
56 | const 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 |
|
123 | module.exports = convertLcovToCoveralls;
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 |
|
132 |
|
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 |
|
150 |
|
151 |
|
152 |
|
153 |
|
154 |
|
155 |
|
156 |
|
157 |
|
158 |
|
159 |
|
160 |
|
161 |
|
162 |
|
163 |
|
164 |
|
165 |
|
166 |
|
167 |
|
168 |
|
169 |
|
170 |
|
171 |
|
172 |
|
173 |
|
174 |
|