1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
"""
Converter for `git diff` paths
"""
import os
import sys
from diff_cover.command_runner import execute
from diff_cover.util import to_unix_path
class GitPathTool:
"""
Converts `git diff` paths to absolute paths or relative paths to cwd.
This class should be used throughout the project to change paths from
the paths yielded by `git diff` to correct project paths
"""
_cwd = None
_root = None
@classmethod
def set_cwd(cls, cwd):
"""
Set the cwd that is used to manipulate paths.
"""
if not cwd:
cwd = os.getcwd()
if isinstance(cwd, bytes):
cwd = cwd.decode(sys.getdefaultencoding())
cls._cwd = cwd
cls._root = cls._git_root()
@classmethod
def relative_path(cls, git_diff_path):
"""
Returns git_diff_path relative to cwd.
"""
# If GitPathTool hasn't been initialized, return the path unchanged
if cls._cwd is None or cls._root is None:
return git_diff_path
# Remove git_root from src_path for searching the correct filename
# If cwd is `/home/user/work/diff-cover/diff_cover`
# and src_path is `diff_cover/violations_reporter.py`
# search for `violations_reporter.py`
root_rel_path = os.path.relpath(cls._cwd, cls._root)
return os.path.relpath(git_diff_path, root_rel_path)
@classmethod
def absolute_path(cls, src_path):
"""
Returns absolute git_diff_path
"""
# If cwd is `/home/user/work/diff-cover/diff_cover`
# and src_path is `other_package/some_file.py`
# search for `/home/user/work/diff-cover/other_package/some_file.py`
return to_unix_path(os.path.join(cls._root, src_path))
@classmethod
def _git_root(cls):
"""
Returns the output of `git rev-parse --show-toplevel`, which
is the absolute path for the git project root.
"""
command = ["git", "rev-parse", "--show-toplevel", "--encoding=utf-8"]
git_root = execute(command)[0]
return git_root.split("\n", maxsplit=1)[0] if git_root else ""
|