copier/tests/test_dirty_local.py
2025-04-22 13:52:51 +02:00

217 lines
6.1 KiB
Python

from pathlib import Path
from shutil import copy2, copytree
import pytest
from plumbum import local
from pytest_gitconfig.plugin import GitConfig
import copier
from copier._main import run_copy, run_update
from copier.errors import DirtyLocalWarning
from .helpers import DATA, PROJECT_TEMPLATE, build_file_tree, git
def test_copy(tmp_path_factory: pytest.TempPathFactory) -> None:
src, dst = map(tmp_path_factory.mktemp, ("src", "dst"))
for item in PROJECT_TEMPLATE.iterdir():
item_src_path = item
item_dst_path = src / item.name
if item_src_path.is_dir():
copytree(item_src_path, item_dst_path)
else:
copy2(item_src_path, item_dst_path)
with local.cwd(src):
git("init")
with pytest.warns(DirtyLocalWarning):
copier.run_copy(str(src), dst, data=DATA, vcs_ref="HEAD", quiet=True)
generated = (dst / "pyproject.toml").read_text()
control = (Path(__file__).parent / "reference_files" / "pyproject.toml").read_text()
assert generated == control
# assert template still dirty
with local.cwd(src):
assert bool(git("status", "--porcelain").strip())
def test_copy_dirty_head(tmp_path_factory: pytest.TempPathFactory) -> None:
src, dst = map(tmp_path_factory.mktemp, ("src", "dst"))
build_file_tree(
{
src / "tracked": "",
src / "untracked": "",
}
)
with local.cwd(src):
git("init")
git("add", "tracked")
git("commit", "-m1")
with pytest.warns(DirtyLocalWarning):
copier.run_copy(str(src), dst, vcs_ref="HEAD")
assert (dst / "tracked").exists()
assert (dst / "untracked").exists()
def test_copy_dirty_head_with_gpg(
tmp_path_factory: pytest.TempPathFactory, gitconfig: GitConfig
) -> None:
src, dst = map(tmp_path_factory.mktemp, ("src", "dst"))
build_file_tree(
{
src / "tracked": "",
src / "untracked": "",
}
)
with local.cwd(src):
git("init")
git("add", "tracked")
git("commit", "-m1")
gitconfig.set({"user.signinkey": "123456", "commit.gpgsign": "true"})
with pytest.warns(DirtyLocalWarning):
copier.run_copy(str(src), dst, vcs_ref="HEAD")
assert (dst / "tracked").exists()
assert (dst / "untracked").exists()
def test_update(tmp_path_factory: pytest.TempPathFactory) -> None:
src, dst = map(tmp_path_factory.mktemp, ("src", "dst"))
build_file_tree(
{
(src / ".copier-answers.yml.jinja"): (
"""\
# Changes here will be overwritten by Copier
{{ _copier_answers|to_nice_yaml }}
"""
),
(src / "copier.yml"): (
"""\
_envops:
"keep_trailing_newline": True
"""
),
(src / "aaaa.txt"): (
"""
Lorem ipsum
"""
),
(src / "to_delete.txt"): (
"""
delete me.
"""
),
(src / "symlink.txt"): Path("./to_delete.txt"),
}
)
with local.cwd(src):
git("init")
git("add", "-A")
git("commit", "-m", "first commit on src")
run_copy(str(src), dst, defaults=True, overwrite=True)
with local.cwd(src):
# test adding a file
Path("test_file.txt").write_text("Test content")
# test updating a file
with Path("aaaa.txt").open("a") as f:
f.write("dolor sit amet")
# test updating a symlink
Path("symlink.txt").unlink()
Path("symlink.txt").symlink_to("test_file.txt")
# test removing a file
Path("to_delete.txt").unlink()
# dst must be vcs-tracked to use run_update
with local.cwd(dst):
git("init")
git("add", "-A")
git("commit", "-m", "first commit on dst")
# make sure changes have not yet propagated
assert not (dst / "test_file.txt").exists()
assert (src / "aaaa.txt").read_text() != (dst / "aaaa.txt").read_text()
p1 = src / "symlink.txt"
p2 = dst / "symlink.txt"
assert p1.read_text() != p2.read_text()
assert (dst / "to_delete.txt").exists()
with pytest.warns(DirtyLocalWarning):
run_update(dst, defaults=True, overwrite=True)
# make sure changes propagate after update
assert (dst / "test_file.txt").exists()
assert (src / "aaaa.txt").read_text() == (dst / "aaaa.txt").read_text()
p1 = src / "symlink.txt"
p2 = dst / "symlink.txt"
assert p1.read_text() == p2.read_text()
assert not (dst / "symlink.txt").is_symlink()
# HACK https://github.com/copier-org/copier/issues/461
# TODO test file deletion on update
# assert not (dst / "to_delete.txt").exists()
def test_update_with_gpg_sign(
tmp_path_factory: pytest.TempPathFactory, gitconfig: GitConfig
) -> None:
src, dst = map(tmp_path_factory.mktemp, ("src", "dst"))
build_file_tree(
{
(src / ".copier-answers.yml.jinja"): (
"""\
# Changes here will be overwritten by Copier
{{ _copier_answers|to_nice_yaml }}
"""
),
(src / "copier.yml"): (
"""\
_envops:
"keep_trailing_newline": True
"""
),
(src / "aaaa.txt"): (
"""
Lorem ipsum
"""
),
}
)
with local.cwd(src):
git("init")
git("add", "-A")
git("commit", "-m", "first commit on src")
run_copy(str(src), dst, defaults=True, overwrite=True)
with local.cwd(src):
Path("test_file.txt").write_text("Test content")
Path("aaaa.txt").write_text("dolor sit amet")
# dst must be vcs-tracked to use run_update
with local.cwd(dst):
git("init")
git("add", "-A")
git("commit", "-m", "first commit on dst")
gitconfig.set({"user.signinkey": "123456", "commit.gpgsign": "true"})
with pytest.warns(DirtyLocalWarning):
run_update(dst, defaults=True, overwrite=True)