Coverage for sel_tools/utils/repo.py: 100%

38 statements  

« prev     ^ index     » next       coverage.py v7.6.4, created at 2024-11-04 21:22 +0000

1"""Repository utilities.""" 

2 

3import subprocess 

4from dataclasses import dataclass 

5from pathlib import Path 

6 

7import git 

8from gitlab.v4.objects.projects import Project 

9 

10from sel_tools.config import GIT_MAIN_BRANCH 

11 

12 

13@dataclass(frozen=True) 

14class GitlabProject: 

15 """Helper class for local gitlab project.""" 

16 

17 local_path: Path 

18 gitlab_project: Project 

19 

20 

21class GitRepo: 

22 """Git repository helper class.""" 

23 

24 HTTPS_LEAD = "https://" 

25 

26 class PrintProgress(git.RemoteProgress): 

27 """Write the progress on the console.""" 

28 

29 def line_dropped(self, line: str) -> None: 

30 print(line) 

31 

32 def __init__(self, path: Path, branch: str = GIT_MAIN_BRANCH) -> None: 

33 self.__path = path 

34 self.__branch = branch 

35 

36 @property 

37 def path(self) -> Path: 

38 return self.__path 

39 

40 @property 

41 def branch(self) -> str: 

42 return self.__branch 

43 

44 def is_repo(self) -> bool: 

45 return (self.path / ".git").is_dir() 

46 

47 @staticmethod 

48 def authenticate_http_url(url: str) -> str: 

49 return url.replace(GitRepo.HTTPS_LEAD, f"{GitRepo.HTTPS_LEAD}gitlab-ci-token:$GITLAB_TOKEN@") 

50 

51 def fetch_from(self, url: str) -> None: 

52 # The reason for this process here is to avoid that git writes the token 

53 # into .git/config 

54 self.__path.mkdir(parents=True, exist_ok=True) 

55 if not self.is_repo(): 

56 git.Repo.init(self.path) 

57 subprocess.check_call( 

58 f"git pull {self.authenticate_http_url(url)} {self.__branch}", 

59 shell=True, 

60 cwd=self.path, 

61 ) 

62 

63 def clone(self, url: str) -> None: 

64 git.Repo.clone_from(url, self.path, progress=GitRepo.PrintProgress(), branch=self.__branch) 

65 

66 def pull(self) -> None: 

67 git.Repo(self.path).remote().pull(progress=GitRepo.PrintProgress())