Skip to content

Commit 2af33db

Browse files
Update print_how_to_use for all tools to use new `get_install_metho… (#814)
* Update `print_how_to_use` for all tools to use new `get_install_method` method for determining the approach to recommend for using the tool * Fix schema violation in pre-commit integration test * Provide explicit pre-commit config for a few TestPrintHowToUse tests * Update test to reflect new beheaviour of Import Linter's `print_how_to_use` (i.e. prefer using directly rather than via pre-commit; less verbose and more consistent behaviour viz. other tools)
1 parent ca3e8e7 commit 2af33db

File tree

9 files changed

+126
-83
lines changed

9 files changed

+126
-83
lines changed

src/usethis/_tool/impl/deptry.py

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,18 @@
33
from pathlib import Path
44
from typing import TYPE_CHECKING
55

6+
from typing_extensions import assert_never
7+
68
from usethis._console import box_print, info_print, tick_print
79
from usethis._integrations.ci.bitbucket.anchor import (
810
ScriptItemAnchor as BitbucketScriptItemAnchor,
911
)
1012
from usethis._integrations.ci.bitbucket.schema import Script as BitbucketScript
1113
from usethis._integrations.ci.bitbucket.schema import Step as BitbucketStep
1214
from usethis._integrations.file.pyproject_toml.io_ import PyprojectTOMLManager
13-
from usethis._integrations.pre_commit.schema import (
14-
HookDefinition,
15-
Language,
16-
LocalRepo,
17-
)
15+
from usethis._integrations.pre_commit.schema import HookDefinition, Language, LocalRepo
1816
from usethis._integrations.project.layout import get_source_dir_str
19-
from usethis._integrations.uv.deps import (
20-
Dependency,
21-
)
17+
from usethis._integrations.uv.deps import Dependency
2218
from usethis._integrations.uv.used import is_uv_used
2319
from usethis._tool.base import Tool
2420
from usethis._tool.config import (
@@ -42,10 +38,23 @@ def name(self) -> str:
4238

4339
def print_how_to_use(self) -> None:
4440
_dir = get_source_dir_str()
45-
if is_uv_used():
46-
box_print(f"Run 'uv run deptry {_dir}' to run deptry.")
41+
install_method = self.get_install_method()
42+
if install_method == "pre-commit":
43+
if is_uv_used():
44+
box_print(
45+
f"Run 'uv run pre-commit run deptry --all-files' to run {self.name}."
46+
)
47+
else:
48+
box_print(
49+
f"Run 'pre-commit run deptry --all-files' to run {self.name}."
50+
)
51+
elif install_method == "devdep" or install_method is None:
52+
if is_uv_used():
53+
box_print(f"Run 'uv run deptry {_dir}' to run deptry.")
54+
else:
55+
box_print(f"Run 'deptry {_dir}' to run deptry.")
4756
else:
48-
box_print(f"Run 'deptry {_dir}' to run deptry.")
57+
assert_never(install_method)
4958

5059
def get_dev_deps(self, *, unconditional: bool = False) -> list[Dependency]:
5160
return [Dependency(name="deptry")]

src/usethis/_tool/impl/import_linter.py

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
from pathlib import Path
66
from typing import TYPE_CHECKING
77

8+
from typing_extensions import assert_never
9+
810
from usethis._config import usethis_config
9-
from usethis._config_file import (
10-
DotImportLinterManager,
11-
)
11+
from usethis._config_file import DotImportLinterManager
1212
from usethis._console import box_print, info_print, warn_print
1313
from usethis._integrations.ci.bitbucket.anchor import (
1414
ScriptItemAnchor as BitbucketScriptItemAnchor,
@@ -18,39 +18,25 @@
1818
from usethis._integrations.file.ini.io_ import INIFileManager
1919
from usethis._integrations.file.pyproject_toml.io_ import PyprojectTOMLManager
2020
from usethis._integrations.file.setup_cfg.io_ import SetupCFGManager
21-
from usethis._integrations.pre_commit.schema import (
22-
HookDefinition,
23-
Language,
24-
LocalRepo,
25-
)
21+
from usethis._integrations.pre_commit.schema import HookDefinition, Language, LocalRepo
2622
from usethis._integrations.project.errors import ImportGraphBuildFailedError
2723
from usethis._integrations.project.imports import (
2824
LayeredArchitecture,
2925
get_layered_architectures,
3026
)
3127
from usethis._integrations.project.name import get_project_name
3228
from usethis._integrations.project.packages import get_importable_packages
33-
from usethis._integrations.uv.deps import (
34-
Dependency,
35-
)
29+
from usethis._integrations.uv.deps import Dependency
3630
from usethis._integrations.uv.used import is_uv_used
3731
from usethis._tool.base import Tool
38-
from usethis._tool.config import (
39-
ConfigEntry,
40-
ConfigItem,
41-
ConfigSpec,
42-
NoConfigValue,
43-
)
44-
from usethis._tool.impl.pre_commit import PreCommitTool
32+
from usethis._tool.config import ConfigEntry, ConfigItem, ConfigSpec, NoConfigValue
4533
from usethis._tool.impl.ruff import RuffTool
4634
from usethis._tool.pre_commit import PreCommitConfig
4735
from usethis._tool.rule import RuleConfig
4836

4937
if TYPE_CHECKING:
5038
from usethis._io import KeyValueFileManager
51-
from usethis._tool.config import (
52-
ResolutionT,
53-
)
39+
from usethis._tool.config import ResolutionT
5440

5541

5642
IMPORT_LINTER_CONTRACT_MIN_MODULE_COUNT = 3
@@ -77,7 +63,8 @@ def print_how_to_use(self) -> None:
7763
info_print(
7864
"For more info see <https://docs.python.org/3/tutorial/modules.html#packages>"
7965
)
80-
if PreCommitTool().is_used():
66+
install_method = self.get_install_method()
67+
if install_method == "pre-commit":
8168
if is_uv_used():
8269
box_print(
8370
f"Run 'uv run pre-commit run import-linter --all-files' to run {self.name}."
@@ -86,10 +73,13 @@ def print_how_to_use(self) -> None:
8673
box_print(
8774
f"Run 'pre-commit run import-linter --all-files' to run {self.name}."
8875
)
89-
elif is_uv_used():
90-
box_print(f"Run 'uv run lint-imports' to run {self.name}.")
76+
elif install_method == "devdep" or install_method is None:
77+
if is_uv_used():
78+
box_print(f"Run 'uv run lint-imports' to run {self.name}.")
79+
else:
80+
box_print(f"Run 'lint-imports' to run {self.name}.")
9181
else:
92-
box_print(f"Run 'lint-imports' to run {self.name}.")
82+
assert_never(install_method)
9383

9484
def get_dev_deps(self, *, unconditional: bool = False) -> list[Dependency]:
9585
# We need to add the import-linter package itself as a dev dependency.

src/usethis/_tool/impl/pyproject_fmt.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,20 @@
22

33
from pathlib import Path
44

5+
from typing_extensions import assert_never
6+
57
from usethis._console import box_print
68
from usethis._integrations.ci.bitbucket.anchor import (
79
ScriptItemAnchor as BitbucketScriptItemAnchor,
810
)
911
from usethis._integrations.ci.bitbucket.schema import Script as BitbucketScript
1012
from usethis._integrations.ci.bitbucket.schema import Step as BitbucketStep
1113
from usethis._integrations.file.pyproject_toml.io_ import PyprojectTOMLManager
12-
from usethis._integrations.pre_commit.schema import (
13-
HookDefinition,
14-
UriRepo,
15-
)
16-
from usethis._integrations.uv.deps import (
17-
Dependency,
18-
)
14+
from usethis._integrations.pre_commit.schema import HookDefinition, UriRepo
15+
from usethis._integrations.uv.deps import Dependency
1916
from usethis._integrations.uv.used import is_uv_used
2017
from usethis._tool.base import Tool
2118
from usethis._tool.config import ConfigEntry, ConfigItem, ConfigSpec
22-
from usethis._tool.impl.pre_commit import PreCommitTool
2319
from usethis._tool.pre_commit import PreCommitConfig
2420

2521

@@ -30,7 +26,8 @@ def name(self) -> str:
3026
return "pyproject-fmt"
3127

3228
def print_how_to_use(self) -> None:
33-
if PreCommitTool().is_used():
29+
install_method = self.get_install_method()
30+
if install_method == "pre-commit":
3431
if is_uv_used():
3532
box_print(
3633
f"Run 'uv run pre-commit run pyproject-fmt --all-files' to run {self.name}."
@@ -39,10 +36,15 @@ def print_how_to_use(self) -> None:
3936
box_print(
4037
f"Run 'pre-commit run pyproject-fmt --all-files' to run {self.name}."
4138
)
42-
elif is_uv_used():
43-
box_print(f"Run 'uv run pyproject-fmt pyproject.toml' to run {self.name}.")
39+
elif install_method == "devdep" or install_method is None:
40+
if is_uv_used():
41+
box_print(
42+
f"Run 'uv run pyproject-fmt pyproject.toml' to run {self.name}."
43+
)
44+
else:
45+
box_print(f"Run 'pyproject-fmt pyproject.toml' to run {self.name}.")
4446
else:
45-
box_print(f"Run 'pyproject-fmt pyproject.toml' to run {self.name}.")
47+
assert_never(install_method)
4648

4749
def get_dev_deps(self, *, unconditional: bool = False) -> list[Dependency]:
4850
return [Dependency(name="pyproject-fmt")]

src/usethis/_tool/impl/requirements_txt.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,12 @@
33
from pathlib import Path
44
from typing import TYPE_CHECKING
55

6+
from typing_extensions import assert_never
7+
68
from usethis._console import box_print
7-
from usethis._integrations.pre_commit.schema import (
8-
HookDefinition,
9-
Language,
10-
LocalRepo,
11-
)
9+
from usethis._integrations.pre_commit.schema import HookDefinition, Language, LocalRepo
1210
from usethis._integrations.uv.used import is_uv_used
1311
from usethis._tool.base import Tool
14-
from usethis._tool.impl.pre_commit import PreCommitTool
1512
from usethis._tool.pre_commit import PreCommitConfig
1613

1714
if TYPE_CHECKING:
@@ -28,21 +25,24 @@ def name(self) -> str:
2825
return "requirements.txt"
2926

3027
def print_how_to_use(self) -> None:
31-
if PreCommitTool().is_used():
28+
install_method = self.get_install_method()
29+
if install_method == "pre-commit":
3230
if is_uv_used():
3331
box_print(
3432
"Run 'uv run pre-commit run uv-export' to write 'requirements.txt'."
3533
)
3634
else:
3735
box_print("Run 'pre-commit run uv-export' to write 'requirements.txt'.")
38-
else:
36+
elif install_method == "devdep" or install_method is None:
3937
if not is_uv_used():
4038
# This is a very crude approach as a temporary measure.
4139
box_print("Install uv to use 'uv export'.")
4240

4341
box_print(
4442
"Run 'uv export --no-default-groups -o=requirements.txt' to write 'requirements.txt'."
4543
)
44+
else:
45+
assert_never(install_method)
4646

4747
def get_dev_deps(self, *, unconditional: bool = False) -> list[Dependency]:
4848
return []

src/usethis/_tool/impl/ruff.py

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@
55

66
from typing_extensions import assert_never
77

8-
from usethis._config_file import (
9-
DotRuffTOMLManager,
10-
RuffTOMLManager,
11-
)
8+
from usethis._config_file import DotRuffTOMLManager, RuffTOMLManager
129
from usethis._console import box_print, tick_print
1310
from usethis._integrations.ci.bitbucket.anchor import (
1411
ScriptItemAnchor as BitbucketScriptItemAnchor,
@@ -23,9 +20,7 @@
2320
Language,
2421
LocalRepo,
2522
)
26-
from usethis._integrations.uv.deps import (
27-
Dependency,
28-
)
23+
from usethis._integrations.uv.deps import Dependency
2924
from usethis._integrations.uv.used import is_uv_used
3025
from usethis._tool.base import Tool
3126
from usethis._tool.config import (
@@ -72,21 +67,44 @@ def __init__(
7267
def name(self) -> str:
7368
return "Ruff"
7469

75-
def print_how_to_use(self) -> None:
76-
if is_uv_used():
77-
if self.is_linter_used():
78-
box_print(
79-
"Run 'uv run ruff check --fix' to run the Ruff linter with autofixes."
80-
)
81-
if self.is_formatter_used():
82-
box_print("Run 'uv run ruff format' to run the Ruff formatter.")
70+
def print_how_to_use(self) -> None: # noqa: PLR0912
71+
install_method = self.get_install_method()
72+
if install_method == "pre-commit":
73+
if is_uv_used():
74+
if self.is_linter_used():
75+
box_print(
76+
"Run 'uv run pre-commit run ruff --all-files' to run the Ruff linter."
77+
)
78+
if self.is_formatter_used():
79+
box_print(
80+
"Run 'uv run pre-commit run ruff-format' to run the Ruff formatter."
81+
)
82+
else:
83+
if self.is_linter_used():
84+
box_print(
85+
"Run 'pre-commit run ruff --all-files' to run the Ruff linter."
86+
)
87+
if self.is_formatter_used():
88+
box_print(
89+
"Run 'pre-commit run ruff-format' to run the Ruff formatter."
90+
)
91+
elif install_method == "devdep" or install_method is None:
92+
if is_uv_used():
93+
if self.is_linter_used():
94+
box_print(
95+
"Run 'uv run ruff check --fix' to run the Ruff linter with autofixes."
96+
)
97+
if self.is_formatter_used():
98+
box_print("Run 'uv run ruff format' to run the Ruff formatter.")
99+
else:
100+
if self.is_linter_used():
101+
box_print(
102+
"Run 'ruff check --fix' to run the Ruff linter with autofixes."
103+
)
104+
if self.is_formatter_used():
105+
box_print("Run 'ruff format' to run the Ruff formatter.")
83106
else:
84-
if self.is_linter_used():
85-
box_print(
86-
"Run 'ruff check --fix' to run the Ruff linter with autofixes."
87-
)
88-
if self.is_formatter_used():
89-
box_print("Run 'ruff format' to run the Ruff formatter.")
107+
assert_never(install_method)
90108

91109
def get_dev_deps(self, *, unconditional: bool = False) -> list[Dependency]:
92110
return [Dependency(name="ruff")]

tests/usethis/_core/test_core_ci.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def test_contents(
100100
self, uv_init_dir: Path, capfd: pytest.CaptureFixture[str]
101101
):
102102
# Arrange
103-
(uv_init_dir / ".pre-commit-config.yaml").touch()
103+
(uv_init_dir / ".pre-commit-config.yaml").write_text("repos: []")
104104

105105
# Act
106106
with change_cwd(uv_init_dir), files_manager():

tests/usethis/_core/test_core_tool.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1439,7 +1439,7 @@ def test_config(
14391439
"✔ Adding hook 'import-linter' to '.pre-commit-config.yaml'.\n"
14401440
"ℹ Ensure '__init__.py' files are used in your packages.\n" # noqa: RUF001
14411441
"ℹ For more info see <https://docs.python.org/3/tutorial/modules.html#packages>\n" # noqa: RUF001
1442-
"☐ Run 'uv run pre-commit run import-linter --all-files' to run Import Linter.\n"
1442+
"☐ Run 'uv run lint-imports' to run Import Linter.\n"
14431443
)
14441444

14451445
class TestBitbucketIntegration:

tests/usethis/_tool/impl/test_import_linter.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,14 @@ def test_pre_commit_and_uv(
1414
):
1515
# Arrange
1616
(tmp_path / "uv.lock").touch()
17-
(tmp_path / ".pre-commit-config.yaml").touch()
17+
(tmp_path / ".pre-commit-config.yaml").write_text("""\
18+
repos:
19+
- repo: local
20+
hooks:
21+
- id: import-linter
22+
name: import-linter
23+
entry: uv run --frozen --offline lint-imports
24+
""")
1825
(tmp_path / "ruff.toml").touch()
1926

2027
# Act
@@ -32,8 +39,15 @@ def test_pre_commit_no_uv(
3239
self, tmp_path: Path, capfd: pytest.CaptureFixture[str]
3340
):
3441
# Arrange
35-
(tmp_path / ".pre-commit-config.yaml").touch()
36-
(tmp_path / "ruff.toml").touch()
42+
(tmp_path / ".pre-commit-config.yaml").write_text("""\
43+
repos:
44+
- repo: local
45+
hooks:
46+
- id: import-linter
47+
name: import-linter
48+
entry: uv run --frozen --offline lint-imports
49+
""")
50+
(tmp_path / "ruff.toml").touch() # For avoid info/hint messages
3751

3852
# Act
3953
with change_cwd(tmp_path), files_manager():

tests/usethis/_tool/impl/test_requirements_txt.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,17 @@ def test_pre_commit_and_not_uv(
1313
self, tmp_path: Path, capfd: pytest.CaptureFixture[str]
1414
):
1515
# Arrange
16-
(tmp_path / ".pre-commit-config.yaml").touch()
16+
(tmp_path / ".pre-commit-config.yaml").write_text("""\
17+
repos:
18+
- repo: local
19+
hooks:
20+
- id: uv-export
21+
name: uv-export
22+
entry: uv export --frozen --offline --quiet -o=requirements.txt
23+
language: system
24+
pass_filenames: false
25+
require_serial: true
26+
""")
1727

1828
# Act
1929
with change_cwd(tmp_path), files_manager():

0 commit comments

Comments
 (0)