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
« 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
8from . import directory
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
18def _get_tmpdir():
19 """
20 Create a temporary folder to be deleted at exit
21 """
22 tmpdir = tempfile.mkdtemp(prefix="scaffold-git-")
24 def remove_tmpdir():
25 shutil.rmtree(tmpdir)
27 atexit.register(remove_tmpdir)
28 return tmpdir
31def _clone(tpl):
32 git = _get_git()
33 tmpdir = _get_tmpdir()
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"]
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}')
52 dirpath = os.path.join(tmpdir, "repository")
53 return directory.accept(tpl, dirpath)
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)