diff options
author | Stef Walter <stefw@gnome.org> | 2012-11-26 10:13:40 +0100 |
---|---|---|
committer | Stef Walter <stefw@gnome.org> | 2012-11-29 14:28:11 +0100 |
commit | e7c196831519330a98b02455b6f86f2e322927f8 (patch) | |
tree | 176007b3cd48e2dbe3e5a9affc858d5748d9190e | |
parent | 4516ca05b983aecedae5570ad39f46398370a866 (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-x | git-coverage | 41 |
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: |