Skip to content

Commit 7c45f33

Browse files
Use ALL_TOOLS as single source of truth for canonical tool ordering (#1793)
* Initial plan * Use ALL_TOOLS as single source of truth for canonical tool ordering Agent-Logs-Url: https://github.com/usethis-python/usethis-python/sessions/2fe957e7-5906-45a0-a2ae-bb7790076083 Co-authored-by: nathanjmcdougall <18602289+nathanjmcdougall@users.noreply.github.com> * Use ALL_TOOL_SPECS from _tool.impl.spec to avoid _OTHER_TOOLS duplication Agent-Logs-Url: https://github.com/usethis-python/usethis-python/sessions/a38b59a7-2008-4870-a1f4-61d44b04cbba Co-authored-by: nathanjmcdougall <18602289+nathanjmcdougall@users.noreply.github.com> * Remove OTHER_TOOLS from all_.py — no longer needed after ALL_TOOL_SPECS refactor Agent-Logs-Url: https://github.com/usethis-python/usethis-python/sessions/f9182353-f655-4e0f-ac44-f175b44a686d Co-authored-by: nathanjmcdougall <18602289+nathanjmcdougall@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: nathanjmcdougall <18602289+nathanjmcdougall@users.noreply.github.com> Co-authored-by: Nathan McDougall <nathan.j.mcdougall@gmail.com>
1 parent 4282401 commit 7c45f33

9 files changed

Lines changed: 77 additions & 56 deletions

File tree

.importlinter

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ type = layers
9797
containers =
9898
usethis._tool.impl.spec
9999
layers =
100+
all_
100101
pyproject_toml
101102
codespell | deptry | import_linter | mkdocs | pyproject_fmt | requirements_txt | tach | ty
102103
ruff

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ usethis # usethis: Automatically manage Python tooling
153153
│ │ ├── tach # Tach tool implementation.
154154
│ │ └── ty # ty tool implementation.
155155
│ └── spec # Tool specification implementations.
156+
│ ├── all_ # Registry of all available tool specifications.
156157
│ ├── codespell # Codespell tool specification.
157158
│ ├── coverage_py # Coverage.py tool specification.
158159
│ ├── deptry # deptry tool specification.

docs/module-tree.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ usethis # usethis: Automatically manage Python tooling
142142
│ │ ├── tach # Tach tool implementation.
143143
│ │ └── ty # ty tool implementation.
144144
│ └── spec # Tool specification implementations.
145+
│ ├── all_ # Registry of all available tool specifications.
145146
│ ├── codespell # Codespell tool specification.
146147
│ ├── coverage_py # Coverage.py tool specification.
147148
│ ├── deptry # deptry tool specification.

src/usethis/_tool/all_.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
| TyTool
3535
)
3636

