repo-review 0.11.0__tar.gz → 0.11.2__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.
Files changed (68) hide show
  1. {repo_review-0.11.0 → repo_review-0.11.2}/.devcontainer/devcontainer.json +1 -1
  2. repo_review-0.11.2/.github/release.yml +5 -0
  3. {repo_review-0.11.0 → repo_review-0.11.2}/.github/workflows/ci.yml +4 -8
  4. {repo_review-0.11.0 → repo_review-0.11.2}/.pre-commit-config.yaml +9 -8
  5. repo_review-0.11.2/.readthedocs.yaml +18 -0
  6. {repo_review-0.11.0 → repo_review-0.11.2}/PKG-INFO +7 -6
  7. {repo_review-0.11.0 → repo_review-0.11.2}/README.md +3 -3
  8. {repo_review-0.11.0 → repo_review-0.11.2}/action.yml +1 -1
  9. {repo_review-0.11.0 → repo_review-0.11.2}/docs/conf.py +21 -0
  10. {repo_review-0.11.0 → repo_review-0.11.2}/docs/index.html +7 -7
  11. {repo_review-0.11.0 → repo_review-0.11.2}/docs/plugins.md +1 -1
  12. {repo_review-0.11.0 → repo_review-0.11.2}/docs/webapp.md +1 -4
  13. {repo_review-0.11.0 → repo_review-0.11.2}/pyproject.toml +5 -10
  14. {repo_review-0.11.0 → repo_review-0.11.2}/src/repo_review/__main__.py +63 -16
  15. {repo_review-0.11.0 → repo_review-0.11.2}/src/repo_review/_version.py +2 -2
  16. {repo_review-0.11.0 → repo_review-0.11.2}/src/repo_review/checks.py +2 -3
  17. {repo_review-0.11.0 → repo_review-0.11.2}/src/repo_review/processor.py +8 -1
  18. {repo_review-0.11.0 → repo_review-0.11.2}/src/repo_review/resources/repo-review.schema.json +12 -1
  19. {repo_review-0.11.0 → repo_review-0.11.2}/tests/conftest.py +2 -2
  20. {repo_review-0.11.0 → repo_review-0.11.2}/tests/test_multi.py +2 -2
  21. {repo_review-0.11.0 → repo_review-0.11.2}/tests/test_package.py +40 -2
  22. {repo_review-0.11.0 → repo_review-0.11.2}/tests/test_utilities/pyproject.toml +1 -1
  23. repo_review-0.11.0/.github/matchers/pylint.json +0 -32
  24. repo_review-0.11.0/.readthedocs.yaml +0 -22
  25. {repo_review-0.11.0 → repo_review-0.11.2}/.git_archival.txt +0 -0
  26. {repo_review-0.11.0 → repo_review-0.11.2}/.gitattributes +0 -0
  27. {repo_review-0.11.0 → repo_review-0.11.2}/.github/CONTRIBUTING.md +0 -0
  28. {repo_review-0.11.0 → repo_review-0.11.2}/.github/ISSUE_TEMPLATE/new-issue.md +0 -0
  29. {repo_review-0.11.0 → repo_review-0.11.2}/.github/dependabot.yml +0 -0
  30. {repo_review-0.11.0 → repo_review-0.11.2}/.github/workflows/cd.yml +0 -0
  31. {repo_review-0.11.0 → repo_review-0.11.2}/.gitignore +0 -0
  32. {repo_review-0.11.0 → repo_review-0.11.2}/.pre-commit-hooks.yaml +0 -0
  33. {repo_review-0.11.0 → repo_review-0.11.2}/LICENSE +0 -0
  34. {repo_review-0.11.0 → repo_review-0.11.2}/docs/.nojekyll +0 -0
  35. {repo_review-0.11.0 → repo_review-0.11.2}/docs/api/repo_review.resources.rst +0 -0
  36. {repo_review-0.11.0 → repo_review-0.11.2}/docs/api/repo_review.rst +0 -0
  37. {repo_review-0.11.0 → repo_review-0.11.2}/docs/changelog.md +0 -0
  38. {repo_review-0.11.0 → repo_review-0.11.2}/docs/checks.md +0 -0
  39. {repo_review-0.11.0 → repo_review-0.11.2}/docs/cli.md +0 -0
  40. {repo_review-0.11.0 → repo_review-0.11.2}/docs/families.md +0 -0
  41. {repo_review-0.11.0 → repo_review-0.11.2}/docs/fixtures.md +0 -0
  42. {repo_review-0.11.0 → repo_review-0.11.2}/docs/index.md +0 -0
  43. {repo_review-0.11.0 → repo_review-0.11.2}/docs/intro.md +0 -0
  44. {repo_review-0.11.0 → repo_review-0.11.2}/docs/programmatic.md +0 -0
  45. {repo_review-0.11.0 → repo_review-0.11.2}/docs/webapp.js +0 -0
  46. {repo_review-0.11.0 → repo_review-0.11.2}/src/repo_review/__init__.py +0 -0
  47. {repo_review-0.11.0 → repo_review-0.11.2}/src/repo_review/_compat/__init__.py +0 -0
  48. {repo_review-0.11.0 → repo_review-0.11.2}/src/repo_review/_compat/importlib/__init__.py +0 -0
  49. {repo_review-0.11.0 → repo_review-0.11.2}/src/repo_review/_compat/importlib/resources/__init__.py +0 -0
  50. {repo_review-0.11.0 → repo_review-0.11.2}/src/repo_review/_compat/importlib/resources/abc.py +0 -0
  51. {repo_review-0.11.0 → repo_review-0.11.2}/src/repo_review/_compat/tomllib.py +0 -0
  52. {repo_review-0.11.0 → repo_review-0.11.2}/src/repo_review/_compat/typing.py +0 -0
  53. {repo_review-0.11.0 → repo_review-0.11.2}/src/repo_review/_version.pyi +0 -0
  54. {repo_review-0.11.0 → repo_review-0.11.2}/src/repo_review/families.py +0 -0
  55. {repo_review-0.11.0 → repo_review-0.11.2}/src/repo_review/fixtures.py +0 -0
  56. {repo_review-0.11.0 → repo_review-0.11.2}/src/repo_review/ghpath.py +0 -0
  57. {repo_review-0.11.0 → repo_review-0.11.2}/src/repo_review/html.py +0 -0
  58. {repo_review-0.11.0 → repo_review-0.11.2}/src/repo_review/py.typed +0 -0
  59. {repo_review-0.11.0 → repo_review-0.11.2}/src/repo_review/resources/__init__.py +0 -0
  60. {repo_review-0.11.0 → repo_review-0.11.2}/src/repo_review/schema.py +0 -0
  61. {repo_review-0.11.0 → repo_review-0.11.2}/src/repo_review/testing.py +0 -0
  62. {repo_review-0.11.0 → repo_review-0.11.2}/tests/test_checks.py +0 -0
  63. {repo_review-0.11.0 → repo_review-0.11.2}/tests/test_cmd.py +0 -0
  64. {repo_review-0.11.0 → repo_review-0.11.2}/tests/test_depends.py +0 -0
  65. {repo_review-0.11.0 → repo_review-0.11.2}/tests/test_families.py +0 -0
  66. {repo_review-0.11.0 → repo_review-0.11.2}/tests/test_fixtures.py +0 -0
  67. {repo_review-0.11.0 → repo_review-0.11.2}/tests/test_self.py +0 -0
  68. {repo_review-0.11.0 → repo_review-0.11.2}/tests/test_utilities/pyproject.py +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "repo-review[dev]",
