mirror of
https://github.com/copier-org/copier.git
synced 2025-05-05 15:32:54 +00:00
213 lines
7.0 KiB
Python
213 lines
7.0 KiB
Python
import os
|
|
import shutil
|
|
from collections.abc import Iterator, Sequence
|
|
from pathlib import Path
|
|
from typing import Callable
|
|
|
|
import pytest
|
|
from packaging.version import Version
|
|
from plumbum import local
|
|
|
|
from copier import run_copy, run_update
|
|
from copier._main import Worker
|
|
from copier._user_data import load_answersfile_data
|
|
from copier._vcs import checkout_latest_tag, clone, get_git_version, get_repo
|
|
from copier.errors import ShallowCloneWarning
|
|
|
|
from .helpers import git
|
|
|
|
|
|
def test_get_repo() -> None:
|
|
get = get_repo
|
|
|
|
assert get("git@git.myproject.org:MyProject") == "git@git.myproject.org:MyProject"
|
|
assert (
|
|
get("git://git.myproject.org/MyProject") == "git://git.myproject.org/MyProject"
|
|
)
|
|
assert (
|
|
get("https://github.com/jpscaletti/copier.git")
|
|
== "https://github.com/jpscaletti/copier.git"
|
|
)
|
|
|
|
assert (
|
|
get("https://github.com/jpscaletti/copier")
|
|
== "https://github.com/jpscaletti/copier.git"
|
|
)
|
|
assert (
|
|
get("https://gitlab.com/gitlab-org/gitlab")
|
|
== "https://gitlab.com/gitlab-org/gitlab.git"
|
|
)
|
|
|
|
assert (
|
|
get("gh:/jpscaletti/copier.git") == "https://github.com/jpscaletti/copier.git"
|
|
)
|
|
assert get("gh:jpscaletti/copier.git") == "https://github.com/jpscaletti/copier.git"
|
|
assert get("gl:jpscaletti/copier.git") == "https://gitlab.com/jpscaletti/copier.git"
|
|
assert get("gh:jpscaletti/copier") == "https://github.com/jpscaletti/copier.git"
|
|
assert get("gl:jpscaletti/copier") == "https://gitlab.com/jpscaletti/copier.git"
|
|
|
|
assert (
|
|
get("git+https://git.myproject.org/MyProject")
|
|
== "https://git.myproject.org/MyProject"
|
|
)
|
|
assert (
|
|
get("git+ssh://git.myproject.org/MyProject")
|
|
== "ssh://git.myproject.org/MyProject"
|
|
)
|
|
|
|
assert get("git://git.myproject.org/MyProject.git@master")
|
|
assert get("git://git.myproject.org/MyProject.git@v1.0")
|
|
assert get("git://git.myproject.org/MyProject.git@da39a3ee5e6b4b0d3255bfef956018")
|
|
|
|
assert get("http://google.com") is None
|
|
assert get("git.myproject.org/MyProject") is None
|
|
assert get("https://google.com") is None
|
|
|
|
assert (
|
|
get("tests/demo_updatediff_repo.bundle") == "tests/demo_updatediff_repo.bundle"
|
|
)
|
|
|
|
|
|
@pytest.mark.impure
|
|
def test_clone() -> None:
|
|
tmp = clone("https://github.com/copier-org/copier.git")
|
|
assert tmp
|
|
assert Path(tmp, "README.md").exists()
|
|
shutil.rmtree(tmp, ignore_errors=True)
|
|
|
|
|
|
@pytest.mark.impure
|
|
def test_local_clone() -> None:
|
|
tmp = clone("https://github.com/copier-org/copier.git")
|
|
assert tmp
|
|
assert Path(tmp, "README.md").exists()
|
|
|
|
local_tmp = clone(tmp)
|
|
assert local_tmp
|
|
assert Path(local_tmp, "README.md").exists()
|
|
shutil.rmtree(local_tmp, ignore_errors=True)
|
|
|
|
|
|
@pytest.mark.impure
|
|
def test_shallow_clone(tmp_path: Path, recwarn: pytest.WarningsRecorder) -> None:
|
|
# This test should always work but should be much slower if `is_git_shallow_repo()` is not
|
|
# checked in `clone()`.
|
|
src_path = str(tmp_path / "autopretty")
|
|
git("clone", "--depth=2", "https://github.com/copier-org/autopretty.git", src_path)
|
|
assert Path(src_path, "README.md").exists()
|
|
|
|
if get_git_version() >= Version("2.27"):
|
|
with pytest.warns(ShallowCloneWarning):
|
|
local_tmp = clone(str(src_path))
|
|
else:
|
|
assert len(recwarn) == 0
|
|
local_tmp = clone(str(src_path))
|
|
assert len(recwarn) == 0
|
|
assert local_tmp
|
|
assert Path(local_tmp, "README.md").exists()
|
|
shutil.rmtree(local_tmp, ignore_errors=True)
|
|
|
|
|
|
@pytest.mark.impure
|
|
def test_removes_temporary_clone(tmp_path: Path) -> None:
|
|
src_path = "https://github.com/copier-org/autopretty.git"
|
|
with Worker(
|
|
src_path=src_path, dst_path=tmp_path, defaults=True, unsafe=True
|
|
) as worker:
|
|
worker.run_copy()
|
|
temp_clone = worker.template.local_abspath
|
|
assert not temp_clone.exists()
|
|
|
|
|
|
@pytest.mark.impure
|
|
def test_dont_remove_local_clone(tmp_path: Path) -> None:
|
|
src_path = str(tmp_path / "autopretty")
|
|
git("clone", "https://github.com/copier-org/autopretty.git", src_path)
|
|
with Worker(
|
|
src_path=src_path, dst_path=tmp_path, defaults=True, unsafe=True
|
|
) as worker:
|
|
worker.run_copy()
|
|
assert Path(src_path).exists()
|
|
|
|
|
|
@pytest.mark.impure
|
|
def test_update_using_local_source_path_with_tilde(tmp_path: Path) -> None:
|
|
# first, get a local repository clone
|
|
src_path = str(tmp_path / "autopretty")
|
|
git("clone", "https://github.com/copier-org/autopretty.git", src_path)
|
|
|
|
# then prepare the user path to this clone (starting with ~)
|
|
if os.name == "nt":
|
|
# in GitHub CI, the user in the temporary path is not the same as the current user:
|
|
# ["C:\\", "Users", "RUNNER~X"] vs. runneradmin
|
|
user = Path(src_path).parts[2]
|
|
user_src_path = str(Path("~", "..", user, *Path(src_path).parts[3:]))
|
|
else:
|
|
# temporary path is in /tmp, so climb back up from ~ using ../
|
|
user_src_path = f"~/{'/'.join(['..'] * len(Path.home().parts))}{src_path}"
|
|
|
|
# generate project and assert correct path in answers
|
|
worker = run_copy(
|
|
src_path=user_src_path, dst_path=tmp_path, defaults=True, unsafe=True
|
|
)
|
|
assert worker.answers.combined["_src_path"] == user_src_path
|
|
|
|
# assert project update works and correct path again
|
|
with local.cwd(tmp_path):
|
|
git("init")
|
|
git("add", "-A")
|
|
git("commit", "-m", "init")
|
|
worker = run_update(
|
|
dst_path=tmp_path,
|
|
defaults=True,
|
|
overwrite=True,
|
|
answers_file=".copier-answers.autopretty.yml",
|
|
unsafe=True,
|
|
)
|
|
assert worker.answers.combined["_src_path"] == user_src_path
|
|
|
|
|
|
def test_invalid_version(tmp_path: Path) -> None:
|
|
sample = tmp_path / "sample.txt"
|
|
with local.cwd(tmp_path):
|
|
git("init")
|
|
sample.write_text("1")
|
|
git("add", sample)
|
|
git("commit", "-m1")
|
|
git("tag", "not-a-version")
|
|
sample.write_text("2")
|
|
git("commit", "-am2")
|
|
git("tag", "v2")
|
|
sample.write_text("3")
|
|
git("commit", "-am3")
|
|
assert git("describe", "--tags").strip() != "v2"
|
|
checkout_latest_tag(tmp_path)
|
|
assert git("describe", "--tags").strip() == "v2"
|
|
|
|
|
|
@pytest.mark.parametrize("sorter", [iter, reversed])
|
|
def test_select_latest_version_tag(
|
|
tmp_path_factory: pytest.TempPathFactory,
|
|
sorter: Callable[[Sequence[str]], Iterator[str]],
|
|
) -> None:
|
|
src, dst = map(tmp_path_factory.mktemp, ("src", "dst"))
|
|
filename = "version.txt"
|
|
|
|
with local.cwd(src):
|
|
git("init")
|
|
Path("{{ _copier_conf.answers_file }}.jinja").write_text(
|
|
"{{ _copier_answers|to_nice_yaml }}"
|
|
)
|
|
for version in sorter(["v1", "v1.0", "v1.0.0", "v1.0.1"]):
|
|
Path(filename).write_text(version)
|
|
git("add", ".")
|
|
git("commit", "-m", version)
|
|
git("tag", version)
|
|
|
|
run_copy(str(src), dst)
|
|
|
|
assert (dst / filename).is_file()
|
|
assert (dst / filename).read_text() == "v1.0.1"
|
|
answers = load_answersfile_data(dst)
|
|
assert answers["_commit"] == "v1.0.1"
|