Skip to content

Commit c587212

Browse files
Use frozen=True for most tests (#268)
* Use frozen=True for most tests * Add missing early return
1 parent 9b1ee0e commit c587212

7 files changed

Lines changed: 106 additions & 63 deletions

File tree

src/usethis/_core/tool.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,7 @@ def use_pre_commit(*, remove: bool = False) -> None:
103103

104104
if not remove:
105105
add_deps_to_group(tool.dev_deps, "dev")
106-
for _tool in ALL_TOOLS:
107-
if _tool.is_used():
108-
_tool.add_pre_commit_repo_configs()
106+
_add_all_tools_pre_commit_configs()
109107

110108
if pyproject_fmt_tool.is_used():
111109
# We will use pre-commit instead of the dev-dep.
@@ -135,6 +133,7 @@ def use_pre_commit(*, remove: bool = False) -> None:
135133
add_deps_to_group(tool.dev_deps, "dev")
136134

137135
uninstall_pre_commit_hooks()
136+
138137
remove_pre_commit_config()
139138
remove_deps_from_group(tool.dev_deps, "dev")
140139

@@ -150,6 +149,12 @@ def use_pre_commit(*, remove: bool = False) -> None:
150149
_requirements_txt_instructions_basic()
151150

152151

152+
def _add_all_tools_pre_commit_configs():
153+
for _tool in ALL_TOOLS:
154+
if _tool.is_used():
155+
_tool.add_pre_commit_repo_configs()
156+
157+
153158
def _add_bitbucket_linter_steps_to_default() -> None:
154159
# This order of adding tools should be synced with the order hard-coded
155160
# in the function which adds steps.

src/usethis/_integrations/pre_commit/core.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from pathlib import Path
22

3-
from usethis._console import info_print, tick_print
3+
from usethis._config import usethis_config
4+
from usethis._console import box_print, info_print, tick_print
45
from usethis._integrations.pre_commit.errors import PreCommitInstallationError
56
from usethis._integrations.uv.call import call_uv_subprocess
67
from usethis._integrations.uv.errors import UVSubprocessFailedError
@@ -22,6 +23,10 @@ def install_pre_commit_hooks() -> None:
2223
Note that this requires pre-commit to be installed. It also requires the user to be
2324
in a git repo.
2425
"""
26+
if usethis_config.frozen:
27+
box_print("Run 'uv run pre-commit install' to register pre-commit with git.")
28+
return
29+
2530
tick_print("Ensuring pre-commit is installed to Git.")
2631
try:
2732
call_uv_subprocess(["run", "pre-commit", "install"])
@@ -45,6 +50,12 @@ def uninstall_pre_commit_hooks() -> None:
4550
Note that this requires pre-commit to be installed. It also requires the user to be
4651
in a git repo.
4752
"""
53+
if usethis_config.frozen:
54+
box_print(
55+
"Run 'uv run pre-commit uninstall' to deregister pre-commit with git."
56+
)
57+
return
58+
4859
tick_print("Ensuring pre-commit hooks are uninstalled.")
4960
try:
5061
call_uv_subprocess(["run", "pre-commit", "uninstall"])

src/usethis/_integrations/uv/call.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,15 @@ def call_uv_subprocess(args: list[str]) -> str:
1212
"""
1313
read_pyproject_toml_from_path.cache_clear()
1414
new_args = ["uv", *args]
15-
if usethis_config.frozen:
15+
if usethis_config.frozen and args[0] in {
16+
"run",
17+
"add",
18+
"remove",
19+
"sync",
20+
"lock",
21+
"export",
22+
"tree",
23+
}:
1624
new_args.append("--frozen")
1725
try:
1826
return call_subprocess(new_args)

tests/conftest.py

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1+
import shutil
12
from collections.abc import Generator
23
from enum import Enum
34
from pathlib import Path
45

56
import pytest
67

78
from usethis._config import usethis_config
8-
from usethis._integrations.uv.call import call_uv_subprocess
9+
from usethis._integrations.uv.call import call_subprocess, call_uv_subprocess
910
from usethis._test import change_cwd, is_offline
1011

1112

12-
@pytest.fixture
13-
def uv_init_dir(tmp_path: Path) -> Path:
13+
@pytest.fixture(scope="session")
14+
def _uv_init_dir(tmp_path_factory: pytest.TempPathFactory) -> Path:
15+
tmp_path = tmp_path_factory.mktemp("uv_init")
1416
with change_cwd(tmp_path):
1517
call_uv_subprocess(
1618
[
@@ -22,21 +24,39 @@ def uv_init_dir(tmp_path: Path) -> Path:
2224
"none",
2325
]
2426
)
27+
2528
return tmp_path
2629

2730

2831
@pytest.fixture
29-
def uv_init_repo_dir(tmp_path: Path) -> Path:
32+
def uv_init_dir(tmp_path: Path, _uv_init_dir: Path) -> Generator[Path, None, None]:
3033
with change_cwd(tmp_path):
31-
call_uv_subprocess(
32-
[
33-
"init",
34-
"--lib",
35-
"--python",
36-
"3.12",
37-
]
34+
shutil.copytree(
35+
src=_uv_init_dir, dst=tmp_path, symlinks=True, dirs_exist_ok=True
3836
)
39-
return tmp_path
37+
38+
with usethis_config.set(frozen=True):
39+
yield tmp_path
40+
41+
42+
@pytest.fixture
43+
def uv_init_repo_dir(tmp_path: Path, _uv_init_dir: Path) -> Generator[Path, None, None]:
44+
with change_cwd(tmp_path):
45+
shutil.copytree(
46+
src=_uv_init_dir, dst=tmp_path, symlinks=True, dirs_exist_ok=True
47+
)
48+
49+
call_subprocess(["git", "init"])
50+
51+
with usethis_config.set(frozen=True):
52+
yield tmp_path
53+
54+
55+
@pytest.fixture
56+
def uv_env_dir(uv_init_repo_dir: Path) -> Generator[Path, None, None]:
57+
"""A directory with a git repo, as well as uv-unfrozen project; allow venv and lockfile."""
58+
with change_cwd(uv_init_repo_dir), usethis_config.set(frozen=False):
59+
yield uv_init_repo_dir
4060

4161

4262
class NetworkConn(Enum):

tests/test_install.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ def usethis_installed_dir(
2121
usethis_dev_dir,
2222
copy_usethis_dev_dir,
2323
# The git repo is too big and we don't need it
24-
ignore=shutil.ignore_patterns(".git"),
24+
# Also ignore the virtual environment
25+
ignore=shutil.ignore_patterns(".git", ".venv"),
26+
symlinks=True,
2527
)
2628

2729
with change_cwd(copy_usethis_dev_dir):
@@ -39,12 +41,12 @@ def usethis_installed_dir(
3941

4042

4143
class TestInstalledInOwnVenv:
42-
def test_help(self, usethis_installed_dir):
44+
def test_help(self, usethis_installed_dir: Path):
4345
with change_cwd(usethis_installed_dir):
4446
# Should run without error
4547
call_subprocess(["usethis", "--help"])
4648

47-
def test_add_pytest(self, usethis_installed_dir):
49+
def test_add_pytest(self, usethis_installed_dir: Path):
4850
with change_cwd(usethis_installed_dir):
4951
# Should run without error
5052
call_subprocess(["usethis", "tool", "pytest"])

tests/usethis/_core/test_tool.py

Lines changed: 35 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -225,24 +225,24 @@ def test_run_deptry_pass(self, uv_init_dir: Path):
225225

226226
@pytest.mark.usefixtures("_vary_network_conn")
227227
def test_pre_commit_after(
228-
self, uv_init_repo_dir: Path, capfd: pytest.CaptureFixture[str]
228+
self, uv_env_dir: Path, capfd: pytest.CaptureFixture[str]
229229
):
230230
# Act
231-
with change_cwd(uv_init_repo_dir):
231+
with change_cwd(uv_env_dir):
232232
use_deptry()
233233
use_pre_commit()
234234

235235
# Assert
236236
hook_names = get_hook_names()
237237

238238
# 1. File exists
239-
assert (uv_init_repo_dir / ".pre-commit-config.yaml").exists()
239+
assert (uv_env_dir / ".pre-commit-config.yaml").exists()
240240

241241
# 2. Hook is in the file
242242
assert "deptry" in hook_names
243243

244244
# 3. Test file contents
245-
assert (uv_init_repo_dir / ".pre-commit-config.yaml").read_text() == (
245+
assert (uv_env_dir / ".pre-commit-config.yaml").read_text() == (
246246
"""\
247247
repos:
248248
- repo: local
@@ -459,9 +459,9 @@ def test_remove(
459459
class TestPreCommit:
460460
class TestAdd:
461461
@pytest.mark.usefixtures("_vary_network_conn")
462-
def test_fresh(self, uv_init_repo_dir: Path, capfd: pytest.CaptureFixture[str]):
462+
def test_fresh(self, uv_env_dir: Path, capfd: pytest.CaptureFixture[str]):
463463
# Act
464-
with change_cwd(uv_init_repo_dir):
464+
with change_cwd(uv_env_dir):
465465
use_pre_commit()
466466

467467
# Assert
@@ -483,8 +483,8 @@ def test_fresh(self, uv_init_repo_dir: Path, capfd: pytest.CaptureFixture[str]):
483483
"☐ Run 'pre-commit run --all-files' to run the hooks manually.\n"
484484
)
485485
# Config file
486-
assert (uv_init_repo_dir / ".pre-commit-config.yaml").exists()
487-
contents = (uv_init_repo_dir / ".pre-commit-config.yaml").read_text()
486+
assert (uv_env_dir / ".pre-commit-config.yaml").exists()
487+
contents = (uv_env_dir / ".pre-commit-config.yaml").read_text()
488488
assert contents == (
489489
"""\
490490
repos:
@@ -531,28 +531,28 @@ def test_config_file_already_exists(self, uv_init_repo_dir: Path):
531531
)
532532

533533
@pytest.mark.usefixtures("_vary_network_conn")
534-
def test_bad_commit(self, uv_init_repo_dir: Path):
534+
def test_bad_commit(self, uv_env_dir: Path):
535535
# Act
536-
with change_cwd(uv_init_repo_dir):
536+
with change_cwd(uv_env_dir):
537537
use_pre_commit()
538-
subprocess.run(["git", "add", "."], cwd=uv_init_repo_dir, check=True)
538+
subprocess.run(["git", "add", "."], cwd=uv_env_dir, check=True)
539539
subprocess.run(
540-
["git", "commit", "-m", "Good commit"], cwd=uv_init_repo_dir, check=True
540+
["git", "commit", "-m", "Good commit"], cwd=uv_env_dir, check=True
541541
)
542542

543543
# Assert
544-
(uv_init_repo_dir / "pyproject.toml").write_text("[")
545-
subprocess.run(["git", "add", "."], cwd=uv_init_repo_dir, check=True)
544+
(uv_env_dir / "pyproject.toml").write_text("[")
545+
subprocess.run(["git", "add", "."], cwd=uv_env_dir, check=True)
546546
with pytest.raises(subprocess.CalledProcessError):
547547
subprocess.run(
548548
["git", "commit", "-m", "Bad commit"],
549-
cwd=uv_init_repo_dir,
549+
cwd=uv_env_dir,
550550
check=True,
551551
)
552552

553553
@pytest.mark.usefixtures("_vary_network_conn")
554-
def test_requirements_txt_used(self, uv_init_repo_dir: Path):
555-
with change_cwd(uv_init_repo_dir):
554+
def test_requirements_txt_used(self, uv_env_dir: Path):
555+
with change_cwd(uv_env_dir):
556556
# Arrange
557557
use_requirements_txt()
558558

@@ -603,11 +603,9 @@ def test_dep(self, uv_init_repo_dir: Path):
603603
assert not get_deps_from_group("dev")
604604

605605
@pytest.mark.usefixtures("_vary_network_conn")
606-
def test_stdout(
607-
self, uv_init_repo_dir: Path, capfd: pytest.CaptureFixture[str]
608-
):
606+
def test_stdout(self, uv_env_dir: Path, capfd: pytest.CaptureFixture[str]):
609607
# Arrange
610-
(uv_init_repo_dir / ".pre-commit-config.yaml").write_text(
608+
(uv_env_dir / ".pre-commit-config.yaml").write_text(
611609
"""\
612610
repos:
613611
- repo: local
@@ -617,7 +615,7 @@ def test_stdout(
617615
)
618616

619617
# Act
620-
with change_cwd(uv_init_repo_dir):
618+
with change_cwd(uv_env_dir):
621619
use_pre_commit(remove=True)
622620

623621
# Assert
@@ -632,9 +630,9 @@ def test_stdout(
632630

633631
@pytest.mark.usefixtures("_vary_network_conn")
634632
def test_requirements_txt_used(
635-
self, uv_init_repo_dir: Path, capfd: pytest.CaptureFixture[str]
633+
self, uv_env_dir: Path, capfd: pytest.CaptureFixture[str]
636634
):
637-
with change_cwd(uv_init_repo_dir):
635+
with change_cwd(uv_env_dir):
638636
# Arrange
639637
with usethis_config.set(quiet=True):
640638
use_pre_commit()
@@ -654,9 +652,9 @@ def test_requirements_txt_used(
654652

655653
@pytest.mark.usefixtures("_vary_network_conn")
656654
def test_pyproject_fmt_used(
657-
self, uv_init_repo_dir: Path, capfd: pytest.CaptureFixture[str]
655+
self, uv_env_dir: Path, capfd: pytest.CaptureFixture[str]
658656
):
659-
with change_cwd(uv_init_repo_dir):
657+
with change_cwd(uv_env_dir):
660658
# Arrange
661659
with usethis_config.set(quiet=True):
662660
use_pre_commit()
@@ -692,13 +690,12 @@ def test_prexisting(self, uv_init_repo_dir: Path):
692690
contents = (uv_init_repo_dir / "bitbucket-pipelines.yml").read_text()
693691
assert "pre-commit" in contents
694692

695-
def test_remove(
696-
self, uv_init_repo_dir: Path, capfd: pytest.CaptureFixture[str]
697-
):
693+
def test_remove(self, uv_env_dir: Path, capfd: pytest.CaptureFixture[str]):
698694
# Arrange
699-
with change_cwd(uv_init_repo_dir), usethis_config.set(quiet=True):
695+
with change_cwd(uv_env_dir):
700696
use_pre_commit()
701-
(uv_init_repo_dir / "bitbucket-pipelines.yml").write_text(
697+
capfd.readouterr()
698+
(uv_env_dir / "bitbucket-pipelines.yml").write_text(
702699
"""\
703700
image: atlassian/default-image:3
704701
pipelines:
@@ -711,11 +708,11 @@ def test_remove(
711708
)
712709

713710
# Act
714-
with change_cwd(uv_init_repo_dir):
711+
with change_cwd(uv_env_dir):
715712
use_pre_commit(remove=True)
716713

717714
# Assert
718-
contents = (uv_init_repo_dir / "bitbucket-pipelines.yml").read_text()
715+
contents = (uv_env_dir / "bitbucket-pipelines.yml").read_text()
719716
assert (
720717
contents
721718
== """\
@@ -1409,7 +1406,7 @@ def test_start_from_uv_init(
14091406
self, uv_init_dir: Path, capfd: pytest.CaptureFixture[str]
14101407
):
14111408
# Act
1412-
with change_cwd(uv_init_dir):
1409+
with change_cwd(uv_init_dir), usethis_config.set(frozen=False):
14131410
use_requirements_txt()
14141411

14151412
# Assert
@@ -1425,7 +1422,7 @@ def test_start_from_uv_init(
14251422
def test_start_from_uv_locked(
14261423
self, uv_init_dir: Path, capfd: pytest.CaptureFixture[str]
14271424
):
1428-
with change_cwd(uv_init_dir):
1425+
with change_cwd(uv_init_dir), usethis_config.set(frozen=False):
14291426
# Arrange
14301427
call_uv_subprocess(["lock"])
14311428

@@ -1444,10 +1441,10 @@ def test_start_from_uv_locked(
14441441
def test_pre_commit(
14451442
self, uv_init_repo_dir: Path, capfd: pytest.CaptureFixture[str]
14461443
):
1447-
with change_cwd(uv_init_repo_dir):
1444+
with change_cwd(uv_init_repo_dir), usethis_config.set(frozen=False):
14481445
# Arrange
1449-
with usethis_config.set(quiet=True):
1450-
use_pre_commit()
1446+
use_pre_commit()
1447+
capfd.readouterr()
14511448

14521449
# Act
14531450
use_requirements_txt()

0 commit comments

Comments
 (0)