Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .importlinter
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,29 @@ name = usethis._tool.impl
type = layers
containers =
usethis._tool.impl
layers =
base
spec
exhaustive = true

[importlinter:contract:tool_impl_base]
name = usethis._tool.impl.base
type = layers
containers =
usethis._tool.impl.base
layers =
pyproject_toml
codespell | deptry | import_linter | mkdocs | pyproject_fmt | requirements_txt
ruff
pytest : coverage_py
pre_commit
exhaustive = true

[importlinter:contract:tool_impl_spec]
name = usethis._tool.impl.spec
type = layers
containers =
usethis._tool.impl.spec
layers =
pyproject_toml
codespell | deptry | import_linter | mkdocs | pyproject_fmt | requirements_txt
Expand Down
14 changes: 7 additions & 7 deletions src/usethis/_core/ci.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
remove_bitbucket_pipelines_config,
)
from usethis._tool.all_ import ALL_TOOLS
from usethis._tool.impl.codespell import CodespellTool
from usethis._tool.impl.deptry import DeptryTool
from usethis._tool.impl.import_linter import ImportLinterTool
from usethis._tool.impl.pre_commit import PreCommitTool
from usethis._tool.impl.pyproject_fmt import PyprojectFmtTool
from usethis._tool.impl.pytest import PytestTool
from usethis._tool.impl.ruff import RuffTool
from usethis._tool.impl.base.codespell import CodespellTool
from usethis._tool.impl.base.deptry import DeptryTool
from usethis._tool.impl.base.import_linter import ImportLinterTool
from usethis._tool.impl.base.pre_commit import PreCommitTool
from usethis._tool.impl.base.pyproject_fmt import PyprojectFmtTool
from usethis._tool.impl.base.pytest import PytestTool
from usethis._tool.impl.base.ruff import RuffTool

# Ordered list of QA tools that should run in CI (matches canonical step order)
# These tools run via pre-commit if available, otherwise directly in CI
Expand Down
2 changes: 1 addition & 1 deletion src/usethis/_core/docstyle.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from typing import TYPE_CHECKING

from usethis._core.tool import use_ruff
from usethis._tool.impl.ruff import RuffTool
from usethis._tool.impl.base.ruff import RuffTool

if TYPE_CHECKING:
from usethis._types.docstyle import DocStyleEnum
Expand Down
2 changes: 1 addition & 1 deletion src/usethis/_core/list.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from usethis._detect.ci.bitbucket import is_bitbucket_used
from usethis._detect.readme import is_readme_used
from usethis._tool.all_ import ALL_TOOLS
from usethis._tool.impl.ruff import RuffTool
from usethis._tool.impl.base.ruff import RuffTool


class UsageRow(BaseModel):
Expand Down
4 changes: 2 additions & 2 deletions src/usethis/_core/rule.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from pydantic import BaseModel

from usethis._core.tool import use_deptry, use_ruff
from usethis._tool.impl.deptry import DeptryTool
from usethis._tool.impl.ruff import RuffTool
from usethis._tool.impl.base.deptry import DeptryTool
from usethis._tool.impl.base.ruff import RuffTool


class RulesMapping(BaseModel):
Expand Down
22 changes: 11 additions & 11 deletions src/usethis/_core/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@
from usethis._integrations.pre_commit.hooks import add_placeholder_hook, get_hook_ids
from usethis._integrations.pytest.core import add_pytest_dir, remove_pytest_dir
from usethis._tool.all_ import ALL_TOOLS
from usethis._tool.impl.codespell import CodespellTool
from usethis._tool.impl.coverage_py import CoveragePyTool
from usethis._tool.impl.deptry import DeptryTool
from usethis._tool.impl.import_linter import ImportLinterTool
from usethis._tool.impl.mkdocs import MkDocsTool
from usethis._tool.impl.pre_commit import PreCommitTool
from usethis._tool.impl.pyproject_fmt import PyprojectFmtTool
from usethis._tool.impl.pyproject_toml import PyprojectTOMLTool
from usethis._tool.impl.pytest import PytestTool
from usethis._tool.impl.requirements_txt import RequirementsTxtTool
from usethis._tool.impl.ruff import RuffTool
from usethis._tool.impl.base.codespell import CodespellTool
from usethis._tool.impl.base.coverage_py import CoveragePyTool
from usethis._tool.impl.base.deptry import DeptryTool
from usethis._tool.impl.base.import_linter import ImportLinterTool
from usethis._tool.impl.base.mkdocs import MkDocsTool
from usethis._tool.impl.base.pre_commit import PreCommitTool
from usethis._tool.impl.base.pyproject_fmt import PyprojectFmtTool
from usethis._tool.impl.base.pyproject_toml import PyprojectTOMLTool
from usethis._tool.impl.base.pytest import PytestTool
from usethis._tool.impl.base.requirements_txt import RequirementsTxtTool
from usethis._tool.impl.base.ruff import RuffTool
from usethis._tool.rule import RuleConfig
from usethis._types.backend import BackendEnum

