repo-review 0.10.4__tar.gz → 0.10.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {repo_review-0.10.4 → repo_review-0.10.6}/.github/workflows/ci.yml +12 -4
- {repo_review-0.10.4 → repo_review-0.10.6}/.pre-commit-config.yaml +5 -5
- {repo_review-0.10.4 → repo_review-0.10.6}/PKG-INFO +14 -4
- {repo_review-0.10.4 → repo_review-0.10.6}/README.md +3 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/docs/api/repo_review.rst +8 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/docs/fixtures.md +1 -1
- {repo_review-0.10.4 → repo_review-0.10.6}/docs/index.html +2 -2
- {repo_review-0.10.4 → repo_review-0.10.6}/docs/intro.md +4 -1
- {repo_review-0.10.4 → repo_review-0.10.6}/docs/plugins.md +17 -1
- {repo_review-0.10.4 → repo_review-0.10.6}/noxfile.py +2 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/src/repo_review/__init__.py +0 -1
- {repo_review-0.10.4 → repo_review-0.10.6}/src/repo_review/__main__.py +3 -1
- {repo_review-0.10.4 → repo_review-0.10.6}/src/repo_review/_compat/importlib/resources/abc.py +1 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/src/repo_review/_version.py +2 -2
- {repo_review-0.10.4 → repo_review-0.10.6}/src/repo_review/checks.py +23 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/src/repo_review/ghpath.py +4 -8
- {repo_review-0.10.4 → repo_review-0.10.6}/src/repo_review/processor.py +9 -13
- repo_review-0.10.6/src/repo_review/testing.py +70 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/tests/test_cmd.py +1 -1
- repo_review-0.10.6/tests/test_depends.py +61 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/tests/test_package.py +13 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/.devcontainer/devcontainer.json +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/.git_archival.txt +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/.gitattributes +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/.github/CONTRIBUTING.md +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/.github/dependabot.yml +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/.github/matchers/pylint.json +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/.github/workflows/cd.yml +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/.gitignore +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/.pre-commit-hooks.yaml +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/.readthedocs.yaml +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/LICENSE +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/action.yml +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/docs/.nojekyll +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/docs/api/repo_review.resources.rst +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/docs/changelog.md +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/docs/checks.md +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/docs/cli.md +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/docs/conf.py +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/docs/families.md +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/docs/index.md +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/docs/programmatic.md +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/docs/webapp.js +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/docs/webapp.md +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/pyproject.toml +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/src/repo_review/_compat/__init__.py +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/src/repo_review/_compat/importlib/__init__.py +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/src/repo_review/_compat/importlib/resources/__init__.py +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/src/repo_review/_compat/tomllib.py +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/src/repo_review/_compat/typing.py +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/src/repo_review/_version.pyi +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/src/repo_review/families.py +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/src/repo_review/fixtures.py +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/src/repo_review/html.py +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/src/repo_review/py.typed +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/src/repo_review/resources/__init__.py +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/src/repo_review/resources/repo-review.schema.json +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/src/repo_review/schema.py +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/tests/conftest.py +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/tests/test_checks.py +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/tests/test_families.py +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/tests/test_fixtures.py +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/tests/test_multi.py +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/tests/test_self.py +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/tests/test_utilities/pyproject.py +0 -0
- {repo_review-0.10.4 → repo_review-0.10.6}/tests/test_utilities/pyproject.toml +0 -0
@@ -26,7 +26,7 @@ jobs:
|
|
26
26
|
- uses: actions/setup-python@v5
|
27
27
|
with:
|
28
28
|
python-version: "3.x"
|
29
|
-
- uses: pre-commit/action@v3.0.
|
29
|
+
- uses: pre-commit/action@v3.0.1
|
30
30
|
with:
|
31
31
|
extra_args: --hook-stage manual --all-files
|
32
32
|
- name: Run PyLint
|
@@ -53,8 +53,13 @@ jobs:
|
|
53
53
|
with:
|
54
54
|
python-version: ${{ matrix.python-version }}
|
55
55
|
|
56
|
+
- name: Setup uv
|
57
|
+
uses: yezz123/setup-uv@v4
|
58
|
+
with:
|
59
|
+
uv-venv: ".venv"
|
60
|
+
|
56
61
|
- name: Install package
|
57
|
-
run:
|
62
|
+
run: uv pip install .[test,cli]
|
58
63
|
|
59
64
|
- name: Test package
|
60
65
|
run: python -m pytest -ra
|
@@ -80,7 +85,10 @@ jobs:
|
|
80
85
|
with:
|
81
86
|
fetch-depth: 0
|
82
87
|
|
83
|
-
-
|
88
|
+
- name: Setup uv
|
89
|
+
uses: yezz123/setup-uv@v4
|
90
|
+
|
91
|
+
- uses: wntrblm/nox@2024.04.15
|
84
92
|
with:
|
85
93
|
python-versions: "3.11"
|
86
94
|
|
@@ -106,4 +114,4 @@ jobs:
|
|
106
114
|
- name: Run repo-review action
|
107
115
|
uses: ./
|
108
116
|
with:
|
109
|
-
plugins: sp-repo-review==
|
117
|
+
plugins: sp-repo-review==2024.03.10
|
@@ -10,20 +10,20 @@ repos:
|
|
10
10
|
additional_dependencies: [black==23.*]
|
11
11
|
|
12
12
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
13
|
-
rev: "v0.1
|
13
|
+
rev: "v0.4.1"
|
14
14
|
hooks:
|
15
15
|
- id: ruff
|
16
16
|
args: ["--fix", "--show-fixes"]
|
17
17
|
- id: ruff-format
|
18
18
|
|
19
19
|
- repo: https://github.com/pre-commit/mirrors-prettier
|
20
|
-
rev: "
|
20
|
+
rev: "v4.0.0-alpha.8"
|
21
21
|
hooks:
|
22
22
|
- id: prettier
|
23
23
|
types_or: [yaml, markdown, html, css, scss, javascript, json]
|
24
24
|
|
25
25
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
26
|
-
rev: v4.
|
26
|
+
rev: v4.6.0
|
27
27
|
hooks:
|
28
28
|
- id: check-added-large-files
|
29
29
|
- id: check-case-conflict
|
@@ -44,7 +44,7 @@ repos:
|
|
44
44
|
- id: rst-inline-touching-normal
|
45
45
|
|
46
46
|
- repo: https://github.com/pre-commit/mirrors-mypy
|
47
|
-
rev: v1.
|
47
|
+
rev: v1.9.0
|
48
48
|
hooks:
|
49
49
|
- id: mypy
|
50
50
|
files: (src|web|tests)
|
@@ -64,7 +64,7 @@ repos:
|
|
64
64
|
args: ["-Lhist,absense", "-w"]
|
65
65
|
|
66
66
|
- repo: https://github.com/shellcheck-py/shellcheck-py
|
67
|
-
rev: v0.
|
67
|
+
rev: v0.10.0.1
|
68
68
|
hooks:
|
69
69
|
- id: shellcheck
|
70
70
|
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.3
|
2
2
|
Name: repo_review
|
3
|
-
Version: 0.10.
|
3
|
+
Version: 0.10.6
|
4
4
|
Summary: Framework that can run checks on repos
|
5
5
|
Project-URL: Changelog, https://github.com/scientific-python/repo-review/releases
|
6
6
|
Project-URL: Demo, https://scientific-python.github.io/repo-review
|
@@ -34,11 +34,18 @@ Requires-Dist: click>=8; extra == 'cli'
|
|
34
34
|
Requires-Dist: rich-click; extra == 'cli'
|
35
35
|
Requires-Dist: rich>=12.2; extra == 'cli'
|
36
36
|
Provides-Extra: dev
|
37
|
-
Requires-Dist:
|
37
|
+
Requires-Dist: click>=8; extra == 'dev'
|
38
|
+
Requires-Dist: pytest>=7; extra == 'dev'
|
39
|
+
Requires-Dist: rich-click; extra == 'dev'
|
40
|
+
Requires-Dist: rich>=12.2; extra == 'dev'
|
41
|
+
Requires-Dist: sp-repo-review>=2023.12.21; extra == 'dev'
|
42
|
+
Requires-Dist: validate-pyproject>=0.14; extra == 'dev'
|
38
43
|
Provides-Extra: docs
|
44
|
+
Requires-Dist: click>=8; extra == 'docs'
|
39
45
|
Requires-Dist: furo; extra == 'docs'
|
40
46
|
Requires-Dist: myst-parser>=0.13; extra == 'docs'
|
41
|
-
Requires-Dist:
|
47
|
+
Requires-Dist: rich-click; extra == 'docs'
|
48
|
+
Requires-Dist: rich>=12.2; extra == 'docs'
|
42
49
|
Requires-Dist: sphinx-autodoc-typehints; extra == 'docs'
|
43
50
|
Requires-Dist: sphinx-copybutton; extra == 'docs'
|
44
51
|
Requires-Dist: sphinx-github-changelog; extra == 'docs'
|
@@ -57,6 +64,7 @@ Description-Content-Type: text/markdown
|
|
57
64
|
[![Documentation Status][docs-badge]][docs-link]
|
58
65
|
|
59
66
|
[![PyPI version][pypi-version]][pypi-link]
|
67
|
+
[![Conda-Forge][conda-badge]][conda-link]
|
60
68
|
[![PyPI platforms][pypi-platforms]][pypi-link]
|
61
69
|
|
62
70
|
<!-- SPHINX-START -->
|
@@ -212,6 +220,8 @@ This was developed for [Scikit-HEP][] before moving to Scientific-Python.
|
|
212
220
|
[sp-repo-review]: https://pypi.org/project/sp-repo-review
|
213
221
|
[validate-pyproject]: https://validate-pyproject.readthedocs.io
|
214
222
|
[validate-pyproject-schema-store]: https://github.com/henryiii/validate-pyproject-schema-store
|
223
|
+
[conda-badge]: https://img.shields.io/conda/vn/conda-forge/repo-review
|
224
|
+
[conda-link]: https://github.com/conda-forge/repo-review-feedstock
|
215
225
|
|
216
226
|
[intro-pre-commit]: https://repo-review.readthedocs.io/en/latest/intro.html#pre-commit
|
217
227
|
[intro-github-actions]: https://repo-review.readthedocs.io/en/latest/intro.html#github-actions
|
@@ -4,6 +4,7 @@
|
|
4
4
|
[![Documentation Status][docs-badge]][docs-link]
|
5
5
|
|
6
6
|
[![PyPI version][pypi-version]][pypi-link]
|
7
|
+
[![Conda-Forge][conda-badge]][conda-link]
|
7
8
|
[![PyPI platforms][pypi-platforms]][pypi-link]
|
8
9
|
|
9
10
|
<!-- SPHINX-START -->
|
@@ -159,6 +160,8 @@ This was developed for [Scikit-HEP][] before moving to Scientific-Python.
|
|
159
160
|
[sp-repo-review]: https://pypi.org/project/sp-repo-review
|
160
161
|
[validate-pyproject]: https://validate-pyproject.readthedocs.io
|
161
162
|
[validate-pyproject-schema-store]: https://github.com/henryiii/validate-pyproject-schema-store
|
163
|
+
[conda-badge]: https://img.shields.io/conda/vn/conda-forge/repo-review
|
164
|
+
[conda-link]: https://github.com/conda-forge/repo-review-feedstock
|
162
165
|
|
163
166
|
[intro-pre-commit]: https://repo-review.readthedocs.io/en/latest/intro.html#pre-commit
|
164
167
|
[intro-github-actions]: https://repo-review.readthedocs.io/en/latest/intro.html#github-actions
|
@@ -3,7 +3,7 @@
|
|
3
3
|
Like pytest fixtures, fixtures in repo-review are requested by name. There are five built-in fixtures:
|
4
4
|
|
5
5
|
- `root`: {class}`~importlib.resources.abc.Traversable` - The repository path. All checks or fixtures that depend on the root of the repository should use this.
|
6
|
-
- `package`: `~importlib.resources.abc.Traversable` - The path to the package directory. This is the same as `root` unless `--package-dir` is passed.
|
6
|
+
- `package`: {class}`~importlib.resources.abc.Traversable` - The path to the package directory. This is the same as `root` unless `--package-dir` is passed.
|
7
7
|
- `name`: `str` - The name of the current check. (Special fixture only provided for checks, not collection functions.)
|
8
8
|
- {func}`~repo_review.fixtures.pyproject`: `dict[str, Any]` - The `pyproject.toml` in the package if it exists, an empty dict otherwise.
|
9
9
|
- {func}`~repo_review.fixtures.list_all`: `bool` - Returns `True`` if repo-review is just trying to collect all checks to list them.
|
@@ -65,8 +65,8 @@
|
|
65
65
|
header={true}
|
66
66
|
deps={[
|
67
67
|
"repo-review~=0.10.0",
|
68
|
-
"sp-repo-review==
|
69
|
-
"validate-pyproject-schema-store==2024.
|
68
|
+
"sp-repo-review==2024.03.10",
|
69
|
+
"validate-pyproject-schema-store==2024.04.20",
|
70
70
|
"validate-pyproject[all]~=0.16.0",
|
71
71
|
]}
|
72
72
|
/>,
|
@@ -31,10 +31,13 @@ pipx inject repo-review <plugin(s)>
|
|
31
31
|
repo-review .
|
32
32
|
```
|
33
33
|
|
34
|
-
Any other way you like installing things works too, including `pip install`.
|
34
|
+
Any other way you like installing things works too, including `pip install` and `uv pip install`.
|
35
35
|
Remember the `[cli]` extra if you are using the command line
|
36
36
|
interface.
|
37
37
|
|
38
|
+
A conda-forge package is also available. You can use `conda`, `mamba`, `micromamba`, or `pixi` to
|
39
|
+
install from the conda-forge channel.
|
40
|
+
|
38
41
|
Plugins are also encouraged to support pre-commit and GitHub Actions.
|
39
42
|
|
40
43
|
## Running checks
|
@@ -6,7 +6,7 @@ nicer display names. When writing a plugin, you should also do a few things
|
|
6
6
|
when setting up the package. These suggestions assume you are using a
|
7
7
|
standardized backend, such as `hatchling`, `flit-core`, `pdm-backend`, or
|
8
8
|
`setuptools>=61`. If you are using some other build backend, please adjust
|
9
|
-
accordingly.
|
9
|
+
accordingly. Notably, Poetry calls `project.entry-points` "`tool.poetry.plugins`".
|
10
10
|
|
11
11
|
## Entry points
|
12
12
|
|
@@ -53,6 +53,22 @@ You have `processed.results` and `processed.families` from the return of
|
|
53
53
|
{func}`~repo_review.processor.collect_all` to get `.fixtures`, `.checks`, and
|
54
54
|
`.families`.
|
55
55
|
|
56
|
+
### Unit testing
|
57
|
+
|
58
|
+
You can also run unit tests with the {func}`~repo_review.testing.compute_check` helper. It is used like this:
|
59
|
+
|
60
|
+
```python
|
61
|
+
def test_has_tool_ruff_unit() -> None:
|
62
|
+
assert repo_review.testing.compute_check("RF001", ruff={}).result
|
63
|
+
assert not repo_review.testing.compute_check("RF001", ruff=None).result
|
64
|
+
```
|
65
|
+
|
66
|
+
It takes the check name and any fixtures as keyword arguments. It returns a
|
67
|
+
{class}`~repo_review.checks.Check` instance, so you can see if the `.result` is
|
68
|
+
`True`/`False`/`None`, or check any of the other properties.
|
69
|
+
|
70
|
+
.. versionadded:: 0.10.5
|
71
|
+
|
56
72
|
## An existing package
|
57
73
|
|
58
74
|
Since writing a plugin does not require depending on repo-review, you can also
|
@@ -41,7 +41,9 @@ def __dir__() -> list[str]:
|
|
41
41
|
return __all__
|
42
42
|
|
43
43
|
|
44
|
-
rich.traceback.install(
|
44
|
+
rich.traceback.install(
|
45
|
+
suppress=[click, rich, orig_click], show_locals=False, width=None
|
46
|
+
)
|
45
47
|
|
46
48
|
Status = Literal["empty", "passed", "skips", "errors"]
|
47
49
|
Formats = Literal["rich", "json", "html", "svg"]
|
@@ -120,3 +120,26 @@ def get_check_description(name: str, check: Check) -> str:
|
|
120
120
|
.. versionadded:: 0.8
|
121
121
|
"""
|
122
122
|
return (check.__doc__ or "").format(self=check, name=name)
|
123
|
+
|
124
|
+
|
125
|
+
def process_result_bool(
|
126
|
+
result: str | bool | None, check: Check, name: str
|
127
|
+
) -> str | None:
|
128
|
+
"""
|
129
|
+
This converts a bool into a string given a check and name. If the result is a string
|
130
|
+
or None, it is returned as is.
|
131
|
+
|
132
|
+
:param result: The result to process.
|
133
|
+
:param check: The check instance.
|
134
|
+
:param name: The name of the check.
|
135
|
+
:return: The final string or None.
|
136
|
+
|
137
|
+
.. versionadded:: 0.11
|
138
|
+
"""
|
139
|
+
if isinstance(result, bool):
|
140
|
+
return (
|
141
|
+
""
|
142
|
+
if result
|
143
|
+
else (check.check.__doc__ or "Check failed").format(name=name, self=check)
|
144
|
+
)
|
145
|
+
return result
|
@@ -76,12 +76,10 @@ class GHPath(Traversable):
|
|
76
76
|
return (self.path or self.repo).split("/")[-1]
|
77
77
|
|
78
78
|
@typing.overload # type: ignore[override]
|
79
|
-
def open(self, mode: Literal["r"], encoding: str | None = ...) -> io.StringIO:
|
80
|
-
...
|
79
|
+
def open(self, mode: Literal["r"], encoding: str | None = ...) -> io.StringIO: ...
|
81
80
|
|
82
81
|
@typing.overload
|
83
|
-
def open(self, mode: Literal["rb"]) -> io.BytesIO:
|
84
|
-
...
|
82
|
+
def open(self, mode: Literal["rb"]) -> io.BytesIO: ...
|
85
83
|
|
86
84
|
def open(
|
87
85
|
self, mode: Literal["r", "rb"] = "r", encoding: str | None = "utf-8"
|
@@ -164,12 +162,10 @@ class EmptyTraversable(Traversable):
|
|
164
162
|
return self._fake_name
|
165
163
|
|
166
164
|
@typing.overload # type: ignore[override]
|
167
|
-
def open(self, mode: Literal["r"], encoding: str | None = ...) -> io.StringIO:
|
168
|
-
...
|
165
|
+
def open(self, mode: Literal["r"], encoding: str | None = ...) -> io.StringIO: ...
|
169
166
|
|
170
167
|
@typing.overload
|
171
|
-
def open(self, mode: Literal["rb"]) -> io.BytesIO:
|
172
|
-
...
|
168
|
+
def open(self, mode: Literal["rb"]) -> io.BytesIO: ...
|
173
169
|
|
174
170
|
def open(
|
175
171
|
self, mode: Literal["r", "rb"] = "r", encoding: str | None = "utf-8"
|
@@ -10,7 +10,13 @@ from typing import Any, TypeVar
|
|
10
10
|
import markdown_it
|
11
11
|
|
12
12
|
from ._compat.importlib.resources.abc import Traversable
|
13
|
-
from .checks import
|
13
|
+
from .checks import (
|
14
|
+
Check,
|
15
|
+
collect_checks,
|
16
|
+
get_check_url,
|
17
|
+
is_allowed,
|
18
|
+
process_result_bool,
|
19
|
+
)
|
14
20
|
from .families import Family, collect_families
|
15
21
|
from .fixtures import apply_fixtures, collect_fixtures, compute_fixtures, pyproject
|
16
22
|
from .ghpath import EmptyTraversable
|
@@ -108,8 +114,7 @@ class HasFamily(typing.Protocol):
|
|
108
114
|
"""
|
109
115
|
|
110
116
|
@property
|
111
|
-
def family(self) -> str:
|
112
|
-
...
|
117
|
+
def family(self) -> str: ...
|
113
118
|
|
114
119
|
|
115
120
|
T = TypeVar("T", bound=HasFamily)
|
@@ -212,16 +217,7 @@ def process(
|
|
212
217
|
for name in ts.static_order():
|
213
218
|
if all(completed.get(n, "") == "" for n in graph[name]):
|
214
219
|
result = apply_fixtures({"name": name, **fixtures}, tasks[name].check)
|
215
|
-
|
216
|
-
completed[name] = (
|
217
|
-
""
|
218
|
-
if result
|
219
|
-
else (tasks[name].check.__doc__ or "Check failed").format(
|
220
|
-
name=name, self=tasks[name]
|
221
|
-
)
|
222
|
-
)
|
223
|
-
else:
|
224
|
-
completed[name] = result
|
220
|
+
completed[name] = process_result_bool(result, tasks[name], name)
|
225
221
|
else:
|
226
222
|
completed[name] = None
|
227
223
|
|
@@ -0,0 +1,70 @@
|
|
1
|
+
"""
|
2
|
+
Helpers for testing repo-review plugins.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from __future__ import annotations
|
6
|
+
|
7
|
+
import importlib.metadata
|
8
|
+
import textwrap
|
9
|
+
from typing import Any
|
10
|
+
|
11
|
+
from ._compat import tomllib
|
12
|
+
from .checks import Check, get_check_url, process_result_bool
|
13
|
+
from .fixtures import apply_fixtures
|
14
|
+
from .processor import Result
|
15
|
+
|
16
|
+
__all__ = ["toml_loads", "compute_check"]
|
17
|
+
|
18
|
+
|
19
|
+
def __dir__() -> list[str]:
|
20
|
+
return __all__
|
21
|
+
|
22
|
+
|
23
|
+
def toml_loads(contents: str, /) -> Any:
|
24
|
+
"""
|
25
|
+
A helper function to quickly load a TOML string for Python 3.10+.
|
26
|
+
|
27
|
+
:param contents: The TOML string to load.
|
28
|
+
:return: The loaded TOML.
|
29
|
+
|
30
|
+
.. versionadded:: 0.10.6
|
31
|
+
"""
|
32
|
+
return tomllib.loads(contents)
|
33
|
+
|
34
|
+
|
35
|
+
def compute_check(name: str, /, **fixtures: Any) -> Result:
|
36
|
+
"""
|
37
|
+
A helper function to compute a check given fixtures, intended for testing.
|
38
|
+
Currently, all fixtures are required to be passed in as keyword arguments,
|
39
|
+
transitive fixtures are not supported.
|
40
|
+
|
41
|
+
:param name: The name of the check to compute.
|
42
|
+
:param fixtures: The fixtures to use when computing the check.
|
43
|
+
:return: The computed result.
|
44
|
+
|
45
|
+
.. versionadded:: 0.10.5
|
46
|
+
"""
|
47
|
+
|
48
|
+
check_functions = (
|
49
|
+
ep.load() for ep in importlib.metadata.entry_points(group="repo_review.checks")
|
50
|
+
)
|
51
|
+
checks = {
|
52
|
+
k: v
|
53
|
+
for func in check_functions
|
54
|
+
for k, v in apply_fixtures(fixtures, func).items()
|
55
|
+
}
|
56
|
+
check: Check = checks[name]
|
57
|
+
completed_raw = apply_fixtures({"name": name, **fixtures}, check.check)
|
58
|
+
completed = process_result_bool(completed_raw, check, name)
|
59
|
+
result = None if completed is None else not completed
|
60
|
+
doc = check.__doc__ or ""
|
61
|
+
err_msg = completed or ""
|
62
|
+
|
63
|
+
return Result(
|
64
|
+
family=check.family,
|
65
|
+
name=name,
|
66
|
+
description=doc.format(self=check, name=name).strip(),
|
67
|
+
result=result,
|
68
|
+
err_msg=textwrap.dedent(err_msg),
|
69
|
+
url=get_check_url(name, check),
|
70
|
+
)
|
@@ -0,0 +1,61 @@
|
|
1
|
+
from pathlib import Path
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
|
5
|
+
import repo_review.processor
|
6
|
+
from repo_review._compat.importlib.resources.abc import Traversable
|
7
|
+
|
8
|
+
|
9
|
+
class E100:
|
10
|
+
"Was passed correctly"
|
11
|
+
|
12
|
+
family = "example"
|
13
|
+
|
14
|
+
@staticmethod
|
15
|
+
def check(package: Traversable) -> bool:
|
16
|
+
"""
|
17
|
+
Requires Path(".") to be passed
|
18
|
+
"""
|
19
|
+
|
20
|
+
return package == Path()
|
21
|
+
|
22
|
+
|
23
|
+
class E200:
|
24
|
+
"Always true"
|
25
|
+
|
26
|
+
family = "example"
|
27
|
+
requires = frozenset(["E100"])
|
28
|
+
|
29
|
+
@staticmethod
|
30
|
+
def check() -> bool:
|
31
|
+
"""
|
32
|
+
Can't be false.
|
33
|
+
"""
|
34
|
+
|
35
|
+
return True
|
36
|
+
|
37
|
+
|
38
|
+
def test_ignore_filter_single(monkeypatch: pytest.MonkeyPatch) -> None:
|
39
|
+
monkeypatch.setattr(
|
40
|
+
repo_review.processor,
|
41
|
+
"collect_checks",
|
42
|
+
lambda _: {"E100": E100, "E200": E200},
|
43
|
+
)
|
44
|
+
_, results = repo_review.processor.process(Path(), ignore={"E100"})
|
45
|
+
|
46
|
+
assert len(results) == 1
|
47
|
+
assert results[0].name == "E200"
|
48
|
+
assert results[0].result
|
49
|
+
|
50
|
+
|
51
|
+
def test_select_filter_single(monkeypatch: pytest.MonkeyPatch) -> None:
|
52
|
+
monkeypatch.setattr(
|
53
|
+
repo_review.processor,
|
54
|
+
"collect_checks",
|
55
|
+
lambda _: {"E100": E100, "E200": E200},
|
56
|
+
)
|
57
|
+
_, results = repo_review.processor.process(Path(), select={"E200"})
|
58
|
+
|
59
|
+
assert len(results) == 1
|
60
|
+
assert results[0].name == "E200"
|
61
|
+
assert results[0].result
|
@@ -6,6 +6,7 @@ from pathlib import Path
|
|
6
6
|
import pytest
|
7
7
|
|
8
8
|
import repo_review as m
|
9
|
+
import repo_review.testing
|
9
10
|
from repo_review.processor import process
|
10
11
|
|
11
12
|
DIR = Path(__file__).parent.resolve()
|
@@ -43,3 +44,15 @@ def test_broken_validate_pyproject(tmp_path: Path) -> None:
|
|
43
44
|
(result,) = (r for r in results.results if r.name == "VPP001")
|
44
45
|
assert "must match pattern" in result.err_msg
|
45
46
|
assert not result.result
|
47
|
+
|
48
|
+
|
49
|
+
def test_testing_function():
|
50
|
+
pytest.importorskip("sp_repo_review")
|
51
|
+
|
52
|
+
assert repo_review.testing.compute_check("RF001", ruff={}).result
|
53
|
+
assert not repo_review.testing.compute_check("RF001", ruff=None).result
|
54
|
+
|
55
|
+
|
56
|
+
def test_toml_function():
|
57
|
+
pyproject = repo_review.testing.toml_loads("one.two = 3")
|
58
|
+
assert pyproject == {"one": {"two": 3}}
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{repo_review-0.10.4 → repo_review-0.10.6}/src/repo_review/_compat/importlib/resources/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|