Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion copier/_vcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,19 @@ def get_latest_tag(url: str, use_prereleases: OptBool = False) -> str:
The latest git tag, or `HEAD` if no valid tags are found.
"""
git = get_git()
try:
tags_output = git("ls-remote", "--tags", "--refs", url)
except ProcessExecutionError:
print(
colors.warn
| "Could not list remote tags from template; using HEAD as ref",
file=sys.stderr,
)
return "HEAD"

all_tags = (
tag.split("\t", 1)[1].removeprefix("refs/tags/")
for tag in git("ls-remote", "--tags", "--refs", url).splitlines()
for tag in tags_output.splitlines()
)
all_tags = (tag for tag in all_tags if valid_version(tag))
if not use_prereleases:
Expand Down
17 changes: 16 additions & 1 deletion tests/test_vcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@
from copier import run_copy, run_update
from copier._main import Worker
from copier._user_data import load_answersfile_data
from copier._vcs import clone, get_git_version, get_latest_tag, get_repo
from copier._vcs import (
ProcessExecutionError,
clone,
get_git_version,
get_latest_tag,
get_repo,
)
from copier.errors import DirtyLocalWarning, ShallowCloneWarning

from .helpers import build_file_tree, git, git_save
Expand Down Expand Up @@ -213,6 +219,15 @@ def test_invalid_version(tmp_path: Path) -> None:
assert get_latest_tag(str(tmp_path)) == "v2"


def test_get_latest_tag_falls_back_to_head_on_ls_remote_error() -> None:
mock_git = mock.MagicMock(
side_effect=ProcessExecutionError(["git", "ls-remote"], 128, "", "auth")
)

with mock.patch("copier._vcs.get_git", return_value=mock_git):
assert get_latest_tag("https://x-access-token:token@github.com/org/private.git") == "HEAD"


@pytest.mark.parametrize("sorter", [iter, reversed])
def test_select_latest_version_tag(
tmp_path_factory: pytest.TempPathFactory,
Expand Down