Coverage for r11k/gitutil.py: 76%

25 statements  

« prev     ^ index     » next       coverage.py v7.2.1, created at 2023-03-13 23:53 +0100

1"""Various minor utilities for git repos.""" 

2 

3from datetime import datetime 

4import os 

5import os.path 

6import subprocess 

7from typing import ( 

8 Optional, 

9) 

10 

11import pygit2 

12 

13 

14def repo_last_fetch(repo: pygit2.Repository) -> datetime: 

15 """ 

16 When was a fetch last perfermed on this repo. 

17 

18 :raises: `FileNotFoundError` if no suitable HEAD could be found. 

19 """ 

20 files = [ 

21 os.path.join(repo.path, 'FETCH_HEAD'), 

22 os.path.join(repo.path, 'HEAD'), 

23 ] 

24 for fetch_head in files: 24 ↛ 30line 24 didn't jump to line 30, because the loop on line 24 didn't complete

25 try: 

26 head_stat = os.stat(fetch_head).st_mtime 

27 return datetime.utcfromtimestamp(head_stat) 

28 except FileNotFoundError: 

29 pass 

30 raise FileNotFoundError(f"No suitable head for repo {repo}") 

31 

32 

33def find_remote(remotes: pygit2.remote.RemoteCollection, 

34 target_url: str) -> Optional[pygit2.remote.Remote]: 

35 """Find the remote matching the given url.""" 

36 for remote in remotes: 36 ↛ 39line 36 didn't jump to line 39, because the loop on line 36 didn't complete

37 if target_url == remote.url: 37 ↛ 36line 37 didn't jump to line 36, because the condition on line 37 was never false

38 return remote 

39 return None 

40 

41 

42def checkout(repo: pygit2.Repository, 

43 refspec: str, 

44 force: bool = False) -> None: 

45 """ 

46 Run gits porecalin checkout. 

47 

48 Shells out to git checkout. 

49 

50 git-checkout(1) allows us to give a reference on any form, 

51 including a commit hash, and a non-local branch (e.g. 

52 origin/master). Proper checkout would be something like 

53 >>> repo.checkout(f'refs/remotes/origin/{self.version}') 

54 >>> repo.checkout(self.version) 

55 """ 

56 cmdline = ['git', 'checkout', '--quiet', refspec] 

57 if force: 57 ↛ 59line 57 didn't jump to line 59, because the condition on line 57 was never false

58 cmdline += ['--force'] 

59 subprocess.run(cmdline, 

60 check=True, 

61 cwd=repo.workdir)