copier/tests/helpers.py
Jairo Llopis cda93273c1
Enhanced user input (#260)
* use a new toolkit for user prompting: questionary (patched).
* multiline questions.
* conditional questions.
* new toolkit for ui tests: pexpect.
* fix lots of tests.
* fix windows builds with newer poetry-dynamic-versioning.
* linters and mypy are now tests, to have faster ci.
* update deprecated ci commands.
* removed dependencies from old times.
* Remove toml 0.5+ syntax (dotted keys)
* Use powershell where syntax is compatible
* Change skip to xfail
* xfail pexpect tests on windows. I'm tired of trying to make it work
* more docs
* possibly something more.
2020-10-12 08:56:46 +01:00

72 lines
1.9 KiB
Python

import filecmp
import os
import sys
import textwrap
from enum import Enum
from hashlib import sha1
from pathlib import Path
from typing import Dict
from plumbum import local
from prompt_toolkit.input.ansi_escape_sequences import REVERSE_ANSI_SEQUENCES
from prompt_toolkit.keys import Keys
import copier
from copier.types import StrOrPath
PROJECT_TEMPLATE = Path(__file__).parent / "demo"
DATA = {
"py3": True,
"make_secret": lambda: sha1(os.urandom(48)).hexdigest(),
"myvar": "awesome",
"what": "world",
"project_name": "Copier",
"version": "2.0.0",
"description": "A library for rendering projects templates",
}
COPIER_CMD = local.get(
# Allow debugging in VSCode
# HACK https://github.com/microsoft/vscode-python/issues/14222
str(Path(sys.executable).parent / "copier.cmd"),
str(Path(sys.executable).parent / "copier"),
# Poetry installs the executable as copier.cmd in Windows
"copier.cmd",
"copier",
)
COPIER_PATH = str(COPIER_CMD.executable)
class Keyboard(str, Enum):
ControlH = REVERSE_ANSI_SEQUENCES[Keys.ControlH]
Enter = "\r"
Esc = REVERSE_ANSI_SEQUENCES[Keys.Escape]
# Equivalent keystrokes in terminals; see python-prompt-toolkit for
# further explanations
Alt = Esc
Backspace = ControlH
def render(tmp_path, **kwargs):
kwargs.setdefault("quiet", True)
copier.copy(str(PROJECT_TEMPLATE), tmp_path, data=DATA, **kwargs)
def assert_file(tmp_path, *path):
p1 = os.path.join(str(tmp_path), *path)
p2 = os.path.join(str(PROJECT_TEMPLATE), *path)
assert filecmp.cmp(p1, p2)
def build_file_tree(spec: Dict[StrOrPath, str], dedent: bool = True):
"""Builds a file tree based on the received spec."""
for path, contents in spec.items():
path = Path(path)
if dedent:
contents = textwrap.dedent(contents)
path.parent.mkdir(parents=True, exist_ok=True)
with path.open("w") as fd:
fd.write(contents)