Skip to content

Commit

Permalink
fix(vcs): prevent local clone from being stuck by gpg prompts
Browse files Browse the repository at this point in the history
Fixes #856
Fixes #1224
Fixes #616
  • Loading branch information
noirbizarre committed Oct 15, 2023
1 parent 6badb2b commit 8fad4be
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 9 deletions.
18 changes: 16 additions & 2 deletions copier/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -943,8 +943,22 @@ def _git_initialize_repo(self):
git("config", "user.email", "copier@copier")
# 1st commit could fail if any pre-commit hook reformats code
# 2nd commit uses --no-verify to disable pre-commit-like checks
git("commit", "--allow-empty", "-am", "dumb commit 1", retcode=None)
git("commit", "--allow-empty", "-am", "dumb commit 2", "--no-verify")
git(
"commit",
"--allow-empty",
"-am",
"dumb commit 1",
"--no-gpg-sign",
retcode=None,
)
git(
"commit",
"--allow-empty",
"-am",
"dumb commit 2",
"--no-gpg-sign",
"--no-verify",
)
git("config", "--unset", "user.name")
git("config", "--unset", "user.email")

Expand Down
1 change: 1 addition & 0 deletions copier/vcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ def clone(url: str, ref: OptStr = None) -> str:
"-m",
"Copier automated commit for draft changes",
"--no-verify",
"--no-gpg-sign",
)
warn(
"Dirty template changes included automatically.",
Expand Down
35 changes: 34 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 3 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ copier = "copier.__main__:copier_app_run"
"Bug Tracker" = "https://github.com/copier-org/copier/issues"

[tool.poetry.dependencies]
python = ">=3.8,<4.0" # HACK https://github.com/PyCQA/isort/issues/1945
python = ">=3.8,<4.0" # HACK https://github.com/PyCQA/isort/issues/1945
colorama = ">=0.4.3"
decorator = ">=5.1.1"
dunamai = ">=1.7.0"
Expand All @@ -53,6 +53,7 @@ poethepoet = ">=0.12.3"
pre-commit = ">=2.17.0"
pytest = ">=7.2.0"
pytest-cov = ">=3.0.0"
pytest-gitconfig = ">=0.6.0"
pytest-xdist = ">=2.5.0"
types-backports = ">=0.1.3"
types-decorator = ">=5.1.1"
Expand Down Expand Up @@ -126,9 +127,7 @@ add_ignore = ["D105", "D107"]

[tool.pytest.ini_options]
addopts = "-n auto -ra"
markers = [
"impure: needs network or is not 100% reproducible"
]
markers = ["impure: needs network or is not 100% reproducible"]

[tool.commitizen]
annotated_tag = true
Expand Down
30 changes: 29 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import platform
import sys
from typing import Optional, Tuple
from typing import Iterator, Optional, Tuple

import pytest
from coverage.tracer import CTracer
from pexpect.popen_spawn import PopenSpawn
from plumbum import local
from pytest_gitconfig import GitConfig

from .helpers import Spawn

Expand Down Expand Up @@ -32,3 +34,29 @@ def _spawn(cmd: Tuple[str, ...], *, timeout: Optional[int] = None) -> PopenSpawn
return PopenSpawn(cmd, timeout, logfile=sys.stderr.buffer)

return _spawn


@pytest.fixture(scope="session", autouse=True)
def default_gitconfig(default_gitconfig: GitConfig) -> GitConfig:
"""
Use a clean and isolated default gitconfig avoiding user settings to break some tests.
Add plumbum support to the original session-scoped fixture.
"""
# local.env is a snapshot frozen at Python startup requiring its own monkeypatching
for var in list(local.env.keys()):
if var.startswith("GIT_"):
del local.env[var]
local.env["GIT_CONFIG_GLOBAL"] = str(default_gitconfig)
return default_gitconfig


@pytest.fixture
def gitconfig(gitconfig: GitConfig) -> Iterator[GitConfig]:
"""
Use a clean and isolated gitconfig to test some specific user settings.
Add plumbum support to the original function-scoped fixture.
"""
with local.env(GIT_CONFIG_GLOBAL=str(gitconfig)):
yield gitconfig
76 changes: 75 additions & 1 deletion tests/test_dirty_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import pytest
from plumbum import local
from plumbum.cmd import git
from pytest_gitconfig import GitConfig

import copier
from copier.errors import DirtyLocalWarning
Expand Down Expand Up @@ -50,7 +51,31 @@ def test_copy_dirty_head(tmp_path_factory: pytest.TempPathFactory) -> None:
git("init")
git("add", "tracked")
git("commit", "-m1")
copier.run_copy(str(src), dst, vcs_ref="HEAD")
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()

Expand Down Expand Up @@ -141,3 +166,52 @@ def test_update(tmp_path_factory: pytest.TempPathFactory) -> None:
# 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)

0 comments on commit 8fad4be

Please sign in to comment.