Expand Down
22 changes: 11 additions & 11 deletions src/usethis/_tool/all_.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

from typing import TypeAlias

from usethis._tool.impl.codespell import CodespellTool
from usethis._tool.impl.coverage_py import CoveragePyTool
from usethis._tool.impl.deptry import DeptryTool
from usethis._tool.impl.import_linter import ImportLinterTool
from usethis._tool.impl.mkdocs import MkDocsTool
from usethis._tool.impl.pre_commit import PreCommitTool
from usethis._tool.impl.pyproject_fmt import PyprojectFmtTool
from usethis._tool.impl.pyproject_toml import PyprojectTOMLTool
from usethis._tool.impl.pytest import PytestTool
from usethis._tool.impl.requirements_txt import RequirementsTxtTool
from usethis._tool.impl.ruff import RuffTool
from usethis._tool.impl.base.codespell import CodespellTool
from usethis._tool.impl.base.coverage_py import CoveragePyTool
from usethis._tool.impl.base.deptry import DeptryTool
from usethis._tool.impl.base.import_linter import ImportLinterTool
from usethis._tool.impl.base.mkdocs import MkDocsTool
from usethis._tool.impl.base.pre_commit import PreCommitTool
from usethis._tool.impl.base.pyproject_fmt import PyprojectFmtTool
from usethis._tool.impl.base.pyproject_toml import PyprojectTOMLTool
from usethis._tool.impl.base.pytest import PytestTool
from usethis._tool.impl.base.requirements_txt import RequirementsTxtTool
from usethis._tool.impl.base.ruff import RuffTool

SupportedToolType: TypeAlias = (
CodespellTool
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -1,80 +1,14 @@
from __future__ import annotations

from pathlib import Path
from typing import TYPE_CHECKING

from usethis._config import usethis_config
from usethis._config_file import DotCodespellRCManager
from usethis._console import how_print
from usethis._file.pyproject_toml.errors import PyprojectTOMLNotFoundError
from usethis._file.pyproject_toml.io_ import PyprojectTOMLManager
from usethis._file.pyproject_toml.requires_python import (
MissingRequiresPythonError,
get_required_minor_python_versions,
)
from usethis._file.setup_cfg.io_ import SetupCFGManager
from usethis._integrations.pre_commit import schema as pre_commit_schema
from usethis._python.version import PythonVersion
from usethis._tool.base import Tool, ToolMeta, ToolSpec
from usethis._tool.base import Tool
from usethis._tool.config import ConfigEntry, ConfigItem, ConfigSpec
from usethis._tool.pre_commit import PreCommitConfig
from usethis._types.deps import Dependency

if TYPE_CHECKING:
from usethis._io import KeyValueFileManager

_CODESPELL_VERSION = "v2.4.1" # Manually bump this version when necessary


class CodespellToolSpec(ToolSpec):
@property
def meta(self) -> ToolMeta:
return ToolMeta(
name="Codespell",
url="https://github.com/codespell-project/codespell",
managed_files=[Path(".codespellrc")],
)

def preferred_file_manager(self) -> KeyValueFileManager:
if (usethis_config.cpd() / "pyproject.toml").exists():
return PyprojectTOMLManager()
return DotCodespellRCManager()

def raw_cmd(self) -> str:
return "codespell"

def dev_deps(self, *, unconditional: bool = False) -> list[Dependency]:
deps = [Dependency(name="codespell")]

# Python < 3.11 needs tomli (instead of the stdlib tomllib) to read
# pyproject.toml files
if unconditional:
needs_tomli = True
else:
try:
versions = get_required_minor_python_versions()
except (MissingRequiresPythonError, PyprojectTOMLNotFoundError):
versions = [PythonVersion.from_interpreter()]

needs_tomli = any(v.to_short_tuple() < (3, 11) for v in versions)
if needs_tomli:
deps.append(Dependency(name="tomli"))

return deps

def pre_commit_config(self) -> PreCommitConfig:
return PreCommitConfig.from_single_repo(
pre_commit_schema.UriRepo(
repo="https://github.com/codespell-project/codespell",
rev=_CODESPELL_VERSION,
hooks=[
pre_commit_schema.HookDefinition(
id="codespell", additional_dependencies=["tomli"]
)
],
),
requires_venv=False,
)
from usethis._tool.impl.spec.codespell import CodespellToolSpec


class CodespellTool(CodespellToolSpec, Tool):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
from __future__ import annotations

from pathlib import Path
from typing import TYPE_CHECKING

from typing_extensions import assert_never

from usethis._backend.dispatch import get_backend
from usethis._backend.uv.detect import is_uv_used
from usethis._config import usethis_config
from usethis._config_file import (
DotCoverageRCManager,
DotCoverageRCTOMLManager,
Expand All @@ -17,26 +15,16 @@
from usethis._file.pyproject_toml.io_ import PyprojectTOMLManager
from usethis._file.setup_cfg.io_ import SetupCFGManager
from usethis._integrations.project.layout import get_source_dir_str
from usethis._tool.base import Tool, ToolMeta, ToolSpec
from usethis._tool.base import Tool
from usethis._tool.config import ConfigEntry, ConfigItem, ConfigSpec
from usethis._tool.impl.spec.coverage_py import CoveragePyToolSpec
from usethis._types.backend import BackendEnum
from usethis._types.deps import Dependency

if TYPE_CHECKING:
from usethis._io import KeyValueFileManager


class CoveragePyToolSpec(ToolSpec):
@property
def meta(self) -> ToolMeta:
return ToolMeta(
name="Coverage.py",
url="https://github.com/nedbat/coveragepy",
managed_files=[Path(".coveragerc"), Path(".coveragerc.toml")],
)

class CoveragePyTool(CoveragePyToolSpec, Tool):
def test_deps(self, *, unconditional: bool = False) -> list[Dependency]:
from usethis._tool.impl.pytest import ( # to avoid circularity; # noqa: PLC0415
from usethis._tool.impl.base.pytest import ( # to avoid circularity; # noqa: PLC0415
PytestTool,
)

Expand All @@ -45,13 +33,6 @@ def test_deps(self, *, unconditional: bool = False) -> list[Dependency]:
deps += [Dependency(name="pytest-cov")]
return deps

def preferred_file_manager(self) -> KeyValueFileManager:
if (usethis_config.cpd() / "pyproject.toml").exists():
return PyprojectTOMLManager()
return DotCoverageRCManager()


class CoveragePyTool(CoveragePyToolSpec, Tool):
def config_spec(self) -> ConfigSpec:
# https://coverage.readthedocs.io/en/latest/config.html#configuration-reference
# But the `latest` link doesn't yet include some latest changes regarding
Expand Down Expand Up @@ -275,7 +256,7 @@ def _get_source():
)

def print_how_to_use(self) -> None:
from usethis._tool.impl.pytest import ( # to avoid circularity; # noqa: PLC0415
from usethis._tool.impl.base.pytest import ( # to avoid circularity; # noqa: PLC0415
PytestTool,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,88 +3,21 @@
from pathlib import Path
from typing import TYPE_CHECKING

from typing_extensions import assert_never

from usethis._backend.dispatch import get_backend
from usethis._console import info_print
from usethis._file.pyproject_toml.io_ import PyprojectTOMLManager
from usethis._integrations.pre_commit import schema as pre_commit_schema
from usethis._integrations.pre_commit.language import get_system_language
from usethis._integrations.project.layout import get_source_dir_str
from usethis._tool.base import Tool, ToolMeta, ToolSpec
from usethis._tool.base import Tool
from usethis._tool.config import (
ConfigEntry,
ConfigItem,
ConfigSpec,
)
from usethis._tool.pre_commit import PreCommitConfig
from usethis._types.backend import BackendEnum
from usethis._types.deps import Dependency
from usethis._tool.impl.spec.deptry import DeptryToolSpec

if TYPE_CHECKING:
from usethis._io import KeyValueFileManager
from usethis._tool.rule import Rule


class DeptryToolSpec(ToolSpec):
@property
def meta(self) -> ToolMeta:
return ToolMeta(
name="deptry",
url="https://github.com/fpgmaas/deptry",
)

def raw_cmd(self) -> str:
_dir = get_source_dir_str()
return f"deptry {_dir}"

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

def pre_commit_config(self) -> PreCommitConfig:
backend = get_backend()

_dir = get_source_dir_str()
if backend is BackendEnum.uv:
return PreCommitConfig.from_single_repo(
pre_commit_schema.LocalRepo(
repo="local",
hooks=[
pre_commit_schema.HookDefinition(
id="deptry",
name="deptry",
entry=f"uv run --frozen --offline deptry {_dir}",
language=get_system_language(),
always_run=True,
pass_filenames=False,
)
],
),
requires_venv=True,
inform_how_to_use_on_migrate=False,
)
elif backend is BackendEnum.none:
return PreCommitConfig.from_single_repo(
pre_commit_schema.LocalRepo(
repo="local",
hooks=[
pre_commit_schema.HookDefinition(
id="deptry",
name="deptry",
entry=f"deptry {_dir}",
language=get_system_language(),
always_run=True,
pass_filenames=False,
)
],
),
requires_venv=True,
inform_how_to_use_on_migrate=False,
)
else:
assert_never(backend)


class DeptryTool(DeptryToolSpec, Tool):
def config_spec(self) -> ConfigSpec:
# https://deptry.com/usage/#configuration
Expand Down
Loading
Loading