diff --git a/copier/main.py b/copier/main.py index dc076fcd..dc0c9c05 100644 --- a/copier/main.py +++ b/copier/main.py @@ -480,9 +480,6 @@ def _ask(self) -> None: # noqa: C901 else: if question.validate_answer(answer): del result.last[var_name] - # Skip a question when the user already answered it. - if self.skip_answered and var_name in result.last: - continue # Skip a question when the skip condition is met. if not question.get_when(): # Omit its answer from the answers file. @@ -502,6 +499,9 @@ def _ask(self) -> None: # noqa: C901 # question again, but set answer as the user's answer instead. result.user[var_name] = answer continue + # Skip a question when the user already answered it. + if self.skip_answered and var_name in result.last: + continue # Display TUI and ask user interactively only without --defaults try: diff --git a/tests/test_recopy.py b/tests/test_recopy.py index 06257d95..80a67310 100644 --- a/tests/test_recopy.py +++ b/tests/test_recopy.py @@ -1,6 +1,7 @@ from pathlib import Path import pytest +import yaml from plumbum import local from copier import run_copy, run_recopy @@ -72,3 +73,28 @@ def test_recopy_works_without_replay(tpl: str, tmp_path: Path) -> None: # Recopy run_recopy(tmp_path, skip_answered=True, overwrite=True) assert (tmp_path / "name.txt").read_text() == "This is my name: Mario." + + +def test_recopy_with_skip_answered_and_new_answer( + tmp_path_factory: pytest.TempPathFactory, +) -> None: + src, dst = map(tmp_path_factory.mktemp, ("src", "dst")) + build_file_tree( + { + src / "copier.yml": "boolean: false", + src / "{{ _copier_conf.answers_file }}.jinja": ( + "{{ _copier_answers|to_nice_yaml }}" + ), + } + ) + git_save(src) + # First copy + run_copy(str(src), dst, defaults=True, overwrite=True) + git_save(dst) + answers_file = dst / ".copier-answers.yml" + answers = yaml.safe_load(answers_file.read_text()) + assert answers["boolean"] is False + # Recopy with different answer and `skip_answered=True` + run_recopy(dst, data={"boolean": "true"}, skip_answered=True, overwrite=True) + answers = yaml.safe_load(answers_file.read_text()) + assert answers["boolean"] is True diff --git a/tests/test_updatediff.py b/tests/test_updatediff.py index 2e73a41c..a556de05 100644 --- a/tests/test_updatediff.py +++ b/tests/test_updatediff.py @@ -1518,3 +1518,31 @@ def test_update_with_separate_git_directory( run_update(dst, overwrite=True) assert "_commit: v2" in (dst / ".copier-answers.yml").read_text() + + +def test_update_with_skip_answered_and_new_answer( + tmp_path_factory: pytest.TempPathFactory, +) -> None: + src, dst = map(tmp_path_factory.mktemp, ("src", "dst")) + + with local.cwd(src): + build_file_tree( + { + "copier.yml": "boolean: false", + "{{ _copier_conf.answers_file }}.jinja": "{{ _copier_answers|to_nice_yaml }}", + } + ) + git_init("v1") + git("tag", "v1") + + run_copy(str(src), dst, defaults=True, overwrite=True) + answers_file = dst / ".copier-answers.yml" + answers = yaml.safe_load(answers_file.read_text()) + assert answers["boolean"] is False + + with local.cwd(dst): + git_init("v1") + + run_update(dst, data={"boolean": "true"}, skip_answered=True, overwrite=True) + answers = yaml.safe_load(answers_file.read_text()) + assert answers["boolean"] is True