mirror of
https://github.com/copier-org/copier.git
synced 2025-05-05 15:32:54 +00:00
wip
This commit is contained in:
parent
386e50ede9
commit
1482de4972
10
tests/demo/copier.yaml
Normal file
10
tests/demo/copier.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
_templates_suffix: .tmpl
|
||||
_envops:
|
||||
autoescape: false
|
||||
block_end_string: "%]"
|
||||
block_start_string: "[%"
|
||||
comment_end_string: "#]"
|
||||
comment_start_string: "[#"
|
||||
keep_trailing_newline: true
|
||||
variable_end_string: "]]"
|
||||
variable_start_string: "[["
|
@ -1,3 +1,14 @@
|
||||
_templates_suffix: .tmpl
|
||||
_envops:
|
||||
autoescape: false
|
||||
block_end_string: "%]"
|
||||
block_start_string: "[%"
|
||||
comment_end_string: "#]"
|
||||
comment_start_string: "[#"
|
||||
keep_trailing_newline: true
|
||||
variable_end_string: "]]"
|
||||
variable_start_string: "[["
|
||||
|
||||
_exclude:
|
||||
- tasks.py
|
||||
- migrations.py
|
||||
|
@ -1,2 +0,0 @@
|
||||
# Changes here will be overwritten by Copier
|
||||
[[ _copier_answers|to_nice_yaml ]]
|
@ -1 +0,0 @@
|
||||
EXAMPLE_CONTENT
|
Binary file not shown.
@ -1,8 +0,0 @@
|
||||
# This is a comment
|
||||
a_string: lorem ipsum
|
||||
a_number: 12345
|
||||
a_boolean: true
|
||||
a_list:
|
||||
- one
|
||||
- two
|
||||
- three
|
@ -1,4 +0,0 @@
|
||||
A string: [[ a_string ]]
|
||||
A number: [[ a_number ]]
|
||||
A boolean: [[ a_boolean ]]
|
||||
A list: [[ ", ".join(a_list) ]]
|
@ -1,8 +0,0 @@
|
||||
# This is a comment
|
||||
a_string: lorem ipsum
|
||||
a_number: 12345
|
||||
a_boolean: true
|
||||
a_list:
|
||||
- one
|
||||
- two
|
||||
- three
|
@ -1,4 +0,0 @@
|
||||
A string: [[ a_string ]]
|
||||
A number: [[ a_number ]]
|
||||
A boolean: [[ a_boolean ]]
|
||||
A list: [[ ", ".join(a_list) ]]
|
@ -1,4 +1,5 @@
|
||||
import filecmp
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import textwrap
|
||||
@ -37,6 +38,20 @@ COPIER_CMD = local.get(
|
||||
)
|
||||
COPIER_PATH = str(COPIER_CMD.executable)
|
||||
|
||||
# Helpers to use with tests designed for old copier bracket envops defaults
|
||||
BRACKET_ENVOPS = {
|
||||
"autoescape": False,
|
||||
"block_end_string": "%]",
|
||||
"block_start_string": "[%",
|
||||
"comment_end_string": "#]",
|
||||
"comment_start_string": "[#",
|
||||
"keep_trailing_newline": True,
|
||||
"variable_end_string": "]]",
|
||||
"variable_start_string": "[[",
|
||||
}
|
||||
BRACKET_ENVOPS_JSON = json.dumps(BRACKET_ENVOPS)
|
||||
SUFFIX_TMPL = ".tmpl"
|
||||
|
||||
# Helper to parse back an iso-formatted datetime; needed for py3.6, where
|
||||
# datetime.datetime.fromisoformat() doesn't exist
|
||||
ISOFORMAT = "%Y-%m-%d %H:%M:%S.%f"
|
||||
|
@ -1,4 +0,0 @@
|
||||
A string: lorem ipsum
|
||||
A number: 12345
|
||||
A boolean: True
|
||||
A list: one, two, three
|
@ -5,7 +5,7 @@ import pytest
|
||||
import copier
|
||||
from copier.user_data import load_answersfile_data
|
||||
|
||||
from .helpers import build_file_tree
|
||||
from .helpers import BRACKET_ENVOPS_JSON, SUFFIX_TMPL, build_file_tree
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
@ -19,8 +19,10 @@ def template_path(tmp_path_factory) -> str:
|
||||
[[ _copier_answers|to_nice_yaml ]]
|
||||
""",
|
||||
root
|
||||
/ "copier.yml": """\
|
||||
/ "copier.yml": f"""\
|
||||
_answers_file: .answers-file-changed-in-template.yml
|
||||
_templates_suffix: {SUFFIX_TMPL}
|
||||
_envops: {BRACKET_ENVOPS_JSON}
|
||||
|
||||
round: 1st
|
||||
|
||||
|
@ -1,26 +1,39 @@
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
import yaml
|
||||
|
||||
from copier.cli import CopierApp
|
||||
|
||||
from .helpers import COPIER_CMD
|
||||
|
||||
SIMPLE_DEMO_PATH = Path(__file__).parent / "demo_simple"
|
||||
from .helpers import COPIER_CMD, build_file_tree
|
||||
|
||||
|
||||
def test_good_cli_run(tmp_path):
|
||||
@pytest.fixture(scope="module")
|
||||
def template_path(tmp_path_factory) -> str:
|
||||
root = tmp_path_factory.mktemp("template")
|
||||
build_file_tree(
|
||||
{
|
||||
root
|
||||
/ "{{ _copier_conf.answers_file }}.jinja": """\
|
||||
# Changes here will be overwritten by Copier
|
||||
{{ _copier_answers|to_nice_yaml }}
|
||||
""",
|
||||
root / "a.txt": "EXAMPLE_CONTENT",
|
||||
}
|
||||
)
|
||||
return str(root)
|
||||
|
||||
|
||||
def test_good_cli_run(tmp_path, template_path):
|
||||
run_result = CopierApp.run(
|
||||
["--quiet", "-a", "altered-answers.yml", str(SIMPLE_DEMO_PATH), str(tmp_path)],
|
||||
["--quiet", "-a", "altered-answers.yml", str(template_path), str(tmp_path)],
|
||||
exit=False,
|
||||
)
|
||||
a_txt = tmp_path / "a.txt"
|
||||
assert run_result[1] == 0
|
||||
assert a_txt.exists()
|
||||
assert a_txt.is_file()
|
||||
assert a_txt.read_text().strip() == "EXAMPLE_CONTENT"
|
||||
assert a_txt.read_text() == "EXAMPLE_CONTENT"
|
||||
answers = yaml.safe_load((tmp_path / "altered-answers.yml").read_text())
|
||||
assert answers["_src_path"] == str(SIMPLE_DEMO_PATH)
|
||||
assert answers["_src_path"] == str(template_path)
|
||||
|
||||
|
||||
def test_help():
|
||||
|
@ -6,7 +6,13 @@ import pytest
|
||||
|
||||
from copier import copy
|
||||
|
||||
from .helpers import COPIER_PATH, Keyboard, build_file_tree
|
||||
from .helpers import (
|
||||
BRACKET_ENVOPS_JSON,
|
||||
COPIER_PATH,
|
||||
SUFFIX_TMPL,
|
||||
Keyboard,
|
||||
build_file_tree,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
@ -15,7 +21,9 @@ def template_path(tmp_path_factory) -> str:
|
||||
build_file_tree(
|
||||
{
|
||||
root
|
||||
/ "copier.yml": """\
|
||||
/ "copier.yml": f"""\
|
||||
_templates_suffix: {SUFFIX_TMPL}
|
||||
_envops: {BRACKET_ENVOPS_JSON}
|
||||
love_me:
|
||||
help: I need to know it. Do you love me?
|
||||
type: bool
|
||||
|
@ -1,4 +1,5 @@
|
||||
from pathlib import Path
|
||||
from textwrap import dedent
|
||||
|
||||
import pytest
|
||||
from plumbum import local
|
||||
@ -8,7 +9,7 @@ import copier
|
||||
from copier.errors import InvalidConfigFileError, MultipleConfigFilesError
|
||||
from copier.template import DEFAULT_EXCLUDE, Template, load_template_config
|
||||
|
||||
from .helpers import build_file_tree
|
||||
from .helpers import BRACKET_ENVOPS_JSON, SUFFIX_TMPL, build_file_tree
|
||||
|
||||
GOOD_ENV_OPS = {
|
||||
"autoescape": True,
|
||||
@ -30,13 +31,43 @@ def test_config_data_is_loaded_from_file():
|
||||
assert tpl.tasks == ["touch 1", "touch 2"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("template", ["tests/demo_yaml", "tests/demo_yml"])
|
||||
def test_read_data(tmp_path, template):
|
||||
copier.copy(template, tmp_path, force=True)
|
||||
gen_file = tmp_path / "user_data.txt"
|
||||
@pytest.mark.parametrize("config_suffix", ["yaml", "yml"])
|
||||
def test_read_data(tmp_path_factory, config_suffix):
|
||||
src, dst = map(tmp_path_factory.mktemp, ("src", "dst"))
|
||||
build_file_tree(
|
||||
{
|
||||
src
|
||||
/ f"copier.{config_suffix}": f"""\
|
||||
# This is a comment
|
||||
_envops: {BRACKET_ENVOPS_JSON}
|
||||
a_string: lorem ipsum
|
||||
a_number: 12345
|
||||
a_boolean: true
|
||||
a_list:
|
||||
- one
|
||||
- two
|
||||
- three
|
||||
""",
|
||||
src
|
||||
/ "user_data.txt.jinja": """\
|
||||
A string: [[ a_string ]]
|
||||
A number: [[ a_number ]]
|
||||
A boolean: [[ a_boolean ]]
|
||||
A list: [[ ", ".join(a_list) ]]
|
||||
""",
|
||||
}
|
||||
)
|
||||
copier.copy(str(src), dst, force=True)
|
||||
gen_file = dst / "user_data.txt"
|
||||
result = gen_file.read_text()
|
||||
expected = Path("tests/reference_files/user_data.txt").read_text()
|
||||
assert result == expected
|
||||
assert result == dedent(
|
||||
"""\
|
||||
A string: lorem ipsum
|
||||
A number: 12345
|
||||
A boolean: True
|
||||
A list: one, two, three
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def test_invalid_yaml(capsys):
|
||||
@ -73,7 +104,8 @@ def test_valid_multi_section(tmp_path):
|
||||
build_file_tree(
|
||||
{
|
||||
"exclusions.yml": "_exclude: ['*.yml']",
|
||||
"common_jinja.yml": """
|
||||
"common_jinja.yml": f"""
|
||||
_templates_suffix: {SUFFIX_TMPL}
|
||||
_envops:
|
||||
block_start_string: "[%"
|
||||
block_end_string: "%]"
|
||||
@ -105,7 +137,6 @@ def test_valid_multi_section(tmp_path):
|
||||
template = Template(str(tmp_path))
|
||||
assert template.exclude == ("*.yml",)
|
||||
assert template.envops == {
|
||||
"autoescape": False,
|
||||
"block_end_string": "%]",
|
||||
"block_start_string": "[%",
|
||||
"comment_end_string": "#]",
|
||||
|
@ -9,7 +9,14 @@ from plumbum.cmd import git
|
||||
|
||||
import copier
|
||||
|
||||
from .helpers import PROJECT_TEMPLATE, assert_file, build_file_tree, filecmp, render
|
||||
from .helpers import (
|
||||
BRACKET_ENVOPS_JSON,
|
||||
PROJECT_TEMPLATE,
|
||||
assert_file,
|
||||
build_file_tree,
|
||||
filecmp,
|
||||
render,
|
||||
)
|
||||
|
||||
|
||||
def test_project_not_found(tmp_path):
|
||||
@ -120,7 +127,7 @@ def test_exclude_replaces(tmp_path: Path):
|
||||
src / "test.txt": "Test text",
|
||||
src / "test.json": '"test json"',
|
||||
src / "test.yaml": '"test yaml"',
|
||||
src / "copier.yaml.tmpl": "purpose: template inception",
|
||||
src / "copier.yaml.jinja": "purpose: template inception",
|
||||
src / "copier.yml": "_exclude: ['*.json']",
|
||||
}
|
||||
)
|
||||
@ -152,7 +159,7 @@ def test_skip_if_exists_rendered_patterns(tmp_path):
|
||||
"tests/demo_skip_src",
|
||||
tmp_path,
|
||||
data={"name": "meh"},
|
||||
skip_if_exists=["[[ name ]]/c.noeof.txt"],
|
||||
skip_if_exists=["{{ name }}/c.noeof.txt"],
|
||||
force=True,
|
||||
)
|
||||
assert (tmp_path / "a.noeof.txt").read_text() == "SKIPPED"
|
||||
@ -191,9 +198,10 @@ def test_empty_dir(tmp_path_factory, generate):
|
||||
build_file_tree(
|
||||
{
|
||||
src
|
||||
/ "copier.yaml": """
|
||||
/ "copier.yaml": f"""
|
||||
_subdirectory: tpl
|
||||
_templates_suffix: .jinja
|
||||
_envops: {BRACKET_ENVOPS_JSON}
|
||||
do_it:
|
||||
type: bool
|
||||
""",
|
||||
|
@ -5,22 +5,63 @@ from plumbum.cmd import git
|
||||
|
||||
from copier import copy
|
||||
|
||||
from .helpers import PROJECT_TEMPLATE
|
||||
from .helpers import PROJECT_TEMPLATE, build_file_tree
|
||||
|
||||
REPO_BUNDLE_PATH = Path(f"{PROJECT_TEMPLATE}_update_tasks.bundle").absolute()
|
||||
|
||||
|
||||
def test_update_tasks(tmp_path):
|
||||
def test_update_tasks(tmp_path_factory):
|
||||
"""Test that updating a template runs tasks from the expected version."""
|
||||
src, dst = map(tmp_path_factory.mktemp, ("src", "dst"))
|
||||
# Prepare repo bundle
|
||||
repo = src / "repo"
|
||||
bundle = src / "demo_update_tasks.bundle"
|
||||
build_file_tree(
|
||||
{
|
||||
repo
|
||||
/ ".copier-answers.yml.jinja": """\
|
||||
# Changes here will be overwritten by Copier
|
||||
{{ _copier_answers|to_nice_yaml }}
|
||||
""",
|
||||
repo
|
||||
/ "copier.yaml": """\
|
||||
_tasks:
|
||||
- cat v1.txt
|
||||
""",
|
||||
repo / "v1.txt": "file only in v1",
|
||||
}
|
||||
)
|
||||
with local.cwd(repo):
|
||||
git("init")
|
||||
git("add", ".")
|
||||
git("commit", "-m1")
|
||||
git("tag", "v1")
|
||||
build_file_tree(
|
||||
{
|
||||
repo
|
||||
/ "copier.yaml": """\
|
||||
_tasks:
|
||||
- cat v2.txt
|
||||
""",
|
||||
repo / "v2.txt": "file only in v2",
|
||||
}
|
||||
)
|
||||
(repo / "v1.txt").unlink()
|
||||
with local.cwd(repo):
|
||||
git("init")
|
||||
git("add", ".")
|
||||
git("commit", "-m2")
|
||||
git("tag", "v2")
|
||||
git("bundle", "create", bundle, "--all")
|
||||
# Copy the 1st version
|
||||
copy(
|
||||
str(REPO_BUNDLE_PATH),
|
||||
tmp_path,
|
||||
str(bundle),
|
||||
dst,
|
||||
force=True,
|
||||
vcs_ref="v1",
|
||||
)
|
||||
# Init destination as a new independent git repo
|
||||
with local.cwd(tmp_path):
|
||||
with local.cwd(dst):
|
||||
git("init")
|
||||
# Configure git in case you're running in CI
|
||||
git("config", "user.name", "Copier Test")
|
||||
@ -29,4 +70,4 @@ def test_update_tasks(tmp_path):
|
||||
git("add", ".")
|
||||
git("commit", "-m", "hello world")
|
||||
# Update target to v2
|
||||
copy(dst_path=str(tmp_path), force=True)
|
||||
copy(dst_path=str(dst), force=True)
|
||||
|
@ -12,7 +12,7 @@ from plumbum.cmd import git
|
||||
from copier import copy
|
||||
from copier.errors import UserMessageError
|
||||
|
||||
from .helpers import PROJECT_TEMPLATE, build_file_tree
|
||||
from .helpers import BRACKET_ENVOPS_JSON, PROJECT_TEMPLATE, build_file_tree
|
||||
|
||||
SRC = Path(f"{PROJECT_TEMPLATE}_migrations").absolute()
|
||||
|
||||
@ -81,11 +81,12 @@ def test_pre_migration_modifies_answers(tmp_path_factory):
|
||||
with local.cwd(template):
|
||||
build_file_tree(
|
||||
{
|
||||
"[[ _copier_conf.answers_file ]].tmpl": "[[ _copier_answers|tojson ]]",
|
||||
"copier.yml": """\
|
||||
"[[ _copier_conf.answers_file ]].jinja": "[[ _copier_answers|tojson ]]",
|
||||
"copier.yml": f"""\
|
||||
_envops: {BRACKET_ENVOPS_JSON}
|
||||
best_song: la vie en rose
|
||||
""",
|
||||
"songs.json.tmpl": "[ [[ best_song|tojson ]] ]",
|
||||
"songs.json.jinja": "[ [[ best_song|tojson ]] ]",
|
||||
}
|
||||
)
|
||||
git("init")
|
||||
@ -107,7 +108,8 @@ def test_pre_migration_modifies_answers(tmp_path_factory):
|
||||
{
|
||||
# v2 of template supports multiple songs, has a different default
|
||||
# and includes a data format migration script
|
||||
"copier.yml": """\
|
||||
"copier.yml": f"""\
|
||||
_envops: {BRACKET_ENVOPS_JSON}
|
||||
best_song_list:
|
||||
default: [paranoid android]
|
||||
_migrations:
|
||||
@ -124,7 +126,7 @@ def test_pre_migration_modifies_answers(tmp_path_factory):
|
||||
- "[[ _copier_conf.dst_path ]]"
|
||||
- "[[ _copier_conf.answers_file ]]"
|
||||
""",
|
||||
"songs.json.tmpl": "[[ best_song_list|tojson ]]",
|
||||
"songs.json.jinja": "[[ best_song_list|tojson ]]",
|
||||
}
|
||||
)
|
||||
git("add", ".")
|
||||
@ -149,8 +151,9 @@ def test_prereleases(tmp_path: Path):
|
||||
build_file_tree(
|
||||
{
|
||||
"version.txt": "v1.0.0",
|
||||
"[[ _copier_conf.answers_file ]].tmpl": "[[_copier_answers|to_nice_yaml]]",
|
||||
"copier.yaml": """
|
||||
"[[ _copier_conf.answers_file ]].jinja": "[[_copier_answers|to_nice_yaml]]",
|
||||
"copier.yaml": f"""
|
||||
_envops: {BRACKET_ENVOPS_JSON}
|
||||
_migrations:
|
||||
- version: v1.9
|
||||
before:
|
||||
|
@ -1,6 +1,7 @@
|
||||
import warnings
|
||||
|
||||
import pytest
|
||||
from packaging.version import Version
|
||||
from plumbum import local
|
||||
from plumbum.cmd import git
|
||||
|
||||
@ -72,7 +73,7 @@ def test_minimum_version_update(template_path, tmp_path, monkeypatch):
|
||||
|
||||
|
||||
def test_version_0_0_0_ignored(template_path, tmp_path, monkeypatch):
|
||||
monkeypatch.setattr("copier.__version__", "0.0.0")
|
||||
monkeypatch.setattr("copier.template.copier_version", lambda: Version("0.0.0"))
|
||||
# assert no error
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("error")
|
||||
|
@ -6,11 +6,20 @@ import yaml
|
||||
from plumbum import local
|
||||
from plumbum.cmd import git
|
||||
|
||||
from .helpers import COPIER_PATH, Keyboard, build_file_tree
|
||||
from .helpers import (
|
||||
BRACKET_ENVOPS,
|
||||
BRACKET_ENVOPS_JSON,
|
||||
COPIER_PATH,
|
||||
SUFFIX_TMPL,
|
||||
Keyboard,
|
||||
build_file_tree,
|
||||
)
|
||||
|
||||
DEFAULT = object()
|
||||
MARIO_TREE = {
|
||||
"copier.yml": """\
|
||||
"copier.yml": f"""\
|
||||
_templates_suffix: {SUFFIX_TMPL}
|
||||
_envops: {BRACKET_ENVOPS_JSON}
|
||||
in_love:
|
||||
type: bool
|
||||
default: yes
|
||||
@ -77,7 +86,7 @@ def test_copy_default_advertised(tmp_path_factory, spawn, name):
|
||||
git("add", ".")
|
||||
assert "_commit: v1" in Path(".copier-answers.yml").read_text()
|
||||
git("commit", "-m", "v1")
|
||||
tui = spawn([COPIER_PATH], timeout=20)
|
||||
tui = spawn([COPIER_PATH], timeout=30)
|
||||
# Check what was captured
|
||||
tui.expect_exact(["in_love?", "Format: bool", "(Y/n)"])
|
||||
tui.sendline()
|
||||
@ -147,6 +156,8 @@ def test_when(tmp_path_factory, question_1, question_2_when, spawn, asks):
|
||||
tmp_path_factory.mktemp("subproject"),
|
||||
)
|
||||
questions = {
|
||||
"_envops": BRACKET_ENVOPS,
|
||||
"_templates_suffix": SUFFIX_TMPL,
|
||||
"question_1": question_1,
|
||||
"question_2": {"default": "something", "when": question_2_when},
|
||||
}
|
||||
@ -182,6 +193,8 @@ def test_placeholder(tmp_path_factory, spawn):
|
||||
template
|
||||
/ "copier.yml": yaml.dump(
|
||||
{
|
||||
"_envops": BRACKET_ENVOPS,
|
||||
"_templates_suffix": SUFFIX_TMPL,
|
||||
"question_1": "answer 1",
|
||||
"question_2": {
|
||||
"type": "str",
|
||||
@ -221,6 +234,8 @@ def test_multiline(tmp_path_factory, spawn, type_):
|
||||
template
|
||||
/ "copier.yml": yaml.dump(
|
||||
{
|
||||
"_envops": BRACKET_ENVOPS,
|
||||
"_templates_suffix": SUFFIX_TMPL,
|
||||
"question_1": "answer 1",
|
||||
"question_2": {"type": type_},
|
||||
"question_3": {"type": type_, "multiline": True},
|
||||
@ -293,6 +308,8 @@ def test_update_choice(tmp_path_factory, spawn, choices):
|
||||
{
|
||||
template
|
||||
/ "copier.yml": f"""
|
||||
_templates_suffix: {SUFFIX_TMPL}
|
||||
_envops: {BRACKET_ENVOPS_JSON}
|
||||
pick_one:
|
||||
type: float
|
||||
default: 3
|
||||
|
@ -6,7 +6,7 @@ from plumbum.cmd import git
|
||||
|
||||
import copier
|
||||
|
||||
from .helpers import build_file_tree
|
||||
from .helpers import BRACKET_ENVOPS_JSON, SUFFIX_TMPL, build_file_tree
|
||||
|
||||
|
||||
def git_init(message="hello world"):
|
||||
@ -37,7 +37,9 @@ def demo_template(tmp_path_factory):
|
||||
/ "conf_project"
|
||||
/ "[[ _copier_conf.answers_file ]].tmpl": "[[ _copier_answers|to_nice_yaml ]]",
|
||||
root
|
||||
/ "copier.yml": """\
|
||||
/ "copier.yml": f"""\
|
||||
_templates_suffix: {SUFFIX_TMPL}
|
||||
_envops: {BRACKET_ENVOPS_JSON}
|
||||
choose_subdir:
|
||||
type: str
|
||||
default: conf_project
|
||||
@ -92,8 +94,8 @@ def test_new_version_uses_subdirectory(tmp_path_factory):
|
||||
with open("README.md", "w") as fd:
|
||||
fd.write("upstream version 1\n")
|
||||
|
||||
with open("[[_copier_conf.answers_file]].tmpl", "w") as fd:
|
||||
fd.write("[[_copier_answers|to_nice_yaml]]\n")
|
||||
with open("{{_copier_conf.answers_file}}.jinja", "w") as fd:
|
||||
fd.write("{{_copier_answers|to_nice_yaml}}\n")
|
||||
|
||||
git_init("hello template")
|
||||
git("tag", "v1")
|
||||
@ -123,8 +125,8 @@ def test_new_version_uses_subdirectory(tmp_path_factory):
|
||||
os.mkdir("subdir")
|
||||
os.rename("README.md", "subdir/README.md")
|
||||
os.rename(
|
||||
"[[_copier_conf.answers_file]].tmpl",
|
||||
"subdir/[[_copier_conf.answers_file]].tmpl",
|
||||
"{{_copier_conf.answers_file}}.jinja",
|
||||
"subdir/{{_copier_conf.answers_file}}.jinja",
|
||||
)
|
||||
|
||||
# Add the subdirectory option to copier.yml
|
||||
|
@ -2,7 +2,7 @@ import pytest
|
||||
|
||||
import copier
|
||||
|
||||
from .helpers import build_file_tree
|
||||
from .helpers import BRACKET_ENVOPS_JSON, SUFFIX_TMPL, build_file_tree
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
@ -11,7 +11,10 @@ def demo_template(tmp_path_factory):
|
||||
build_file_tree(
|
||||
{
|
||||
root
|
||||
/ "copier.yaml": """
|
||||
/ "copier.yaml": f"""
|
||||
_templates_suffix: {SUFFIX_TMPL}
|
||||
_envops: {BRACKET_ENVOPS_JSON}
|
||||
|
||||
other_file: bye
|
||||
|
||||
# This tests two things:
|
||||
|
@ -7,11 +7,22 @@ import yaml
|
||||
from copier import Worker
|
||||
from copier.errors import InvalidTypeError
|
||||
|
||||
from .helpers import COPIER_PATH, ISOFORMAT, build_file_tree
|
||||
from .helpers import (
|
||||
BRACKET_ENVOPS,
|
||||
BRACKET_ENVOPS_JSON,
|
||||
COPIER_PATH,
|
||||
ISOFORMAT,
|
||||
SUFFIX_TMPL,
|
||||
build_file_tree,
|
||||
)
|
||||
|
||||
envops = {}
|
||||
main_default = "copier"
|
||||
main_question = {"main": {"default": main_default}}
|
||||
main_question = {
|
||||
"main": {"default": main_default},
|
||||
"_envops": BRACKET_ENVOPS,
|
||||
"_templates_suffix": SUFFIX_TMPL,
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@ -165,7 +176,7 @@ def test_templated_prompt_custom_envops(tmp_path_factory):
|
||||
"<% if powerlevel >= 9000 %>It's over 9000!<% else %>It's only << powerlevel >>...<%
|
||||
endif %>"
|
||||
""",
|
||||
src / "result.tmpl": "<<sentence>>",
|
||||
src / "result.jinja": "<<sentence>>",
|
||||
}
|
||||
)
|
||||
worker1 = Worker(str(src), dst, force=True)
|
||||
@ -182,7 +193,9 @@ def test_templated_prompt_builtins(tmp_path_factory):
|
||||
build_file_tree(
|
||||
{
|
||||
src
|
||||
/ "copier.yaml": """
|
||||
/ "copier.yaml": f"""
|
||||
_templates_suffix: {SUFFIX_TMPL}
|
||||
_envops: {BRACKET_ENVOPS_JSON}
|
||||
question1:
|
||||
default: "[[ now() ]]"
|
||||
question2:
|
||||
@ -201,10 +214,10 @@ def test_templated_prompt_builtins(tmp_path_factory):
|
||||
@pytest.mark.parametrize(
|
||||
"questions, raises, returns",
|
||||
(
|
||||
({"question": {"default": "[[ not_valid ]]"}}, None, ""),
|
||||
({"question": {"help": "[[ not_valid ]]"}}, None, "None"),
|
||||
({"question": {"type": "[[ not_valid ]]"}}, InvalidTypeError, "None"),
|
||||
({"question": {"choices": ["[[ not_valid ]]"]}}, None, "None"),
|
||||
({"question": {"default": "{{ not_valid }}"}}, None, ""),
|
||||
({"question": {"help": "{{ not_valid }}"}}, None, "None"),
|
||||
({"question": {"type": "{{ not_valid }}"}}, InvalidTypeError, "None"),
|
||||
({"question": {"choices": ["{{ not_valid }}"]}}, None, "None"),
|
||||
),
|
||||
)
|
||||
def test_templated_prompt_invalid(tmp_path_factory, questions, raises, returns):
|
||||
@ -212,7 +225,7 @@ def test_templated_prompt_invalid(tmp_path_factory, questions, raises, returns):
|
||||
build_file_tree(
|
||||
{
|
||||
src / "copier.yml": yaml.safe_dump(questions),
|
||||
src / "result.tmpl": "[[question]]",
|
||||
src / "result.jinja": "{{question}}",
|
||||
}
|
||||
)
|
||||
worker = Worker(str(src), dst, force=True)
|
||||
|
@ -9,27 +9,130 @@ from plumbum.cmd import git
|
||||
from copier import Worker, copy
|
||||
from copier.cli import CopierApp
|
||||
|
||||
from .helpers import PROJECT_TEMPLATE, build_file_tree
|
||||
|
||||
REPO_BUNDLE_PATH = Path(f"{PROJECT_TEMPLATE}_updatediff_repo.bundle").absolute()
|
||||
from .helpers import build_file_tree
|
||||
|
||||
|
||||
def test_updatediff(tmpdir):
|
||||
tmp_path = Path(tmpdir)
|
||||
target = tmp_path / "target"
|
||||
def test_updatediff(tmp_path_factory):
|
||||
src, dst = map(tmp_path_factory.mktemp, ("src", "dst"))
|
||||
# Prepare repo bundle
|
||||
repo = src / "repo"
|
||||
bundle = src / "demo_updatediff_repo.bundle"
|
||||
build_file_tree(
|
||||
{
|
||||
repo
|
||||
/ ".copier-answers.yml.jinja": """\
|
||||
# Changes here will be overwritten by Copier
|
||||
{{ _copier_answers|to_nice_yaml }}
|
||||
""",
|
||||
repo
|
||||
/ "copier.yml": """\
|
||||
_envops:
|
||||
"keep_trailing_newline": True
|
||||
project_name: to become a pirate
|
||||
author_name: Guybrush
|
||||
""",
|
||||
repo
|
||||
/ "README.txt.jinja": """
|
||||
Let me introduce myself.
|
||||
|
||||
My name is {{author_name}}, and my project is {{project_name}}.
|
||||
|
||||
Thanks for your attention.
|
||||
""",
|
||||
}
|
||||
)
|
||||
with local.cwd(repo):
|
||||
git("init")
|
||||
git("add", ".")
|
||||
git("commit", "-m", "Guybrush wants to be a pirate")
|
||||
git("tag", "v0.0.1")
|
||||
build_file_tree(
|
||||
{
|
||||
repo
|
||||
/ "copier.yml": """\
|
||||
_envops:
|
||||
"keep_trailing_newline": True
|
||||
project_name: to become a pirate
|
||||
author_name: Guybrush
|
||||
_migrations:
|
||||
- version: v0.0.1
|
||||
before:
|
||||
- touch before-v0.0.1
|
||||
after:
|
||||
- touch after-v0.0.1
|
||||
- version: v0.0.2
|
||||
before:
|
||||
- touch before-v0.0.2
|
||||
after:
|
||||
- touch after-v0.0.2
|
||||
- version: v1.0.0
|
||||
before:
|
||||
- touch before-v1.0.0
|
||||
after:
|
||||
- touch after-v1.0.0
|
||||
""",
|
||||
}
|
||||
)
|
||||
with local.cwd(repo):
|
||||
git("init")
|
||||
git("add", ".")
|
||||
git("commit", "-m", "Add migrations")
|
||||
git("tag", "v0.0.2")
|
||||
build_file_tree(
|
||||
{
|
||||
repo
|
||||
/ "copier.yml": """\
|
||||
_envops:
|
||||
"keep_trailing_newline": True
|
||||
project_name: to rule
|
||||
author_name: Elaine
|
||||
_migrations:
|
||||
- version: v0.0.1
|
||||
before:
|
||||
- touch before-v0.0.1
|
||||
after:
|
||||
- touch after-v0.0.1
|
||||
- version: v0.0.2
|
||||
before:
|
||||
- touch before-v0.0.2
|
||||
after:
|
||||
- touch after-v0.0.2
|
||||
- version: v1.0.0
|
||||
before:
|
||||
- touch before-v1.0.0
|
||||
after:
|
||||
- touch after-v1.0.0
|
||||
""",
|
||||
repo
|
||||
/ "README.txt.jinja": """
|
||||
Let me introduce myself.
|
||||
|
||||
My name is {{author_name}}.
|
||||
|
||||
My project is {{project_name}}.
|
||||
|
||||
Thanks for your attention.
|
||||
""",
|
||||
}
|
||||
)
|
||||
with local.cwd(repo):
|
||||
git("init")
|
||||
git("add", ".")
|
||||
git("commit", "-m", "Elaine wants to rule")
|
||||
git("bundle", "create", bundle, "--all")
|
||||
# Generate repo bundle
|
||||
target = dst / "target"
|
||||
readme = target / "README.txt"
|
||||
answers = target / ".copier-answers.yml"
|
||||
commit = git["commit", "--all"]
|
||||
# Run copier 1st time, with specific tag
|
||||
CopierApp.invoke(
|
||||
"copy", str(REPO_BUNDLE_PATH), str(target), force=True, vcs_ref="v0.0.1"
|
||||
)
|
||||
CopierApp.invoke("copy", str(bundle), str(target), force=True, vcs_ref="v0.0.1")
|
||||
# Check it's copied OK
|
||||
assert answers.read_text() == dedent(
|
||||
f"""
|
||||
f"""\
|
||||
# Changes here will be overwritten by Copier
|
||||
_commit: v0.0.1
|
||||
_src_path: {REPO_BUNDLE_PATH}
|
||||
_src_path: {bundle}
|
||||
author_name: Guybrush
|
||||
project_name: to become a pirate
|
||||
"""
|
||||
@ -69,10 +172,10 @@ def test_updatediff(tmpdir):
|
||||
# Update target to latest tag and check it's updated in answers file
|
||||
CopierApp.invoke(force=True)
|
||||
assert answers.read_text() == dedent(
|
||||
f"""
|
||||
f"""\
|
||||
# Changes here will be overwritten by Copier
|
||||
_commit: v0.0.2
|
||||
_src_path: {REPO_BUNDLE_PATH}
|
||||
_src_path: {bundle}
|
||||
author_name: Guybrush
|
||||
project_name: to become a pirate
|
||||
"""
|
||||
@ -101,7 +204,7 @@ def test_updatediff(tmpdir):
|
||||
f"""
|
||||
# Changes here will be overwritten by Copier
|
||||
_commit: v0.0.2-1-g81c335d
|
||||
_src_path: {REPO_BUNDLE_PATH}
|
||||
_src_path: {bundle}
|
||||
author_name: Guybrush
|
||||
project_name: to become a pirate
|
||||
"""
|
||||
|
Loading…
x
Reference in New Issue
Block a user