blob: 5bac98e80d8c3b165a70131aafd2f3856a919b44 [file] [log] [blame]
// Copyright 2016 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.lcovmerger;
import static com.google.devtools.lcovmerger.LcovConstants.TRACEFILE_EXTENSION;
import com.google.common.annotations.VisibleForTesting;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Command line utility to convert raw coverage files to lcov (text) format.
*/
public class Main {
private static final Logger logger = Logger.getLogger(Main.class.getName());
public static void main(String[] args) {
Map<String, String> flags = null;
try {
flags = parseFlags(args);
} catch (IllegalArgumentException e) {
logger.log(Level.SEVERE, e.getMessage());
System.exit(1);
}
List<File> lcovTracefiles = getLcovTracefiles(flags.get("coverage_dir"));
if (lcovTracefiles.isEmpty()) {
logger.log(Level.SEVERE, "No lcov file found.");
System.exit(1);
}
Coverage coverage = new Coverage();
for (File tracefile : lcovTracefiles) {
try {
List<SourceFileCoverage> sourceFilesCoverage =
LcovParser.parse(new FileInputStream(tracefile));
for (SourceFileCoverage sourceFileCoverage : sourceFilesCoverage) {
coverage.add(sourceFileCoverage);
}
} catch (IOException e) {
logger.log(Level.SEVERE, "Tracefile " + tracefile.getAbsolutePath() + " was deleted");
System.exit(1);
}
}
int exitStatus = 0;
String outputFile = flags.get("output_file");
try {
File coverageFile = new File(outputFile);
LcovPrinter.print(new FileOutputStream(coverageFile), coverage);
} catch (IOException e) {
logger.log(Level.SEVERE, "Could not write to output file " + outputFile);
exitStatus = 1;
}
System.exit(exitStatus);
}
/**
* Returns a list of all the files with a “.dat” extension found recursively under the given
* directory.
*/
@VisibleForTesting
static List<File> getLcovTracefiles(String coverageDir) {
List<File> datFiles = new ArrayList<>();
try (Stream<Path> stream = Files.walk(Paths.get(coverageDir))) {
datFiles = stream.filter(p -> p.toString().endsWith(TRACEFILE_EXTENSION))
.map(path -> path.toFile())
.collect(Collectors.toList());
} catch (IOException ex) {
logger.log(Level.SEVERE, "error reading folder " + coverageDir + ": " + ex.getMessage());
}
return datFiles;
}
/**
* Parse flags in the form of "--coverage_dir=... -output_file=..."
*/
private static Map<String, String> parseFlags(String[] args) {
Map<String, String> flags = new HashMap<>();
for (String arg : args) {
if (!arg.startsWith("--")) {
throw new IllegalArgumentException("Argument (" + arg + ") should start with --");
}
String[] parts = arg.substring(2).split("=", 2);
if (parts.length != 2) {
throw new IllegalArgumentException("There should be = in argument (" + arg + ")");
}
flags.put(parts[0], parts[1]);
}
// Validate flags
if (!flags.containsKey("coverage_dir")) {
throw new IllegalArgumentException("coverage_dir was not specified");
}
if (!flags.containsKey("output_file")) {
// Different from blaze, this should be mandatory
throw new IllegalArgumentException("output_file was not specified");
}
return flags;
}
}