Skip to content

Commit e60c8a0

Browse files
authored
Fix pytask clean when git is not installed. (#276)
1 parent 0bfbb7f commit e60c8a0

File tree

5 files changed

+65
-8
lines changed

5 files changed

+65
-8
lines changed

docs/source/changes.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,16 @@ chronological order. Releases follow [semantic versioning](https://semver.org/)
55
releases are available on [PyPI](https://pypi.org/project/pytask) and
66
[Anaconda.org](https://anaconda.org/conda-forge/pytask).
77

8-
## 0.2.2 - 2022-xx-xx
8+
## 0.2.3 - 2022-xx-xx
9+
10+
- {pull}`276` fixes `pytask clean` when git is not installed. Fixes {issue}`275`.
11+
12+
## 0.2.2 - 2022-05-14
913

1014
- {pull}`267` fixes the info under the live execution table to show the total number of
1115
tasks also for pytask-parallel.
16+
- {pull}`273` reworks `pytask clean` so that it ignores files tracked by git. Resolves
17+
{issue}`146`.
1218

1319
## 0.2.1 - 2022-04-28
1420

src/_pytask/clean.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from _pytask.exceptions import CollectionError
2121
from _pytask.git import get_all_files
2222
from _pytask.git import get_root
23+
from _pytask.git import is_git_installed
2324
from _pytask.nodes import Task
2425
from _pytask.outcomes import ExitCode
2526
from _pytask.path import find_common_ancestor
@@ -206,12 +207,15 @@ def _collect_all_paths_known_to_pytask(session: Session) -> set[Path]:
206207
known_paths.add(session.config["database_filename"])
207208

208209
# Add files tracked by git.
209-
git_root = get_root(session.config["root"])
210-
if git_root is not None:
211-
paths_known_by_git = get_all_files(session.config["root"])
212-
absolute_paths_known_by_git = [git_root.joinpath(p) for p in paths_known_by_git]
213-
known_paths.update(absolute_paths_known_by_git)
214-
known_paths.add(git_root / ".git")
210+
if is_git_installed():
211+
git_root = get_root(session.config["root"])
212+
if git_root is not None:
213+
paths_known_by_git = get_all_files(session.config["root"])
214+
absolute_paths_known_by_git = [
215+
git_root.joinpath(p) for p in paths_known_by_git
216+
]
217+
known_paths.update(absolute_paths_known_by_git)
218+
known_paths.add(git_root / ".git")
215219

216220
return known_paths
217221

src/_pytask/git.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
"""This module contains all functions related to git."""
22
from __future__ import annotations
33

4+
import shutil
45
import subprocess
56
from os import PathLike
67
from pathlib import Path
78
from typing import Any
89

910

11+
def is_git_installed() -> bool:
12+
"""Check if git is installed."""
13+
return shutil.which("git") is not None
14+
15+
1016
def cmd_output(*cmd: str, **kwargs: Any) -> tuple[int, str, str]:
1117
"""Execute a command and capture the output."""
1218
r = subprocess.run(cmd, capture_output=True, **kwargs)
@@ -48,6 +54,6 @@ def get_root(cwd: PathLike[str] | None) -> Path | None:
4854
_, stdout, _ = cmd_output("git", "rev-parse", "--show-cdup", cwd=cwd)
4955
root = Path(cwd) / stdout.strip()
5056
except subprocess.CalledProcessError:
51-
# Either git is not installed or user is not in git repo.
57+
# User is not in git repo.
5258
root = None
5359
return root

tests/test_clean.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,3 +221,31 @@ def test_dont_remove_files_tracked_by_git(runner, git_project):
221221
assert "tracked.txt" not in result.output
222222
assert "in_tracked.txt" not in result.output
223223
assert ".git" not in result.output
224+
225+
226+
@pytest.mark.end_to_end
227+
def test_clean_git_files_if_git_is_not_installed(monkeypatch, runner, git_project):
228+
monkeypatch.setattr(
229+
"_pytask.clean.is_git_installed", lambda *x: False # noqa: U100
230+
)
231+
232+
result = runner.invoke(cli, ["clean", git_project.as_posix()])
233+
234+
assert result.exit_code == ExitCode.OK
235+
assert "tracked.txt" in result.output
236+
assert "in_tracked.txt" not in result.output
237+
assert ".git" not in result.output
238+
239+
240+
@pytest.mark.end_to_end
241+
def test_clean_git_files_if_git_is_installed_but_git_root_is_not_found(
242+
monkeypatch, runner, git_project
243+
):
244+
monkeypatch.setattr("_pytask.clean.get_root", lambda x: None) # noqa: U100
245+
246+
result = runner.invoke(cli, ["clean", git_project.as_posix()])
247+
248+
assert result.exit_code == ExitCode.OK
249+
assert "tracked.txt" in result.output
250+
assert "in_tracked.txt" not in result.output
251+
assert ".git" not in result.output

tests/test_git.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from __future__ import annotations
2+
3+
import pytest
4+
from _pytask.git import is_git_installed
5+
6+
7+
@pytest.mark.parametrize("mock_return, expected", [(True, True), (None, False)])
8+
def test_is_git_installed(monkeypatch, mock_return, expected):
9+
monkeypatch.setattr(
10+
"_pytask.git.shutil.which", lambda *x: mock_return # noqa: U100
11+
)
12+
result = is_git_installed()
13+
assert result is expected

0 commit comments

Comments
 (0)