3
- "image": "mcr.microsoft.com/devcontainers/python:0-3.11",
3
+ "image": "mcr.microsoft.com/devcontainers/python:0-3.12",
4
4
  "postCreateCommand": "pipx install hatch && pip install -e.[cli,test] pylint",
5
5
  "customizations": {
6
6
  "vscode": {
@@ -0,0 +1,5 @@
1
+ changelog:
2
+ exclude:
3
+ authors:
4
+ - dependabot
5
+ - pre-commit-ci
@@ -27,12 +27,8 @@ jobs:
27
27
  with:
28
28
  python-version: "3.x"
29
29
  - uses: pre-commit/action@v3.0.1
30
- with:
31
- extra_args: --hook-stage manual --all-files
32
30
  - name: Run PyLint
33
- run: |
34
- echo "::add-matcher::$GITHUB_WORKSPACE/.github/matchers/pylint.json"
35
- pipx run --python=python hatch run pylint:lint
31
+ run: pipx run --python=python hatch run pylint:lint --output-format=github
36
32
 
37
33
  checks:
38
34
  name: Check Python on ${{ matrix.runs-on }}
@@ -53,6 +49,8 @@ jobs:
53
49
  3.10
54
50
  3.11
55
51
  3.12
52
+ 3.13
53
+ allow-prereleases: true
56
54
 
57
55
  - name: Setup uv
58
56
  uses: yezz123/setup-uv@v4
@@ -62,8 +60,6 @@ jobs:
62
60
 
63
61
  - name: Test package (all Pythons)
64
62
  run: hatch test -a
65
- env:
66
- PYTHONUTF8: "1"
67
63
 
68
64
  dist:
69
65
  name: Distribution build
@@ -116,4 +112,4 @@ jobs:
116
112
  - name: Run repo-review action
117
113
  uses: ./
118
114
  with:
119
- plugins: sp-repo-review==2024.04.23
115
+ plugins: sp-repo-review==2024.08.19
@@ -1,23 +1,24 @@
1
1
  ci:
2
2
  autoupdate_commit_msg: "chore(deps): update pre-commit hooks"
3
3
  autofix_commit_msg: "style: pre-commit fixes"
4
+ autoupdate_schedule: monthly
4
5
 
5
6
  repos:
6
7
  - repo: https://github.com/adamchainz/blacken-docs
7
- rev: 1.16.0
8
+ rev: 1.18.0
8
9
  hooks:
9
10
  - id: blacken-docs
10
11
  additional_dependencies: [black==23.*]
11
12
 
12
13
  - repo: https://github.com/astral-sh/ruff-pre-commit
13
- rev: "v0.4.2"
14
+ rev: "v0.6.1"
14
15
  hooks:
15
16
  - id: ruff
16
17
  args: ["--fix", "--show-fixes"]
17
18
  - id: ruff-format
18
19
 
19
- - repo: https://github.com/pre-commit/mirrors-prettier
20
- rev: "v4.0.0-alpha.8"
20
+ - repo: https://github.com/rbubley/mirrors-prettier
21
+ rev: "v3.3.3"
21
22
  hooks:
22
23
  - id: prettier
23
24
  types_or: [yaml, markdown, html, css, scss, javascript, json]
@@ -44,7 +45,7 @@ repos:
44
45
  - id: rst-inline-touching-normal
45
46
 
46
47
  - repo: https://github.com/pre-commit/mirrors-mypy
47
- rev: v1.10.0
48
+ rev: v1.11.1
48
49
  hooks:
49
50
  - id: mypy
50
51
  files: (src|web|tests)
@@ -58,7 +59,7 @@ repos:
58
59
  - types-PyYAML
59
60
 
60
61
  - repo: https://github.com/codespell-project/codespell
61
- rev: v2.2.6
62
+ rev: v2.3.0
62
63
  hooks:
63
64
  - id: codespell
64
65
  args: ["-Lhist,absense", "-w"]
@@ -77,12 +78,12 @@ repos:
77
78
  exclude: .pre-commit-config.yaml
78
79
 
79
80
  - repo: https://github.com/henryiii/validate-pyproject-schema-store
80
- rev: 2024.04.29
81
+ rev: 2024.08.19
81
82
  hooks:
82
83
  - id: validate-pyproject
83
84
 
84
85
  - repo: https://github.com/python-jsonschema/check-jsonschema
85
- rev: 0.28.2
86
+ rev: 0.29.1
86
87
  hooks:
87
88
  - id: check-dependabot
88
89
  - id: check-github-workflows
@@ -0,0 +1,18 @@
1
+ # .readthedocs.yaml
2
+ # Read the Docs configuration file
3
+ # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4
+
5
+ # Required
6
+ version: 2
7
+
8
+ build:
9
+ os: "ubuntu-22.04"
10
+ tools:
11
+ python: "3.12"
12
+ commands:
13
+ - asdf plugin add uv
14
+ - asdf install uv latest
15
+ - asdf global uv latest
16
+ - uv venv
17
+ - uv pip install .[docs]
18
+ - . .venv/bin/activate && sphinx-build -T -b html -d docs/_build/doctrees -D language=en docs $READTHEDOCS_OUTPUT/html
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: repo_review
3
- Version: 0.11.0
3
+ Version: 0.11.2
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
@@ -21,6 +21,7 @@ Classifier: Programming Language :: Python :: 3
21
21
  Classifier: Programming Language :: Python :: 3.10
22
22
  Classifier: Programming Language :: Python :: 3.11
23
23
  Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
24
25
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
25
26
  Classifier: Topic :: Software Development :: Quality Assurance
26
27
  Classifier: Typing :: Typed
@@ -38,7 +39,7 @@ Requires-Dist: click>=8; extra == 'dev'
38
39
  Requires-Dist: pytest>=7; extra == 'dev'
39
40
  Requires-Dist: rich-click; extra == 'dev'
40
41
  Requires-Dist: rich>=12.2; extra == 'dev'
41
- Requires-Dist: sp-repo-review>=2023.12.21; extra == 'dev'
42
+ Requires-Dist: sp-repo-review>=2024.08.19; extra == 'dev'
42
43
  Requires-Dist: validate-pyproject>=0.14; extra == 'dev'
43
44
  Provides-Extra: docs
44
45
  Requires-Dist: click>=8; extra == 'docs'
@@ -54,7 +55,7 @@ Requires-Dist: sphinxcontrib-programoutput; extra == 'docs'
54
55
  Requires-Dist: sphinxext-opengraph; extra == 'docs'
55
56
  Provides-Extra: test
56
57
  Requires-Dist: pytest>=7; extra == 'test'
57
- Requires-Dist: sp-repo-review>=2023.12.21; extra == 'test'
58
+ Requires-Dist: sp-repo-review>=2024.08.19; extra == 'test'
58
59
  Requires-Dist: validate-pyproject>=0.14; extra == 'test'
59
60
  Description-Content-Type: text/markdown
60
61
 
@@ -76,7 +77,7 @@ least one plugin to be installed.
76
77
  With one or more plugins, it will produce a list of results - green checkmarks
77
78
  mean this rule is followed, red x’s mean the rule is not. A yellow warning sign
78
79
  means that the check was skipped because a previous required check failed. Four
79
- output formats are supported; `rich`, `svg`, `html`, and `json`.
80
+ output formats are supported: `rich`, `svg`, `html`, and `json`.
80
81
 
81
82
  ## Plugins
82
83
 
@@ -140,7 +141,7 @@ the files that interest the plugin in question.
140
141
 
141
142
  So if you want to lint Python code, use Flake8 or Ruff. But if you want to
142
143
  check Flake8 or Ruff's configuration, use repo-review! Generally, repo-review
143
- plugins are more about requiring things to be present, like making use all your
144
+ plugins are more about requiring things to be present, like making sure all your
144
145
  repos have some [pre-commit][] check.
145
146
 
146
147
  ## Development of repo-review and plugins
@@ -169,7 +170,7 @@ accept fixtures, allowing dynamic check listings.
169
170
  Check files do not depend on the main library, and can be extended (similar to
170
171
  Flake8). You register new check files via entry-points - so extending this is
171
172
  with custom checks or custom fixtures is easy and trivial. There's no need to
172
- subclass or do anything with the base library - no dependency required.
173
+ subclass or do anything with the base library - no dependency on repo-review required.
173
174
 
174
175
  Checks are as simple as possible so they are easy to write. A check is a class
175
176
  with the name (1-2 letters + number) and a docstring (the check message). It
@@ -16,7 +16,7 @@ least one plugin to be installed.
16
16
  With one or more plugins, it will produce a list of results - green checkmarks
17
17
  mean this rule is followed, red x’s mean the rule is not. A yellow warning sign
18
18
  means that the check was skipped because a previous required check failed. Four
19
- output formats are supported; `rich`, `svg`, `html`, and `json`.
19
+ output formats are supported: `rich`, `svg`, `html`, and `json`.
20
20
 
21
21
  ## Plugins
22
22
 
@@ -80,7 +80,7 @@ the files that interest the plugin in question.
80
80
 
81
81
  So if you want to lint Python code, use Flake8 or Ruff. But if you want to
82
82
  check Flake8 or Ruff's configuration, use repo-review! Generally, repo-review
83
- plugins are more about requiring things to be present, like making use all your
83
+ plugins are more about requiring things to be present, like making sure all your
84
84
  repos have some [pre-commit][] check.
85
85
 
86
86
  ## Development of repo-review and plugins
@@ -109,7 +109,7 @@ accept fixtures, allowing dynamic check listings.
109
109
  Check files do not depend on the main library, and can be extended (similar to
110
110
  Flake8). You register new check files via entry-points - so extending this is
111
111
  with custom checks or custom fixtures is easy and trivial. There's no need to
112
- subclass or do anything with the base library - no dependency required.
112
+ subclass or do anything with the base library - no dependency on repo-review required.
113
113
 
114
114
  Checks are as simple as possible so they are easy to write. A check is a class
115
115
  with the name (1-2 letters + number) and a docstring (the check message). It
@@ -26,7 +26,7 @@ runs:
26
26
  - uses: actions/setup-python@v5
27
27
  id: python
28
28
  with:
29
- python-version: "3.11"
29
+ python-version: "3.12"
30
30
  update-environment: false
31
31
 
32
32
  - name: Install repo-review and plugins
@@ -1,8 +1,11 @@
1
+ from __future__ import annotations
2
+
1
3
  import importlib
2
4
  import importlib.metadata
3
5
  import inspect
4
6
  import os
5
7
  from pathlib import Path
8
+ from typing import Any
6
9
 
7
10
  import repo_review
8
11
 
@@ -39,6 +42,24 @@ exclude_patterns = [
39
42
 
40
43
  html_theme = "furo"
41
44
 
45
+ html_theme_options: dict[str, Any] = {
46
+ "footer_icons": [
47
+ {
48
+ "name": "GitHub",
49
+ "url": "https://github.com/scientific-python/repo-review",
50
+ "html": """
51
+ <svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 16 16">
52
+ <path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path>
53
+ </svg>
54
+ """,
55
+ "class": "",
56
+ },
57
+ ],
58
+ "source_repository": "https://github.com/scientific-python/repo-review/",
59
+ "source_branch": "main",
60
+ "source_directory": "docs/",
61
+ }
62
+
42
63
  myst_enable_extensions = [
43
64
  "colon_fence",
44
65
  "deflist",
@@ -6,7 +6,7 @@
6
6
  content="initial-scale=1, width=device-width"
7
7
  />
8
8
  <script
9
- src="https://cdn.jsdelivr.net/pyodide/v0.25.1/full/pyodide.js"
9
+ src="https://cdn.jsdelivr.net/pyodide/v0.26.2/full/pyodide.js"
10
10
  crossorigin
11
11
  ></script>
12
12
  <!-- Production -->
@@ -19,7 +19,7 @@
19
19
  crossorigin
20
20
  ></script>
21
21
  <script
22
- src="https://unpkg.com/@mui/material@v5.15.16/umd/material-ui.production.min.js"
22
+ src="https://unpkg.com/@mui/material@v5.16.7/umd/material-ui.production.min.js"
23
23
  crossorigin
24
24
  ></script>
25
25
  <!-- Development
@@ -32,7 +32,7 @@
32
32
  crossorigin
33
33
  ></script>
34
34
  <script
35
- src="https://unpkg.com/@mui/material@v5.15.16/umd/material-ui.development.js"
35
+ src="https://unpkg.com/@mui/material@v5.16.7/umd/material-ui.development.js"
36
36
  crossorigin
37
37
  ></script>
38
38
  -->
@@ -64,10 +64,10 @@
64
64
  <App
65
65
  header={true}
66
66
  deps={[
67
- "repo-review~=0.10.0",
68
- "sp-repo-review==2024.04.23",
69
- "validate-pyproject-schema-store==2024.04.20",
70
- "validate-pyproject[all]~=0.16.0",
67
+ "repo-review~=0.11.0",
68
+ "sp-repo-review==2024.08.19",
69
+ "validate-pyproject-schema-store== 2024.08.19",
70
+ "validate-pyproject[all]~=0.19.0",
71
71
  ]}
72
72
  />,
73
73
  );
@@ -43,7 +43,7 @@ def test_has_tool_ruff(tmp_path: Path) -> None:
43
43
  # In this example, tool.ruff is required to be present by this plugin
44
44
  d = tmp_path / "some_package"
45
45
  d.mkdir()
46
- d.joinpath("pyproject.toml").write_text("[tool.ruff]")
46
+ d.joinpath("pyproject.toml").write_text("[tool.ruff]", encoding="utf-8")
47
47
  processed = repo_review_processor.process(d)
48
48
  assert all(r.result for r in processed.results), f"{processed.results}"
49
49
  ```
@@ -20,7 +20,7 @@ You can also use the `html` output and write your own webapp. You need to provid
20
20
 
21
21
  ```html
22
22
  <script
23
- src="https://cdn.jsdelivr.net/pyodide/v0.23.2/full/pyodide.js"
23
+ src="https://cdn.jsdelivr.net/pyodide/v0.25.1/full/pyodide.js"
24
24
  crossorigin
25
25
  ></script>
26
26
  ```
@@ -44,13 +44,10 @@ You can get the families and the checks:
44
44
 
45
45
  ```js
46
46
  result_html_py = pyodide.runPython(`
47
- from pyodide.http import open_url
48
47
  from repo_review.processor import process
49
48
  from repo_review.ghpath import GHPath
50
49
  from repo_review.html import to_html
51
50
 
52
- GHPath.open_url = staticmethod(open_url)
53
-
54
51
  package = GHPath(repo="${state.repo}", branch="${state.branch}")
55
52
  to_html(*process(package))
56
53
  `);
@@ -23,6 +23,7 @@ classifiers = [
23
23
  "Programming Language :: Python :: 3.10",
24
24
  "Programming Language :: Python :: 3.11",
25
25
  "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
26
27
  "Programming Language :: Python",
27
28
  "Topic :: Software Development :: Quality Assurance",
28
29
  "Topic :: Software Development :: Libraries :: Python Modules",
@@ -44,7 +45,7 @@ cli = [
44
45
  ]
45
46
  test = [
46
47
  "pytest >=7",
47
- "sp-repo-review >=2023.12.21",
48
+ "sp-repo-review >=2024.08.19",
48
49
  "validate-pyproject >=0.14",
49
50
  ]
50
51
  dev = [
@@ -89,6 +90,7 @@ installer = "uv"
89
90
 
90
91
  [tool.hatch.envs.hatch-test]
91
92
  features = ["test", "cli"]
93
+ env-vars.PYTHONWARNDEFAULTENCODING = "1"
92
94
 
93
95
  [tool.hatch.envs.lint]
94
96
  dependencies = ["pre-commit"]
@@ -97,7 +99,7 @@ scripts.lint = "pre-commit run --all-files --show-diff-on-failure {args}"
97
99
 
98
100
  [tool.hatch.envs.pylint]
99
101
  features = ["cli"]
100
- dependencies = ["pylint"]
102
+ dependencies = ["pylint>=3.2"]
101
103
  scripts.lint = "pylint repo_review {args}"
102
104
 
103
105
  [tool.hatch.envs.docs]
@@ -122,7 +124,7 @@ skip-install = true
122
124
  scripts.serve = "cd docs && echo 'Serving on http://localhost:8080' && python -m http.server 8080"
123
125
 
124
126
  [[tool.hatch.envs.hatch-test.matrix]]
125
- python = ["3.12", "3.11", "3.10"]
127
+ python = ["3.13", "3.12", "3.11", "3.10"]
126
128
 
127
129
 
128
130
  [tool.pytest.ini_options]
@@ -178,9 +180,6 @@ messages_control.disable = [
178
180
  ]
179
181
 
180
182
 
181
- [tool.ruff]
182
- src = ["src"]
183
-
184
183
  [tool.ruff.lint]
185
184
  extend-select = [
186
185
  "B", # flake8-bugbear
@@ -224,7 +223,3 @@ typing-modules = ["repo_review._compat.typing"]
224
223
  [tool.ruff.lint.per-file-ignores]
225
224
  "src/repo_review/_compat/**.py" = ["TID251"]
226
225
  "src/**/__main__.py" = ["T20"]
227
-
228
-
229
- [tool.repo-review]
230
- ignore = ["PC110"]
@@ -1,7 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import importlib.metadata
3
4
  import itertools
4
5
  import json
6
+ import os
5
7
  import sys
6
8
  import typing
7
9
  from collections.abc import Mapping, Sequence
@@ -73,6 +75,29 @@ def list_all(ctx: click.Context, _param: click.Parameter, value: bool) -> None:
73
75
  ctx.exit()
74
76
 
75
77
 
78
+ def all_versions(ctx: click.Context, _param: click.Parameter, value: bool) -> None:
79
+ if not value or ctx.resilient_parsing:
80
+ return
81
+
82
+ groups = ["repo_review.checks", "repo_review.families", "repo_review.fixtures"]
83
+ packages = {
84
+ dist.name: dist.version
85
+ for group in groups
86
+ for ep in importlib.metadata.entry_points(group=group)
87
+ if (dist := ep.dist) is not None
88
+ }
89
+ deps = ["rich", "rich-click", "click", "markdown-it-py", "pyyaml"]
90
+ rich.print("Repo-review's dependencies:")
91
+ for name in deps:
92
+ rich.print(
93
+ f" [bold]{name}[/bold]: [magenta]{importlib.metadata.version(name)}[/magenta]"
94
+ )
95
+ rich.print("Packages providing repo-review plugins:")
96
+ for name, version in sorted(packages.items()):
97
+ rich.print(f" [bold]{name}[/bold]: [green]{version}[/green]")
98
+ ctx.exit()
99
+
100
+
76
101
  def rich_printer(
77
102
  families: Mapping[str, Family],
78
103
  processed: list[Result],
@@ -83,6 +108,17 @@ def rich_printer(
83
108
  status: Status,
84
109
  header: str = "",
85
110
  ) -> None:
111
+ # Before Python 3.15, this isn't always unicode
112
+ if (
113
+ sys.version_info < (3, 15)
114
+ and "PYTHONIOENCODING" not in os.environ
115
+ and "PYTHONUTF8" not in os.environ
116
+ ):
117
+ if sys.stdout.encoding != "utf-8":
118
+ sys.stdout.reconfigure(encoding="utf-8") # type: ignore[union-attr]
119
+ if sys.stderr.encoding != "utf-8":
120
+ sys.stderr.reconfigure(encoding="utf-8") # type: ignore[union-attr]
121
+
86
122
  console = rich.console.Console(
87
123
  record=svg, quiet=svg, stderr=stderr, color_system="auto" if color else None
88
124
  )
@@ -231,9 +267,25 @@ def _remote_path_processor(package: Path) -> Path | GHPath:
231
267
  "packages",
232
268
  type=click.Path(dir_okay=True, path_type=Path),
233
269
  nargs=-1,
234
- required=True,
270
+ required=False,
235
271
  callback=remote_path_support,
236
272
  )
273
+ @click.option(
274
+ "--versions",
275
+ is_flag=True,
276
+ callback=all_versions,
277
+ expose_value=False,
278
+ is_eager=True,
279
+ help="List all plugin versions and exit",
280
+ )
281
+ @click.option(
282
+ "--list-all",
283
+ is_flag=True,
284
+ callback=list_all,
285
+ expose_value=False,
286
+ is_eager=True,
287
+ help="List all checks and exit",
288
+ )
237
289
  @click.option(
238
290
  "--format",
239
291
  "format_opt",
@@ -247,6 +299,12 @@ def _remote_path_processor(package: Path) -> Path | GHPath:
247
299
  type=click.Choice(["rich", "json", "html", "svg"]),
248
300
  help="Select additional output format for stderr. Will disable terminal escape codes for stdout for easy redirection.",
249
301
  )
302
+ @click.option(
303
+ "--show",
304
+ type=click.Choice(["all", "err", "errskip"]),
305
+ default="all",
306
+ help="Show all (default), or just errors, or errors and skips",
307
+ )
250
308
  @click.option(
251
309
  "--select",
252
310
  help="Only run certain checks, comma separated. All checks run if empty.",
@@ -263,20 +321,6 @@ def _remote_path_processor(package: Path) -> Path | GHPath:
263
321
  help="Path to python package.",
264
322
  default="",
265
323
  )
266
- @click.option(
267
- "--list-all",
268
- is_flag=True,
269
- callback=list_all,
270
- expose_value=False,
271
- is_eager=True,
272
- help="List all checks and exit",
273
- )
274
- @click.option(
275
- "--show",
276
- type=click.Choice(["all", "err", "errskip"]),
277
- default="all",
278
- help="Show all (default), or just errors, or errors and skips",
279
- )
280
324
  def main(
281
325
  packages: list[Path | GHPath],
282
326
  format_opt: Formats,
@@ -287,8 +331,11 @@ def main(
287
331
  show: Show,
288
332
  ) -> None:
289
333
  """
290
- Pass in a local Path or gh:org/repo@branch.
334
+ Pass in a local Path or gh:org/repo@branch. Will run on the current
335
+ directory if no path passed.
291
336
  """
337
+ if not packages:
338
+ packages = [Path()]
292
339
 
293
340
  if len(packages) > 1:
294
341
  if format_opt == "json":
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.11.0'
16
- __version_tuple__ = version_tuple = (0, 11, 0)
15
+ __version__ = version = '0.11.2'
16
+ __version_tuple__ = version_tuple = (0, 11, 2)
@@ -89,9 +89,8 @@ def is_allowed(select: Set[str], ignore: Set[str], name: str) -> bool:
89
89
  and "*" not in select
90
90
  ):
91
91
  return False
92
- if name in ignore or name.rstrip("0123456789") in ignore:
93
- return False
94
- return True
92
+
93
+ return name not in ignore and name.rstrip("0123456789") not in ignore
95
94
 
96
95
 
97
96
  def get_check_url(name: str, check: Check) -> str:
@@ -1,9 +1,11 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import copy
3
4
  import dataclasses
4
5
  import graphlib
5
6
  import textwrap
6
7
  import typing
8
+ import warnings
7
9
  from collections.abc import Mapping, Set
8
10
  from typing import Any, TypeVar
9
11
 
@@ -211,13 +213,18 @@ def process(
211
213
 
212
214
  # Keep track of which checks have been completed
213
215
  completed: dict[str, str | None] = {}
216
+ fixtures_copy = copy.deepcopy(fixtures)
214
217
 
215
218
  # Run all the checks in topological order based on their dependencies
216
219
  ts = graphlib.TopologicalSorter(graph)
217
220
  for name in ts.static_order():
218
221
  if all(completed.get(n, "") == "" for n in graph[name]):
219
- result = apply_fixtures({"name": name, **fixtures}, tasks[name].check)
222
+ result = apply_fixtures({"name": name, **fixtures_copy}, tasks[name].check)
220
223
  completed[name] = process_result_bool(result, tasks[name], name)
224
+ if fixtures != fixtures_copy:
225
+ fixtures_copy = copy.deepcopy(fixtures)
226
+ msg = f"{name} modified the input fixtures! Making a deepcopy to fix and continue."
227
+ warnings.warn(msg, stacklevel=1)
221
228
  else:
222
229
  completed[name] = None
223
230
 
@@ -9,7 +9,18 @@
9
9
  "$ref": "#/$defs/checks"
10
10
  },
11
11
  "ignore": {
12
- "$ref": "#/$defs/checks"
12
+ "oneOf": [
13
+ {
14
+ "$ref": "#/$defs/checks"
15
+ },
16
+ {
17
+ "type": "object",
18
+ "patternProperties": {
19
+ "^[A-Z]+[0-9]*$": { "type": "string" }
20
+ },
21
+ "additionalProperties": false
22
+ }
23
+ ]
13
24
  }
14
25
  },
15
26
  "$defs": {
@@ -9,7 +9,7 @@ def nocolor(monkeypatch: pytest.MonkeyPatch) -> None:
9
9
  monkeypatch.delenv("FORCE_COLOR", raising=False)
10
10
 
11
11
 
12
- @pytest.fixture()
12
+ @pytest.fixture
13
13
  def no_entry_points(monkeypatch: pytest.MonkeyPatch) -> None:
14
14
  monkeypatch.setattr(
15
15
  importlib.metadata,
@@ -18,7 +18,7 @@ def no_entry_points(monkeypatch: pytest.MonkeyPatch) -> None:
18
18
  )
19
19
 
20
20
 
21
- @pytest.fixture()
21
+ @pytest.fixture
22
22
  def local_entry_points(monkeypatch: pytest.MonkeyPatch) -> None:
23
23
  orig_ep = importlib.metadata.entry_points
24
24
  ep1 = importlib.metadata.EntryPoint(
@@ -10,7 +10,7 @@ from click.testing import CliRunner
10
10
  from repo_review.__main__ import main
11
11
 
12
12
 
13
- @pytest.fixture()
13
+ @pytest.fixture
14
14
  def multiple_packages(tmp_path: Path) -> tuple[str, str]:
15
15
  packages = (tmp_path / "package_1", tmp_path / "package_2")
16
16
 
@@ -28,7 +28,7 @@ def multiple_packages(tmp_path: Path) -> tuple[str, str]:
28
28
  """
29
29
  )
30
30
 
31
- package.joinpath("pyproject.toml").write_text(basic_toml)
31
+ package.joinpath("pyproject.toml").write_text(basic_toml, encoding="utf-8")
32
32
  package.joinpath(".pre-commit-config.yaml").touch()
33
33
  package.joinpath("README.md").touch()
34
34
 
@@ -36,16 +36,54 @@ def test_broken_validate_pyproject(tmp_path: Path) -> None:
36
36
  [tool.repo-review]
37
37
  ignore = ["a2"]
38
38
  """
39
- )
39
+ ),
40
+ encoding="utf-8",
40
41
  )
41
42
 
42
43
  results = process(tmp_path)
43
44
 
44
45
  (result,) = (r for r in results.results if r.name == "VPP001")
45
- assert "must match pattern" in result.err_msg
46
+ assert "must be valid exactly by one definition" in result.err_msg
46
47
  assert not result.result
47
48
 
48
49
 
50
+ def test_broken_validate_pyproject_object(tmp_path: Path) -> None:
51
+ pytest.importorskip("validate_pyproject")
52
+ tmp_path.joinpath("pyproject.toml").write_text(
53
+ textwrap.dedent(
54
+ """\
55
+ [tool.repo-review.ignore]
56
+ a2 = "some message"
57
+ """
58
+ ),
59
+ encoding="utf-8",
60
+ )
61
+
62
+ results = process(tmp_path)
63
+
64
+ (result,) = (r for r in results.results if r.name == "VPP001")
65
+ assert "must be valid exactly by one definition" in result.err_msg
66
+ assert not result.result
67
+
68
+
69
+ def test_working_validate_pyproject_object(tmp_path: Path) -> None:
70
+ pytest.importorskip("validate_pyproject")
71
+ tmp_path.joinpath("pyproject.toml").write_text(
72
+ textwrap.dedent(
73
+ """\
74
+ [tool.repo-review.ignore]
75
+ PP102 = "some message"
76
+ """
77
+ ),
78
+ encoding="utf-8",
79
+ )
80
+
81
+ results = process(tmp_path)
82
+
83
+ (result,) = (r for r in results.results if r.name == "VPP001")
84
+ assert result.result
85
+
86
+
49
87
  def test_testing_function():
50
88
  pytest.importorskip("sp_repo_review")
51
89
 
@@ -5,7 +5,7 @@ build-backend = "flit_core.buildapi"
5
5
  [project]
6
6
  name = "pyproject"
7
7
  version = "0.0.1"
8
- classfiers = [
8
+ classifiers = [
9
9
  "Private :: Do Not Upload",
10
10
  ]
11
11
  description = "Simple repo-review example for testing"
@@ -1,32 +0,0 @@
1
- {
2
- "problemMatcher": [
3
- {
4
- "severity": "warning",
5
- "pattern": [
6
- {
7
- "regexp": "^([^:]+):(\\d+):(\\d+): ([A-DF-Z]\\d+): \\033\\[[\\d;]+m([^\\033]+).*$",
8
- "file": 1,
9
- "line": 2,
10
- "column": 3,
11
- "code": 4,
12
- "message": 5
13
- }
14
- ],
15
- "owner": "pylint-warning"
16
- },
17
- {
18
- "severity": "error",
19
- "pattern": [
20
- {
21
- "regexp": "^([^:]+):(\\d+):(\\d+): (E\\d+): \\033\\[[\\d;]+m([^\\033]+).*$",
22
- "file": 1,
23
- "line": 2,
24
- "column": 3,
25
- "code": 4,
26
- "message": 5
27
- }
28
- ],
29
- "owner": "pylint-error"
30
- }
31
- ]
32
- }
@@ -1,22 +0,0 @@
1
- # .readthedocs.yaml
2
- # Read the Docs configuration file
3
- # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4
-
5
- # Required
6
- version: 2
7
-
8
- build:
9
- os: "ubuntu-22.04"
10
- tools:
11
- python: "3.11"
12
-
13
- # Build documentation in the docs/ directory with Sphinx
14
- sphinx:
15
- configuration: docs/conf.py
16
-
17
- python:
18
- install:
19
- - method: pip
20
- path: .
21
- extra_requirements:
22
- - docs
File without changes
File without changes
File without changes
File without changes
File without changes