summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stefw@gnome.org>2012-11-26 10:13:40 +0100
committerStef Walter <stefw@gnome.org>2012-11-29 14:28:11 +0100
commite7c196831519330a98b02455b6f86f2e322927f8 (patch)
tree176007b3cd48e2dbe3e5a9affc858d5748d9190e
parent4516ca05b983aecedae5570ad39f46398370a866 (diff)
Don't assume gcc was run in same directory as source
gcov needs to be run in the same directory as gcc was run in order to find the source files correctly. We use gcov with --no-output to report which directory this is for given gcno files.
-rwxr-xr-xgit-coverage41
1 files changed, 32 insertions, 9 deletions
diff --git a/git-coverage b/git-coverage
index 1e5889b..f9c22f1 100755
--- a/git-coverage
+++ b/git-coverage
@@ -223,7 +223,8 @@ class GccCoverage:
def __init__(self, skips):
self._gcno_cache = []
- self._creating_re = re.compile(".*'(.+\.gcov)'.*")
+ self._creating_re = re.compile("^.*'(.+\.gcov)'$")
+ self._file_re = re.compile("^File.*'(.+)'$")
self._skips = skips
def visit(paths, dirname, names):
@@ -252,20 +253,41 @@ class GccCoverage:
matches.append(gcno)
return matches
+ def _find_directory_gcno_compiled_in(self, gcno, filename):
+ cmd = ['gcov', '--preserve-paths', '--relative-only', '--no-output']
+ for line in subprocess_lines(cmd + gcno):
+ match = self._file_re.match(line.strip())
+ if not match:
+ continue
+ expected = match.group(1)
+ if filename.endswith(expected):
+ extra = filename[:-len(expected)]
+ if os.path.exists(extra):
+ return extra
+ elif expected.endswith(filename):
+ extra = expected[:-len(filename)]
+ up = "../" * len(extra.strip(os.sep).split(os.sep))
+ if os.path.exists(up):
+ return up
+ return None
+
def _gcov_lines_for_files(self, filename):
gcno = self._match_gcno_files(filename)
if not gcno:
return
- # gcov wants to be in the directory with the source files
- # so we make all the gcno paths absolute and change to that
- # directory
-
absgcno = [os.path.abspath(path) for path in gcno]
- (directory, base) = os.path.split(filename)
- oldpwd = os.getcwd()
+ # gcov wants to be in the directory that gcc was executed
+ # from. We don't know which directory that is. So we run
+ # gcov once to figure out the file path it thinks the source
+ # is at.
+
+ directory = self._find_directory_gcno_compiled_in(absgcno, filename)
+
+ oldcwd = None
if directory:
+ oldcwd = os.getcwd()
os.chdir(directory)
# We scrape the output of the command for the names of the
@@ -274,7 +296,7 @@ class GccCoverage:
cmd = ['gcov', '--preserve-paths', '--relative-only']
for line in subprocess_lines(cmd + absgcno):
- match = self._creating_re.match(line)
+ match = self._creating_re.match(line.strip())
if not match:
continue
gcov = match.group(1)
@@ -284,7 +306,8 @@ class GccCoverage:
# Because we change the directory, we have to take care not
# to yield while the current directory is changed
- os.chdir(oldpwd)
+ if oldcwd:
+ os.chdir(oldcwd)
for gcov in gcovs:
with open(gcov, 'r') as f: