var TRAVIS_JOB_ID = process.env.TRAVIS_JOB_ID || 'unknown'; var fs = require('fs'); var lcovParse = require('lcov-parse'); var path = require('path'); var logger = require('./logger')(); var detailsToCoverage = function(length, details){ var coverage = new Array(length); details.forEach(function(obj){ coverage[obj.line - 1] = obj.hit; }); return coverage; }; var detailsToBranches = function(details){ var branches = []; details.forEach(function(obj){ ['line','block','branch','taken'].forEach(function(key){ branches.push(obj[key] || 0); }); }); return branches; }; var convertLcovFileObject = function(file, filepath){ var rootpath = filepath; filepath = path.resolve(rootpath, file.file); var source = fs.readFileSync(filepath, 'utf8'); var lines = source.split("\n"); var coverage = detailsToCoverage(lines.length, file.lines.details); var branches = detailsToBranches(file.branches.details); return { name : path.relative(rootpath, path.resolve(rootpath, file.file)).split( path.sep ).join( "/" ), source : source, coverage : coverage, branches : branches }; }; var cleanFilePath = function(file) { if (file.indexOf('!') > -1) { var regex = /^(.*!)(.*)$/g; var matches = regex.exec(file); return matches[matches.length-1]; } return file; }; var convertLcovToCoveralls = function(input, options, cb){ var filepath = options.filepath || ''; logger.debug("in: ", filepath); filepath = path.resolve(process.cwd(), filepath); lcovParse(input, function(err, parsed){ if (err){ logger.error("error from lcovParse: ", err); logger.error("input: ", input); return cb(err); } var postJson = { source_files : [] }; if (options.git){ postJson.git = options.git; } if (options.run_at){ postJson.run_at = options.run_at; } if (options.service_name){ postJson.service_name = options.service_name; } if (options.service_job_id){ postJson.service_job_id = options.service_job_id; } if (options.service_pull_request) { postJson.service_pull_request = options.service_pull_request; } if (options.repo_token) { postJson.repo_token = options.repo_token; } if (options.parallel) { postJson.parallel = options.parallel; } if (options.service_pull_request) { postJson.service_pull_request = options.service_pull_request; } parsed.forEach(function(file){ file.file = cleanFilePath(file.file); var currentFilePath = path.resolve(filepath, file.file); if (fs.existsSync(currentFilePath)) { postJson.source_files.push(convertLcovFileObject(file, filepath)); } }); return cb(null, postJson); }); }; module.exports = convertLcovToCoveralls; /* example coveralls json file { "service_job_id": "1234567890", "service_name": "travis-ci", "source_files": [ { "name": "example.rb", "source": "def four\n 4\nend", "coverage": [null, 1, null] }, { "name": "two.rb", "source": "def seven\n eight\n nine\nend", "coverage": [null, 1, 0, null] } ] } example output from lcov parser: [ { "file": "index.js", "lines": { "found": 0, "hit": 0, "details": [ { "line": 1, "hit": 1 }, { "line": 2, "hit": 1 }, { "line": 3, "hit": 1 }, { "line": 5, "hit": 1 }, */