Skip to content

gittable.download

download

download(
    repo: str,
    files: collections.abc.Iterable[str] = ("**",),
    directory: pathlib.Path | str | None = None,
    branch: str = "",
    user: str = "",
    password: str = "",
) -> list[str]

Download files from a git repository and return a list of the files downloaded.

Parameters:

  • repo (str) –

    A git URL, as you would pass to git clone

  • files (collections.abc.Iterable[str], default: ('**',) ) –

    One or more glob patterns or relative file paths

  • directory (pathlib.Path | str | None, default: None ) –

    The target directory (if not provided, the current directory is used)

  • branch (str, default: '' ) –

    A branch from which to retrieve (if not provided, files will be retrieved from HEAD)

  • user (str, default: '' ) –
  • password (str, default: '' ) –
Source code in src/gittable/download.py
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
def download(
    repo: str,
    files: Iterable[str] = ("**",),
    directory: Path | str | None = None,
    branch: str = "",
    user: str = "",
    password: str = "",
) -> list[str]:
    """
    Download files from a git repository and return a list of the files
    downloaded.

    Parameters:
        repo: A git URL, as you would pass to `git clone`
        files: One or more
            [glob patterns](https://docs.python.org/3/library/glob.html)
            or relative file paths
        directory: The target directory (if not provided, the current
            directory is used)
        branch: A branch from which to retrieve (if not provided,
            files will be retrieved from HEAD)
        user:
        password:
    """
    if isinstance(files, str):
        files = (files,)
    if directory:
        if isinstance(directory, Path):
            directory = str(directory.absolute())
        else:
            directory = os.path.abspath(directory)
    else:
        directory = os.path.abspath(os.path.curdir)
    if user or password:
        repo = update_url_user_password(repo, user, password)
    # Shallow clone into a temp directory
    temp_directory: str = mkdtemp(prefix="git_download_")
    check_call(
        ("git", "clone", "-q", "--depth", "1", "--single-branch")
        + (("-b", branch) if branch else ())
        + (repo, temp_directory)
    )
    # Remove the git directory, so those files aren't accidentally matched
    rmtree(os.path.join(temp_directory, ".git"), ignore_errors=True)
    current_directory: str = os.path.abspath(os.path.curdir)
    path: str
    try:
        os.chdir(temp_directory)
        matched_files: tuple[str, ...] = tuple(
            filter(
                os.path.isfile,
                (
                    os.path.join(
                        temp_directory,
                        path,
                    )
                    for path in chain(*map(_iglob_recursive, files))
                ),
            )
        )
    finally:
        os.chdir(current_directory)
    downloaded_paths: list[str] = []
    new_path: str
    for path in matched_files:
        relative_path: str = os.path.relpath(path, temp_directory)
        new_path = os.path.join(directory, relative_path)
        if os.path.sep in relative_path:
            os.makedirs(os.path.dirname(new_path), exist_ok=True)
        move(path, new_path)
        downloaded_paths.append(new_path)
    rmtree(temp_directory, ignore_errors=True)
    return downloaded_paths