Coverage for src / template / methods / git.py: 90%

40 statements  

« prev     ^ index     » next       coverage.py v7.12.0, created at 2025-11-21 16:36 +0000

1import atexit 

2import os 

3import shutil 

4import subprocess 

5import sys 

6import tempfile 

7 

8from . import directory 

9 

10 

11def _get_git(): 

12 retval = shutil.which("git") 

13 if retval is None: 13 ↛ 14line 13 didn't jump to line 14 because the condition on line 13 was never true

14 print('warning: "git" executable was not found', file=sys.stderr) 

15 return retval 

16 

17 

18def _get_tmpdir(): 

19 """ 

20 Create a temporary folder to be deleted at exit 

21 """ 

22 tmpdir = tempfile.mkdtemp(prefix="scaffold-git-") 

23 

24 def remove_tmpdir(): 

25 shutil.rmtree(tmpdir) 

26 

27 atexit.register(remove_tmpdir) 

28 return tmpdir 

29 

30 

31def _clone(tpl): 

32 git = _get_git() 

33 tmpdir = _get_tmpdir() 

34 

35 path = tpl.path 

36 cmdline = [git, "clone", "--single-branch"] 

37 if tpl.branch: 

38 cmdline += ["--branch", tpl.branch] 

39 if os.path.exists(tpl.path) and os.path.isdir(tpl.path): 

40 # This is a local repository and git prefers with the 

41 # "file://" 

42 path = f"file://{tpl.path}" 

43 else: 

44 cmdline += ["--depth", "1"] 

45 cmdline += [path, "repository"] 

46 

47 try: 

48 subprocess.run(cmdline, cwd=tmpdir, check=True) 

49 except subprocess.CalledProcessError as err: 

50 sys.exit(f'error: failed to clone git repository "{tpl.path}": {err}') 

51 

52 dirpath = os.path.join(tmpdir, "repository") 

53 return directory.accept(tpl, dirpath) 

54 

55 

56def find(tpl): 

57 """ 

58 path can be a remote git+ssh, or git+http, or even a local path 

59 if branch is None, we checkout the default branch, usually main or master 

60 """ 

61 git = _get_git() 

62 if not git: 62 ↛ 63line 62 didn't jump to line 63 because the condition on line 62 was never true

63 return False 

64 return _clone(tpl)