Skip to content

Commit 937a94b

Browse files
Major architecture changes to improve CI vs. pre-commit selection logic (#1286)
* Fix indentation and line length issues in docstrings in `base.py` * Major architectural changes to improve functionalization of pre-commit vs. bitbucket selection logic in the `use_*` functions in `src\usethis\_core\tool.py` * Remove trailing `s` from comment * Simplify placeholder check * Fix broken mock reference * Bump fallback versions * Add early return to `_unconditional_update_bitbucket_steps` * Update copilot instructions regarding style * Bump fallback uv version 0.9.26 -> 0.10.0 * Bump fallback pyproject-fmt version 2.11.1->2.12.1 * Bump fallback ruff 0.14.14 -> 0.15.0 * Fix broken mock ref * Fix broken mock ref * Tweak to reflect new behaviour in tests\usethis\_tool\test_base.py::TestTool::TestAddPreCommitConfig::test_multiple_repo_configs * Fix corner case for trying to read `pyproject.toml` which doesn't exist yet but is created by uv * Refactor tests to reflect new behaviour * Fix broken mock refs * Bump the fallback pyproject-fmt version 2.12.1 -> 2.14.0 * Fix broken mock ref * Revert changes to the QA tool logic for bitbucket pipelines * Bump the fallback pyproject.toml version v2.14.0 -> v2.15.1 * Handle some edge cases consistently * Satisfy test suite structural expectations and improve messaging in test
1 parent 5d9732d commit 937a94b

135 files changed

Lines changed: 528 additions & 428 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/copilot-instructions.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,10 @@ Follow the guide in CONTRIBUTING.md:
252252
- Avoid suppressions unless absolutely necessary
253253
- Format: `# ruff: noqa: RULE1, RULE2` (not `# ruff noqa:`)
254254

255+
## Reasoning Style
256+
257+
Never use the word "Actually", say "I just realized" or any other meta-language. Instead, clearly state the insight immediately. Similarly, do not use ellipses, e.g. "Unless...". Don't say "Let me check." Be efficient, clear, and direct, not conversational.
258+
255259
## Trust These Instructions
256260

257261
These instructions have been validated by running actual commands and inspecting the full codebase. Only search for additional information if:

.importlinter

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,13 @@ layers =
1414
_core
1515
_tool
1616
_init
17+
_detect
1718
_deps
1819
_config_file
1920
_integrations
20-
_io | _subprocess | _console
21+
_backend
22+
_file
23+
_io | _subprocess | _console | _python
2124
_config
2225
_types | errors
2326
_pipeweld
@@ -65,10 +68,10 @@ containers =
6568
usethis._tool.impl
6669
layers =
6770
pyproject_toml
68-
codespell | deptry | import_linter | pyproject_fmt | requirements_txt
71+
codespell | deptry | import_linter | mkdocs | pyproject_fmt | requirements_txt
6972
ruff
7073
pytest : coverage_py
71-
pre_commit | mkdocs
74+
pre_commit
7275
exhaustive = true
7376

7477
[importlinter:contract:integrations]
@@ -79,17 +82,15 @@ containers =
7982
layers =
8083
ci | pre_commit
8184
environ
82-
backend | mkdocs | pytest | pydantic | sonarqube
83-
project
84-
file
85-
python
85+
mkdocs | pytest | pydantic | sonarqube
86+
project | readme
8687
exhaustive = true
8788

88-
[importlinter:contract:integrations_file]
89-
name = usethis._integrations.file
89+
[importlinter:contract:_file]
90+
name = usethis._file
9091
type = layers
9192
containers =
92-
usethis._integrations.file
93+
usethis._file
9394
layers =
9495
pyproject_toml | setup_cfg
9596
ini | toml | yaml

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ environment.python-platform = "all"
198198
rules.type-assertion-failure = "ignore"
199199

200200
[[tool.ty.overrides]]
201-
include = [ "src/usethis/_integrations/file/**" ]
201+
include = [ "src/usethis/_file/**" ]
202202
rules.invalid-argument-type = "ignore"
203203
rules.invalid-return-type = "ignore"
204204
rules.invalid-assignment = "ignore"
File renamed without changes.

src/usethis/_integrations/backend/dispatch.py renamed to src/usethis/_backend/dispatch.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
from typing import Literal
44

5+
from usethis._backend.poetry.detect import is_poetry_used
6+
from usethis._backend.uv.available import is_uv_available
7+
from usethis._backend.uv.detect import is_uv_used
58
from usethis._config import usethis_config
69
from usethis._console import warn_print
7-
from usethis._integrations.backend.poetry.used import is_poetry_used
8-
from usethis._integrations.backend.uv.available import is_uv_available
9-
from usethis._integrations.backend.uv.used import is_uv_used
1010
from usethis._types.backend import BackendEnum
1111

1212

File renamed without changes.

src/usethis/_integrations/backend/poetry/used.py renamed to src/usethis/_backend/poetry/detect.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from usethis._config import usethis_config
2-
from usethis._integrations.file.pyproject_toml.io_ import PyprojectTOMLManager
2+
from usethis._file.pyproject_toml.io_ import PyprojectTOMLManager
33

44

55
def is_poetry_used() -> bool:
File renamed without changes.

src/usethis/_integrations/backend/uv/available.py renamed to src/usethis/_backend/uv/available.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
from usethis._integrations.backend.uv.call import call_uv_subprocess
2-
from usethis._integrations.backend.uv.errors import UVSubprocessFailedError
1+
from usethis._backend.uv.call import call_uv_subprocess
2+
from usethis._backend.uv.errors import UVSubprocessFailedError
33

44

55
def is_uv_available() -> bool:

src/usethis/_integrations/backend/uv/call.py renamed to src/usethis/_backend/uv/call.py

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
from __future__ import annotations
22

3+
from usethis._backend.uv.errors import UVSubprocessFailedError
4+
from usethis._backend.uv.link_mode import ensure_symlink_mode
5+
from usethis._backend.uv.toml import UVTOMLManager
36
from usethis._config import usethis_config
4-
from usethis._integrations.backend.uv.errors import UVSubprocessFailedError
5-
from usethis._integrations.backend.uv.link_mode import ensure_symlink_mode
6-
from usethis._integrations.backend.uv.toml import UVTOMLManager
7-
from usethis._integrations.file.pyproject_toml.io_ import (
7+
from usethis._file.pyproject_toml.io_ import (
88
PyprojectTOMLManager,
99
)
10-
from usethis._integrations.file.pyproject_toml.valid import ensure_pyproject_validity
10+
from usethis._file.pyproject_toml.valid import ensure_pyproject_validity
1111
from usethis._subprocess import SubprocessFailedError, call_subprocess
1212
from usethis._types.backend import BackendEnum
1313
from usethis.errors import ForbiddenBackendError
@@ -27,8 +27,6 @@ def call_uv_subprocess(args: list[str], change_toml: bool) -> str:
2727
msg = f"The '{usethis_config.backend.value}' backend is enabled, but a uv subprocess was invoked."
2828
raise ForbiddenBackendError(msg)
2929

30-
is_pyproject_toml = (usethis_config.cpd() / "pyproject.toml").exists()
31-
3230
if change_toml and args[0] in {
3331
"lock",
3432
"add",
@@ -40,14 +38,8 @@ def call_uv_subprocess(args: list[str], change_toml: bool) -> str:
4038
}:
4139
ensure_symlink_mode()
4240

43-
if is_pyproject_toml and change_toml:
44-
if PyprojectTOMLManager().is_locked():
45-
ensure_pyproject_validity()
46-
PyprojectTOMLManager().write_file()
47-
PyprojectTOMLManager()._content = None
48-
else:
49-
with PyprojectTOMLManager():
50-
ensure_pyproject_validity()
41+
if change_toml:
42+
_prepare_pyproject_write()
5143

5244
if usethis_config.frozen and args[0] in {
5345
# Note, not "lock", for which the --frozen flags has quite a different effect
@@ -83,6 +75,22 @@ def call_uv_subprocess(args: list[str], change_toml: bool) -> str:
8375
return output
8476

8577

78+
def _prepare_pyproject_write() -> None:
79+
is_pyproject_toml = (usethis_config.cpd() / "pyproject.toml").exists()
80+
is_locked = PyprojectTOMLManager().is_locked()
81+
82+
if is_pyproject_toml and is_locked:
83+
ensure_pyproject_validity()
84+
PyprojectTOMLManager().write_file()
85+
PyprojectTOMLManager()._content = None # Basically a cache clear
86+
elif not is_pyproject_toml and is_locked:
87+
# Similarly; cache clear
88+
PyprojectTOMLManager()._content = None
89+
elif is_pyproject_toml:
90+
with PyprojectTOMLManager():
91+
ensure_pyproject_validity()
92+
93+
8694
def add_default_groups_via_uv(groups: list[str]) -> None:
8795
"""Add default groups using the uv command-line tool."""
8896
if UVTOMLManager().path.exists():

0 commit comments

Comments
 (0)