Skip to content

Commit

Permalink
feat(tasks): add support for skipping tasks (#1561)
Browse files Browse the repository at this point in the history
Co-authored-by: Timothée Mazzucotelli <dev@pawamoy.fr>
Co-authored-by: Sigurd Spieckermann <2206639+sisp@users.noreply.github.com>
  • Loading branch information
3 people authored Apr 4, 2024
1 parent b78341b commit 4ca2e35
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 10 deletions.
5 changes: 5 additions & 0 deletions copier/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@ def __init__(self, executable: "PathLike[str]") -> None:
"Allow templates with unsafe features (Jinja extensions, migrations, tasks)"
),
)
skip_tasks = cli.Flag(
["-T", "--skip-tasks"],
default=False,
help="Skip template tasks execution",
)

@cli.switch( # type: ignore[misc]
["-d", "--data"],
Expand Down
7 changes: 6 additions & 1 deletion copier/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ class Worker:
skip_answered:
When `True`, skip questions that have already been answered.
skip_tasks:
When `True`, skip template tasks execution.
"""

src_path: str | None = None
Expand All @@ -182,6 +185,7 @@ class Worker:
context_lines: PositiveInt = 3
unsafe: bool = False
skip_answered: bool = False
skip_tasks: bool = False

answers: AnswersMap = field(default_factory=AnswersMap, init=False)
_cleanup_hooks: list[Callable[[], None]] = field(default_factory=list, init=False)
Expand Down Expand Up @@ -766,7 +770,8 @@ def run_copy(self) -> None:
if not self.quiet:
# TODO Unify printing tools
print("") # padding space
self._execute_tasks(self.template.tasks)
if not self.skip_tasks:
self._execute_tasks(self.template.tasks)
except Exception:
if not was_existing and self.cleanup_on_error:
rmtree(self.subproject.local_abspath)
Expand Down
16 changes: 16 additions & 0 deletions docs/configuring.md
Original file line number Diff line number Diff line change
Expand Up @@ -1303,6 +1303,22 @@ exist.
{{999999999999999999999999999999999|ans_random|hash('sha512')}}
```

### `skip_tasks`

- Format: `bool`
- CLI Flags: `-T`, `--skip-tasks`
- Default value: `False`

Skip template [tasks][tasks] execution, if set to `True`.

!!! note

It only skips [tasks][tasks], not [migration tasks][migrations].

!!! question "Does it imply `--trust`?"

This flag does not imply [`--trust`][unsafe], and will do nothing if not used with.

### `subdirectory`

- Format: `str`
Expand Down
2 changes: 0 additions & 2 deletions tests/demo_migrations/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@
import os.path
import sys
from contextlib import suppress
from subprocess import check_call

with open("created-with-tasks.txt", "a", newline="\n") as cwt:
cwt.write(" ".join([os.environ["STAGE"]] + sys.argv[1:]) + "\n")
check_call(["git", "init"])
with suppress(FileNotFoundError):
os.unlink("delete-in-tasks.txt")
32 changes: 25 additions & 7 deletions tests/test_migrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
reason="Windows ignores shebang?",
strict=True,
)
def test_migrations_and_tasks(tmp_path: Path) -> None:
@pytest.mark.parametrize("skip_tasks", [True, False])
def test_migrations_and_tasks(tmp_path: Path, skip_tasks: bool) -> None:
"""Check migrations and tasks are run properly."""
# Convert demo_migrations in a git repository with 2 versions
src, dst = tmp_path / "src", tmp_path / "dst"
Expand All @@ -41,10 +42,20 @@ def test_migrations_and_tasks(tmp_path: Path) -> None:
git("commit", "--allow-empty", "-m2")
git("tag", "v2.0")
# Copy it in v1
run_copy(src_path=str(src), dst_path=dst, vcs_ref="v1.0.0", unsafe=True)
run_copy(
src_path=str(src),
dst_path=dst,
vcs_ref="v1.0.0",
unsafe=True,
skip_tasks=skip_tasks,
)
# Check copy was OK
assert (dst / "created-with-tasks.txt").read_text() == "task 1\ntask 2\n"
assert not (dst / "delete-in-tasks.txt").exists()
if skip_tasks:
assert not (dst / "created-with-tasks.txt").exists()
assert (dst / "delete-in-tasks.txt").exists()
else:
assert (dst / "created-with-tasks.txt").read_text() == "task 1\ntask 2\n"
assert not (dst / "delete-in-tasks.txt").exists()
assert (dst / "delete-in-migration-v2.txt").is_file()
assert not (dst / "migrations.py").exists()
assert not (dst / "tasks.py").exists()
Expand All @@ -54,15 +65,22 @@ def test_migrations_and_tasks(tmp_path: Path) -> None:
assert answers == {"_commit": "v1.0.0", "_src_path": str(src)}
# Save changes in downstream repo
with local.cwd(dst):
git("init")
git("add", ".")
git("config", "user.name", "Copier Test")
git("config", "user.email", "test@copier")
git("commit", "-m1")
# Update it to v2
run_update(dst_path=dst, defaults=True, overwrite=True, unsafe=True)
run_update(
dst_path=dst, defaults=True, overwrite=True, unsafe=True, skip_tasks=skip_tasks
)
# Check update was OK
assert (dst / "created-with-tasks.txt").read_text() == "task 1\ntask 2\n" * 2
assert not (dst / "delete-in-tasks.txt").exists()
if skip_tasks:
assert not (dst / "created-with-tasks.txt").exists()
assert (dst / "delete-in-tasks.txt").exists()
else:
assert (dst / "created-with-tasks.txt").read_text() == "task 1\ntask 2\n" * 2
assert not (dst / "delete-in-tasks.txt").exists()
assert not (dst / "delete-in-migration-v2.txt").exists()
assert not (dst / "migrations.py").exists()
assert not (dst / "tasks.py").exists()
Expand Down
17 changes: 17 additions & 0 deletions tests/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,23 @@ def test_copy_tasks(template_path: str, tmp_path: Path) -> None:
assert (tmp_path / "pyfile").is_file()


def test_copy_skip_tasks(template_path: str, tmp_path: Path) -> None:
copier.run_copy(
template_path,
tmp_path,
quiet=True,
defaults=True,
overwrite=True,
unsafe=True,
skip_tasks=True,
)
assert not (tmp_path / "hello").exists()
assert not (tmp_path / "hello").is_dir()
assert not (tmp_path / "hello" / "world").exists()
assert not (tmp_path / "bye").is_file()
assert not (tmp_path / "pyfile").is_file()


def test_pretend_mode(tmp_path_factory: pytest.TempPathFactory) -> None:
src, dst = map(tmp_path_factory.mktemp, ("src", "dst"))
build_file_tree(
Expand Down

0 comments on commit 4ca2e35

Please sign in to comment.