From f0b5a3625258b6c6f316aa0bc2ff343b1b70a017 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Sat, 14 Jan 2017 18:59:43 -0500 Subject: [PATCH] add FileCoverage and GcovParser to begin parsing .gcov files --- lib/gcovinator.rb | 20 ++++++++++++++------ lib/gcovinator/file_coverage.rb | 4 ++++ lib/gcovinator/gcov_parser.rb | 28 ++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 lib/gcovinator/file_coverage.rb create mode 100644 lib/gcovinator/gcov_parser.rb diff --git a/lib/gcovinator.rb b/lib/gcovinator.rb index 230def9..877c29b 100644 --- a/lib/gcovinator.rb +++ b/lib/gcovinator.rb @@ -1,26 +1,34 @@ +require_relative "gcovinator/file_coverage" +require_relative "gcovinator/gcov_parser" require_relative "gcovinator/version" require "tmpdir" +require "open3" +require "pathname" module Gcovinator class << self def run(build_dir, source_dirs, files, output_dir) - build_dir = File.expand_path(build_dir) + build_dir = Pathname.new(File.expand_path(build_dir)).cleanpath.to_s source_dirs = ["."] if source_dirs.empty? source_dirs = source_dirs.map do |s| - File.expand_path(s) + Pathname.new(File.expand_path(s)).cleanpath.to_s end files = Dir["#{build_dir}/**/*.gcda"] if files.empty? files = files.map do |f| - File.expand_path(f) + Pathname.new(File.expand_path(f)).cleanpath.to_s end - output_dir = File.expand_path(output_dir) + output_dir = Pathname.new(File.expand_path(output_dir)).cleanpath.to_s + file_coverages = {} Dir.mktmpdir do |dir| Dir.chdir(dir) do files.each do |f| - IO.popen(["gcov", "-bmi", f]) do |io| - io.read + stdout, stderr, status = Open3.capture3("gcov", "-bc", f) + gcov_files = Dir["*.gcov"] + gcov_files.each do |gcov_file| + GcovParser.parse(gcov_file, file_coverages, build_dir, source_dirs) + File.unlink(gcov_file) end end end diff --git a/lib/gcovinator/file_coverage.rb b/lib/gcovinator/file_coverage.rb new file mode 100644 index 0000000..fc4d449 --- /dev/null +++ b/lib/gcovinator/file_coverage.rb @@ -0,0 +1,4 @@ +module Gcovinator + class FileCoverage + end +end diff --git a/lib/gcovinator/gcov_parser.rb b/lib/gcovinator/gcov_parser.rb new file mode 100644 index 0000000..71ad4f7 --- /dev/null +++ b/lib/gcovinator/gcov_parser.rb @@ -0,0 +1,28 @@ +module Gcovinator + module GcovParser + class << self + + def parse(gcov_file, file_coverages, build_dir, source_dirs) + gcov_file = File.read(gcov_file) + file_coverage = nil + gcov_file.each_line do |line| + if line =~ /^\s+\S*:\s*\d*:Source:(.*)$/ + filename = $1 + unless Pathname.new(filename).absolute? + filename = Pathname.new(File.join(build_dir, filename)).cleanpath.to_s + end + filename = filename.gsub("\\", "/") + unless source_dirs.any? {|s| filename.start_with?("#{s}/")} + return + end + file_coverages[filename] ||= FileCoverage.new + file_coverage = file_coverages[filename] + next + end + next unless file_coverage + end + end + + end + end +end