Skip to content

Commit a420feb

Browse files
committed
Address comments
1 parent fecdc48 commit a420feb

3 files changed

Lines changed: 96 additions & 277 deletions

File tree

copier/_user_data.py

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -603,33 +603,8 @@ def load_answersfile_data(
603603
Returns:
604604
The loaded answers data, or an empty dict if not found.
605605
"""
606-
dst = Path(dst_path)
607-
608-
# If answers_file is None, auto-detect
609606
if answers_file is None:
610-
yml_path = dst / DEFAULT_ANSWERS_FILE_YML
611-
yaml_path = dst / DEFAULT_ANSWERS_FILE_YAML
612-
613-
yml_exists = yml_path.is_file()
614-
yaml_exists = yaml_path.is_file()
615-
616-
# Warn if both files exist
617-
if yml_exists and yaml_exists:
618-
warnings.warn(
619-
f"Both {DEFAULT_ANSWERS_FILE_YML} and {DEFAULT_ANSWERS_FILE_YAML} "
620-
f"exist in {dst_path}. Using {DEFAULT_ANSWERS_FILE_YML}. "
621-
"Please remove the duplicate file.",
622-
stacklevel=2,
623-
)
624-
625-
# .yml takes precedence, fall back to .yaml
626-
if yml_exists:
627-
answers_file = DEFAULT_ANSWERS_FILE_YML
628-
elif yaml_exists:
629-
answers_file = DEFAULT_ANSWERS_FILE_YAML
630-
else:
631-
# Default to .yml when neither exists
632-
answers_file = DEFAULT_ANSWERS_FILE_YML
607+
answers_file = resolve_answersfile_path(dst_path)
633608

634609
try:
635610
with Path(dst_path, answers_file).open("rb") as fd:

tests/test_answersfile.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import copier
1111
from copier._user_data import load_answersfile_data
12+
from copier._user_data import DEFAULT_ANSWERS_FILE_YAML, DEFAULT_ANSWERS_FILE_YML
1213

1314
from .helpers import BRACKET_ENVOPS_JSON, SUFFIX_TMPL, build_file_tree, git_save
1415

@@ -328,3 +329,97 @@ def test_undefined_phase_in_external_data(
328329
copier.run_copy(str(src), dst, defaults=True, overwrite=True)
329330
answers = load_answersfile_data(dst, ".copier-answers.yml")
330331
assert answers["key"] == "value"
332+
333+
334+
class TestYamlAnswersFileSuffix:
335+
"""Tests for .yaml answers file suffix support alongside .yml."""
336+
337+
@pytest.fixture
338+
def simple_template(self, tmp_path_factory: pytest.TempPathFactory) -> Path:
339+
"""Create a simple template for testing."""
340+
root = tmp_path_factory.mktemp("template")
341+
build_file_tree(
342+
{
343+
(root / "copier.yml"): dedent(
344+
"""\
345+
name:
346+
type: str
347+
default: test
348+
"""
349+
),
350+
(root / "{{ _copier_conf.answers_file }}.jinja"): (
351+
"{{ _copier_answers|tojson }}"
352+
),
353+
}
354+
)
355+
git_save(root, tag="v1")
356+
return root
357+
358+
def test_new_project_uses_yml_by_default(
359+
self, simple_template: Path, tmp_path: Path
360+
) -> None:
361+
"""New projects create .copier-answers.yml by default."""
362+
copier.run_copy(str(simple_template), tmp_path, defaults=True)
363+
assert (tmp_path / DEFAULT_ANSWERS_FILE_YML).exists()
364+
assert not (tmp_path / DEFAULT_ANSWERS_FILE_YAML).exists()
365+
366+
def test_recopy_reads_yaml_answers(
367+
self, simple_template: Path, tmp_path: Path
368+
) -> None:
369+
"""run_recopy can read answers from an existing .yaml file."""
370+
copier.run_copy(str(simple_template), tmp_path, defaults=True)
371+
372+
# Rename .yml to .yaml to simulate a project using .yaml
373+
(tmp_path / DEFAULT_ANSWERS_FILE_YML).rename(
374+
tmp_path / DEFAULT_ANSWERS_FILE_YAML
375+
)
376+
git_save(tmp_path)
377+
378+
# run_recopy should auto-detect and read from .yaml
379+
copier.run_recopy(tmp_path, defaults=True, overwrite=True)
380+
381+
# The template writes to .copier-answers.yml (its configured default),
382+
# so after recopy both may exist. Verify the recopy succeeded
383+
# by checking the newly written answers file is valid.
384+
answers = load_answersfile_data(tmp_path)
385+
assert answers["name"] == "test"
386+
387+
def test_update_reads_yaml_answers(
388+
self, simple_template: Path, tmp_path: Path
389+
) -> None:
390+
"""run_update can read answers from an existing .yaml file."""
391+
copier.run_copy(str(simple_template), tmp_path, defaults=True)
392+
393+
# Rename .yml to .yaml to simulate a project using .yaml
394+
(tmp_path / DEFAULT_ANSWERS_FILE_YML).rename(
395+
tmp_path / DEFAULT_ANSWERS_FILE_YAML
396+
)
397+
git_save(tmp_path)
398+
399+
# run_update should auto-detect and read from .yaml
400+
copier.run_update(tmp_path, defaults=True, overwrite=True)
401+
402+
answers = load_answersfile_data(tmp_path)
403+
assert answers["name"] == "test"
404+
405+
def test_yml_takes_precedence_over_yaml(
406+
self, simple_template: Path, tmp_path: Path
407+
) -> None:
408+
""".yml file takes precedence when both .yml and .yaml exist."""
409+
copier.run_copy(
410+
str(simple_template), tmp_path, data={"name": "from_yml"}, defaults=True
411+
)
412+
413+
# Create a .yaml file with different content
414+
yaml_file = tmp_path / DEFAULT_ANSWERS_FILE_YAML
415+
yml_answers = yaml.safe_load(
416+
(tmp_path / DEFAULT_ANSWERS_FILE_YML).read_text()
417+
)
418+
yaml_file.write_text(yaml.dump({**yml_answers, "name": "from_yaml"}))
419+
git_save(tmp_path)
420+
421+
# recopy should use .yml (which has "from_yml"), not .yaml
422+
copier.run_recopy(tmp_path, defaults=True, overwrite=True)
423+
424+
answers = load_answersfile_data(tmp_path)
425+
assert answers["name"] == "from_yml"

tests/test_yaml_answersfile.py

Lines changed: 0 additions & 251 deletions
This file was deleted.

0 commit comments

Comments
 (0)