37-
# N.B. this list must be kept in-sync with usethis._tool.impl.base.pyproject_toml.OTHER_TOOLS.
3837
ALL_TOOLS: list[SupportedToolType] = [
3938
# Alphabetical order
4039
CodespellTool(),

src/usethis/_tool/impl/base/pyproject_toml.py

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,10 @@
99
from usethis._console import how_print, info_print, instruct_print
1010
from usethis._file.pyproject_toml.io_ import PyprojectTOMLManager
1111
from usethis._tool.base import Tool
12-
from usethis._tool.impl.base.codespell import CodespellTool
13-
from usethis._tool.impl.base.coverage_py import CoveragePyTool
14-
from usethis._tool.impl.base.deptry import DeptryTool
15-
from usethis._tool.impl.base.import_linter import ImportLinterTool
16-
from usethis._tool.impl.base.mkdocs import MkDocsTool
17-
from usethis._tool.impl.base.pre_commit import PreCommitTool
18-
from usethis._tool.impl.base.pyproject_fmt import PyprojectFmtTool
19-
from usethis._tool.impl.base.pytest import PytestTool
20-
from usethis._tool.impl.base.requirements_txt import RequirementsTxtTool
21-
from usethis._tool.impl.base.ruff import RuffTool
22-
from usethis._tool.impl.base.tach import TachTool
23-
from usethis._tool.impl.base.ty import TyTool
12+
from usethis._tool.heuristics import is_likely_used
13+
from usethis._tool.impl.spec.all_ import ALL_TOOL_SPECS
2414
from usethis._tool.impl.spec.pyproject_toml import PyprojectTOMLToolSpec
2515

26-
# N.B. this list must be kept in-sync with usethis._tool.all_.ALL_TOOLS.
27-
OTHER_TOOLS: list[Tool] = [
28-
CodespellTool(),
29-
CoveragePyTool(),
30-
DeptryTool(),
31-
ImportLinterTool(),
32-
MkDocsTool(),
33-
PreCommitTool(),
34-
PyprojectFmtTool(),
35-
PytestTool(),
36-
RequirementsTxtTool(),
37-
RuffTool(),
38-
TachTool(),
39-
TyTool(),
40-
]
41-
4216

4317
@final
4418
class PyprojectTOMLTool(PyprojectTOMLToolSpec, Tool):
@@ -61,14 +35,17 @@ def remove_managed_files(self) -> None:
6135

6236
instruct_print("Check that important config in 'pyproject.toml' is not lost.")
6337

64-
for tool in OTHER_TOOLS:
38+
for tool_spec in ALL_TOOL_SPECS:
39+
if isinstance(tool_spec, PyprojectTOMLToolSpec):
40+
continue
6541
if (
66-
tool.is_used()
67-
and PyprojectTOMLManager() in tool.get_active_config_file_managers()
42+
is_likely_used(tool_spec)
43+
and PyprojectTOMLManager()
44+
in tool_spec.get_active_config_file_managers()
6845
):
6946
# Warn the user
7047
instruct_print(
71-
f"The {tool.name} tool was using 'pyproject.toml' for config, "
48+
f"The {tool_spec.name} tool was using 'pyproject.toml' for config, "
7249
f"but that file is being removed. You will need to re-configure it."
7350
)
7451

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
"""Registry of all available tool specifications."""
2+
3+
from __future__ import annotations
4+
5+
from usethis._tool.impl.spec.codespell import CodespellToolSpec
6+
from usethis._tool.impl.spec.coverage_py import CoveragePyToolSpec
7+
from usethis._tool.impl.spec.deptry import DeptryToolSpec
8+
from usethis._tool.impl.spec.import_linter import ImportLinterToolSpec
9+
from usethis._tool.impl.spec.mkdocs import MkDocsToolSpec
10+
from usethis._tool.impl.spec.pre_commit import PreCommitToolSpec
11+
from usethis._tool.impl.spec.pyproject_fmt import PyprojectFmtToolSpec
12+
from usethis._tool.impl.spec.pyproject_toml import PyprojectTOMLToolSpec
13+
from usethis._tool.impl.spec.pytest import PytestToolSpec
14+
from usethis._tool.impl.spec.requirements_txt import RequirementsTxtToolSpec
15+
from usethis._tool.impl.spec.ruff import RuffToolSpec
16+
from usethis._tool.impl.spec.tach import TachToolSpec
17+
from usethis._tool.impl.spec.ty import TyToolSpec
18+
19+
ALL_TOOL_SPECS: list[
20+
CodespellToolSpec
21+
| CoveragePyToolSpec
22+
| DeptryToolSpec
23+
| ImportLinterToolSpec
24+
| MkDocsToolSpec
25+
| PreCommitToolSpec
26+
| PyprojectFmtToolSpec
27+
| PyprojectTOMLToolSpec
28+
| PytestToolSpec
29+
| RequirementsTxtToolSpec
30+
| RuffToolSpec
31+
| TachToolSpec
32+
| TyToolSpec
33+
] = [
34+
# Alphabetical order, matching ALL_TOOLS in usethis._tool.all_
35+
CodespellToolSpec(),
36+
CoveragePyToolSpec(),
37+
DeptryToolSpec(),
38+
ImportLinterToolSpec(),
39+
MkDocsToolSpec(),
40+
PreCommitToolSpec(),
41+
PyprojectFmtToolSpec(),
42+
PyprojectTOMLToolSpec(),
43+
PytestToolSpec(),
44+
RequirementsTxtToolSpec(),
45+
RuffToolSpec(),
46+
TachToolSpec(),
47+
TyToolSpec(),
48+
]

src/usethis/_ui/interface/tool.py

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -461,20 +461,12 @@ def _run_tool(caller: UseToolFunc, *, remove: bool, how: bool, **kwargs: object)
461461
raise typer.Exit(code=1) from None
462462

463463

464-
ALL_TOOL_COMMANDS: list[str] = [
465-
"codespell",
466-
"coverage.py",
467-
"deptry",
468-
"import-linter",
469-
"mkdocs",
470-
"pre-commit",
471-
"pyproject.toml",
472-
"pyproject-fmt",
473-
"pytest",
474-
"requirements.txt",
475-
"ruff",
476-
"tach",
477-
"ty",
478-
]
464+
def _get_all_tool_commands() -> list[str]:
465+
from usethis._tool.all_ import ALL_TOOLS
466+
467+
return [tool.name.lower().replace(" ", "-") for tool in ALL_TOOLS]
468+
469+
470+
ALL_TOOL_COMMANDS: list[str] = _get_all_tool_commands()
479471

480472
ALL_TOOL_COMMAND_STRS: list[str] = [f"usethis tool {cmd}" for cmd in ALL_TOOL_COMMANDS]

tests/usethis/_tool/impl/base/test_pyproject_toml.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,16 @@
77
from usethis._config_file import files_manager
88
from usethis._test import change_cwd
99
from usethis._tool.all_ import ALL_TOOLS
10-
from usethis._tool.impl.base.pyproject_toml import OTHER_TOOLS, PyprojectTOMLTool
10+
from usethis._tool.impl.base.pyproject_toml import PyprojectTOMLTool
11+
from usethis._tool.impl.spec.all_ import ALL_TOOL_SPECS
1112

1213

13-
class TestOtherTools:
14+
class TestAllToolSpecs:
1415
def test_in_sync_with_all_tools(self):
15-
assert {tool.name.lower() for tool in OTHER_TOOLS} | {
16-
PyprojectTOMLTool().name
17-
} == {tool.name.lower() for tool in ALL_TOOLS}
16+
# ALL_TOOL_SPECS must have the same names in the same order as ALL_TOOLS.
17+
assert [spec.name for spec in ALL_TOOL_SPECS] == [
18+
tool.name for tool in ALL_TOOLS
19+
]
1820

1921

2022
class TestPyprojectTOMLTool:

tests/usethis/_ui/interface/test_tool.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -838,9 +838,9 @@ def test_several_tools_add_and_remove(tmp_path: Path):
838838

839839

840840
def test_tool_matches_command():
841-
assert {tool.name.lower().replace(" ", "-") for tool in ALL_TOOLS} == set(
842-
ALL_TOOL_COMMANDS
843-
)
841+
assert [
842+
tool.name.lower().replace(" ", "-") for tool in ALL_TOOLS
843+
] == ALL_TOOL_COMMANDS
844844

845845

846846
def test_app_commands_match_list():

0 commit comments

Comments
 (0)