Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement support for local extensions #237

Merged
merged 13 commits into from Apr 4, 2023
2 changes: 1 addition & 1 deletion cruft/_commands/check.py
Expand Up @@ -17,7 +17,7 @@ def check(
used to generate this project."""
cruft_file = utils.cruft.get_cruft_file(project_dir)
cruft_state = json.loads(cruft_file.read_text())
with AltTemporaryDirectory() as cookiecutter_template_dir:
with AltTemporaryDirectory(cruft_state.get("directory")) as cookiecutter_template_dir:
with utils.cookiecutter.get_cookiecutter_repo(
cruft_state["template"],
Path(cookiecutter_template_dir),
Expand Down
2 changes: 1 addition & 1 deletion cruft/_commands/create.py
Expand Up @@ -23,7 +23,7 @@ def create(
) -> Path:
"""Expand a Git based Cookiecutter template into a new project on disk."""
template_git_url = utils.cookiecutter.resolve_template_url(template_git_url)
with AltTemporaryDirectory() as cookiecutter_template_dir_str:
with AltTemporaryDirectory(directory) as cookiecutter_template_dir_str:
cookiecutter_template_dir = Path(cookiecutter_template_dir_str)
with utils.cookiecutter.get_cookiecutter_repo(
template_git_url, cookiecutter_template_dir, checkout
Expand Down
2 changes: 1 addition & 1 deletion cruft/_commands/diff.py
Expand Up @@ -19,7 +19,7 @@ def diff(
checkout = checkout or cruft_state.get("commit")

has_diff = False
with AltTemporaryDirectory() as tmpdir_:
with AltTemporaryDirectory(cruft_state.get("directory")) as tmpdir_:
tmpdir = Path(tmpdir_)
repo_dir = tmpdir / "repo"
remote_template_dir = tmpdir / "remote"
Expand Down
2 changes: 1 addition & 1 deletion cruft/_commands/link.py
Expand Up @@ -22,7 +22,7 @@ def link(
"""Links an existing project created from a template, to the template it was created from."""
cruft_file = utils.cruft.get_cruft_file(project_dir, exists=False)
template_git_url = utils.cookiecutter.resolve_template_url(template_git_url)
with AltTemporaryDirectory() as cookiecutter_template_dir_str:
with AltTemporaryDirectory(directory) as cookiecutter_template_dir_str:
cookiecutter_template_dir = Path(cookiecutter_template_dir_str)
with utils.cookiecutter.get_cookiecutter_repo(
template_git_url, cookiecutter_template_dir, checkout
Expand Down
8 changes: 7 additions & 1 deletion cruft/_commands/update.py
Expand Up @@ -38,7 +38,13 @@ def update(

cruft_state = json.loads(cruft_file.read_text())

with AltTemporaryDirectory() as tmpdir_:
directory = cruft_state.get("directory", "")
if directory:
directory = str(Path("repo") / directory)
else:
directory = "repo"

with AltTemporaryDirectory(directory) as tmpdir_:
# Initial setup
tmpdir = Path(tmpdir_)
repo_dir = tmpdir / "repo"
Expand Down
2 changes: 1 addition & 1 deletion cruft/_commands/utils/generate.py
Expand Up @@ -85,7 +85,7 @@ def _generate_output(
# Therefore we have to move the directory content to the expected output_dir.
# See https://github.com/cookiecutter/cookiecutter/pull/907
output_dir.mkdir(parents=True, exist_ok=True)
with AltTemporaryDirectory() as tmpdir:
with AltTemporaryDirectory(cruft_state.get("directory")) as tmpdir:

# Kindly ask cookiecutter to generate the template
template_dir = generate_files(
Expand Down
15 changes: 14 additions & 1 deletion cruft/_commands/utils/iohelper.py
@@ -1,15 +1,28 @@
import sys
from pathlib import Path
from tempfile import TemporaryDirectory
from time import sleep
from typing import Optional


class AltTemporaryDirectory:
def __init__(self):
def __init__(self, directory: Optional[str] = None):
self.tmpdir = TemporaryDirectory()
self._extended_path = False
self._directory = directory or ""
name = str(Path(self.tmpdir.name) / self._directory)
if name not in sys.path:
self._extended_path = True
sys.path.append(name)

def __enter__(self):
return self.tmpdir.name

def cleanup(self, cnt=0):
if self._extended_path:
name = str(Path(self.tmpdir.name) / self._directory)
if name in sys.path:
sys.path.remove(name)
if cnt >= 5: # pragma: no cover
raise RuntimeError("Could not delete TemporaryDirectory!")
try:
Expand Down
35 changes: 35 additions & 0 deletions tests/test_cli.py
Expand Up @@ -471,3 +471,38 @@ def test_diff_skip_git_dir(args, expected_exit_code, cruft_runner, cookiecutter_
print(result.stdout)
assert result.exit_code == expected_exit_code
assert ".git" not in result.stdout


def test_local_extension(cruft_runner, tmpdir):
result = cruft_runner(
[
"create",
"--output-dir",
str(tmpdir),
"https://github.com/cruft/cookiecutter-test",
"--directory",
"dir",
"--checkout",
"extensions",
"-y",
]
)
assert result.exit_code == 0
assert result.stdout == ""


def test_local_extension_update(cruft_runner, tmpdir):
test_local_extension(cruft_runner, tmpdir)
result = cruft_runner(
[
"update",
"--project-dir",
str(tmpdir / "test"),
"--checkout",
"extensions-update",
"--skip-apply-ask",
]
)
assert result.exit_code == 0
with open(tmpdir / "test" / "README.md") as f:
assert "Updated11" in f.read()