Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/git/index/util.py: 68%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

53 statements  

1# This module is part of GitPython and is released under the 

2# 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ 

3 

4"""Index utilities.""" 

5 

6__all__ = ["TemporaryFileSwap", "post_clear_cache", "default_index", "git_working_dir"] 

7 

8import contextlib 

9from functools import wraps 

10import os 

11import os.path as osp 

12import struct 

13import tempfile 

14from types import TracebackType 

15 

16# typing ---------------------------------------------------------------------- 

17 

18from typing import Any, Callable, TYPE_CHECKING, Optional, Type 

19 

20from git.types import Literal, PathLike, _T 

21 

22if TYPE_CHECKING: 

23 from git.index import IndexFile 

24 

25# --------------------------------------------------------------------------------- 

26 

27# { Aliases 

28pack = struct.pack 

29unpack = struct.unpack 

30# } END aliases 

31 

32 

33class TemporaryFileSwap: 

34 """Utility class moving a file to a temporary location within the same directory and 

35 moving it back on to where on object deletion.""" 

36 

37 __slots__ = ("file_path", "tmp_file_path") 

38 

39 def __init__(self, file_path: PathLike) -> None: 

40 self.file_path = file_path 

41 dirname, basename = osp.split(file_path) 

42 fd, self.tmp_file_path = tempfile.mkstemp(prefix=basename, dir=dirname) 

43 os.close(fd) 

44 with contextlib.suppress(OSError): # It may be that the source does not exist. 

45 os.replace(self.file_path, self.tmp_file_path) 

46 

47 def __enter__(self) -> "TemporaryFileSwap": 

48 return self 

49 

50 def __exit__( 

51 self, 

52 exc_type: Optional[Type[BaseException]], 

53 exc_val: Optional[BaseException], 

54 exc_tb: Optional[TracebackType], 

55 ) -> Literal[False]: 

56 if osp.isfile(self.tmp_file_path): 

57 os.replace(self.tmp_file_path, self.file_path) 

58 return False 

59 

60 

61# { Decorators 

62 

63 

64def post_clear_cache(func: Callable[..., _T]) -> Callable[..., _T]: 

65 """Decorator for functions that alter the index using the git command. 

66 

67 When a git command alters the index, this invalidates our possibly existing entries 

68 dictionary, which is why it must be deleted to allow it to be lazily reread later. 

69 """ 

70 

71 @wraps(func) 

72 def post_clear_cache_if_not_raised(self: "IndexFile", *args: Any, **kwargs: Any) -> _T: 

73 rval = func(self, *args, **kwargs) 

74 self._delete_entries_cache() 

75 return rval 

76 

77 # END wrapper method 

78 

79 return post_clear_cache_if_not_raised 

80 

81 

82def default_index(func: Callable[..., _T]) -> Callable[..., _T]: 

83 """Decorator ensuring the wrapped method may only run if we are the default 

84 repository index. 

85 

86 This is as we rely on git commands that operate on that index only. 

87 """ 

88 

89 @wraps(func) 

90 def check_default_index(self: "IndexFile", *args: Any, **kwargs: Any) -> _T: 

91 if self._file_path != self._index_path(): 

92 raise AssertionError( 

93 "Cannot call %r on indices that do not represent the default git index" % func.__name__ 

94 ) 

95 return func(self, *args, **kwargs) 

96 

97 # END wrapper method 

98 

99 return check_default_index 

100 

101 

102def git_working_dir(func: Callable[..., _T]) -> Callable[..., _T]: 

103 """Decorator which changes the current working dir to the one of the git 

104 repository in order to ensure relative paths are handled correctly.""" 

105 

106 @wraps(func) 

107 def set_git_working_dir(self: "IndexFile", *args: Any, **kwargs: Any) -> _T: 

108 cur_wd = os.getcwd() 

109 os.chdir(str(self.repo.working_tree_dir)) 

110 try: 

111 return func(self, *args, **kwargs) 

112 finally: 

113 os.chdir(cur_wd) 

114 # END handle working dir 

115 

116 # END wrapper 

117 

118 return set_git_working_dir 

119 

120 

121# } END decorators