Converts LCOV format coverage data into the JSON format required by the Coveralls.io API, including source file reading, path normalization, and metadata enrichment.
Parses LCOV coverage data and transforms it into Coveralls.io JSON format with source file content and metadata.
/**
* Convert LCOV coverage data to Coveralls.io JSON format
* @param input - LCOV format coverage data as string
* @param options - Configuration options including CI and Git metadata
* @param callback - Error-first callback with Coveralls JSON data
*/
function convertLcovToCoveralls(
input: string,
options: CoverallsOptions,
callback: (err: Error | null, data?: CoverallsData) => void
): void;
interface CoverallsOptions {
filepath?: string; // Base directory for resolving file paths
service_name?: string; // CI service name (travis-ci, circleci, etc.)
service_number?: string; // Build number
service_job_id?: string; // Job ID
service_job_number?: string; // Job number
service_pull_request?: string; // Pull request number
repo_token?: string; // Repository token for private repos
flag_name?: string; // Flag name for parallel builds
parallel?: boolean; // Enable parallel build mode
run_at?: string; // Timestamp for the build
git?: GitData; // Git metadata
}
interface CoverallsData {
source_files: SourceFile[]; // Array of source files with coverage
service_name?: string;
service_number?: string;
service_job_id?: string;
service_job_number?: string;
service_pull_request?: string;
repo_token?: string;
flag_name?: string;
parallel?: boolean;
run_at?: string;
git?: GitData;
}
interface SourceFile {
name: string; // File path relative to repo root
source: string; // Complete source code content
coverage: (number | null)[]; // Line coverage: null=not executable, number=hit count
branches: number[]; // Branch coverage data as flat array
}
interface GitData {
head: {
id: string; // Commit SHA
author_name?: string; // Commit author name
author_email?: string; // Commit author email
committer_name?: string; // Committer name
committer_email?: string; // Committer email
message?: string; // Commit message
};
branch?: string; // Branch name
remotes?: Array<{ // Git remotes
name: string;
url: string;
}>;
}Usage Examples:
const { convertLcovToCoveralls } = require('coveralls');
const fs = require('fs');
// Basic conversion
const lcovData = fs.readFileSync('./coverage/lcov.info', 'utf8');
const options = {
filepath: process.cwd(),
service_name: 'travis-ci',
service_job_id: '12345'
};
convertLcovToCoveralls(lcovData, options, (err, coverallsData) => {
if (err) {
console.error('Conversion failed:', err);
return;
}
console.log(`Converted ${coverallsData.source_files.length} files`);
console.log('Service:', coverallsData.service_name);
});
// With Git metadata
const optionsWithGit = {
filepath: '/path/to/project',
service_name: 'github-actions',
git: {
head: {
id: 'abc123',
author_name: 'John Doe',
author_email: 'john@example.com',
message: 'Add new feature'
},
branch: 'main'
}
};
convertLcovToCoveralls(lcovData, optionsWithGit, (err, data) => {
if (err) throw err;
console.log('Git branch:', data.git.branch);
console.log('Commit:', data.git.head.id);
});The function expects standard LCOV format input as generated by tools like:
Example LCOV format:
TN:
SF:/path/to/file.js
FN:1,functionName
FNDA:1,functionName
FNF:1
FNH:1
DA:1,1
DA:2,0
DA:3,1
LF:3
LH:2
BRF:0
BRH:0
end_of_recordThe conversion process handles each source file by:
filepath option (defaults to current directory)fs.readFileSync()Line coverage is represented as an array where each index corresponds to a line number (0-based):
null: Line is not executable (comments, empty lines)number: Hit count for the line (0 = not covered, >0 = covered)Branch coverage is flattened into a number array with groups of 4 values:
Common errors and their causes:
convertLcovToCoveralls(lcovData, options, (err, data) => {
if (err) {
if (err.message.includes('lcovParse')) {
// Invalid LCOV format
console.error('LCOV parsing error - check input format');
} else if (err.code === 'ENOENT') {
// Source files not found
console.error('Source files missing - check filepath option');
} else {
console.error('Conversion error:', err.message);
}
return;
}
// Success
});The converter handles various path formats:
! prefixes from webpack loader paths