repo-review 0.11.0__py3-none-any.whl → 0.11.2__py3-none-any.whl

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/__main__.py CHANGED
@@ -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":
repo_review/_version.py CHANGED
@@ -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)
repo_review/checks.py CHANGED
@@ -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:
repo_review/processor.py CHANGED
@@ -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": {
@@ -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
@@ -1,13 +1,13 @@
1
1
  repo_review/__init__.py,sha256=U03wTpj7PjSsIROp8O4VRG_NVG-plkx14d_MvqpmJ_w,229
2
- repo_review/__main__.py,sha256=YG78gWDM5ExHNTEhdtMNGvJBV44JU_IkR5mc_3a5fqs,12262
3
- repo_review/_version.py,sha256=HrIG2j3UEFJj4bW1AIsrTZ8_qquvls9ziUAr-b-m7iQ,413
2
+ repo_review/__main__.py,sha256=FjYamqrS55TYqFvz8TuZdJ5-C-l2QP3_6n8lLH04_8o,13890
3
+ repo_review/_version.py,sha256=v52WNNFq-_uq9OSfK9O7vLpi66zlufcyohjNPzWbpdk,413
4
4
  repo_review/_version.pyi,sha256=j5kbzfm6lOn8BzASXWjGIA1yT0OlHTWqlbyZ8Si_o0E,118
5
- repo_review/checks.py,sha256=hIwQARm0JESf0yMCfjR5jaI-AdnCO7ePTY28eQ2iOy4,4340
5
+ repo_review/checks.py,sha256=SzTnMxj756xMb9Rffl9K65o2rUGDYfG6CQCj-pNWQzk,4316
6
6
  repo_review/families.py,sha256=TEMQY3whMj8b3iVlWyVsTa0CAZexXRCFXq5uPIkV6bs,2389
7
7
  repo_review/fixtures.py,sha256=AHdUhDU--SOrlhWSymiyECp5LmaCGYNRcZHuPpzFUts,3709
8
8
  repo_review/ghpath.py,sha256=YadsOkd2hGOrDffSU3PtQiDLgvrVe1GuMKeDFKXwtLs,6123
9
9
  repo_review/html.py,sha256=LwoZUqiWC84qSuhwbzqQtwhWDhE8JiPWWTI4nKXF3nA,3485
10
- repo_review/processor.py,sha256=2NSbuC7jt_eMjIB9VpY0c5-TtKr9GWzA8Gr6Pvj2SqU,7951
10
+ repo_review/processor.py,sha256=txXKyw1VP31sclfQL0yac5mXYTkFoca3t-3yKBvqc5k,8275
11
11
  repo_review/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  repo_review/schema.py,sha256=U_iox0khN1oEHCCB5ILffjRvZLG7BR-aaip9QEpMkJk,593
13
13
  repo_review/testing.py,sha256=qbjevlG_DQbL4-l-7wTM9rqoLvRaxf7GF66D8i723OY,1915
@@ -18,9 +18,9 @@ repo_review/_compat/importlib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
18
18
  repo_review/_compat/importlib/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  repo_review/_compat/importlib/resources/abc.py,sha256=KLv7AqUaY-ezZ32lA5yVcZLfMqY6VEo8Q-1jyWpGRbk,300
20
20
  repo_review/resources/__init__.py,sha256=RBBaUp-hQrIYBqbAT0MytCXEjDmqVsCjiEgdK_K3dN4,138
21
- repo_review/resources/repo-review.schema.json,sha256=Ljna-BRuoKihOnJ5_78Fgs0ZrYHlgohmtS6x37TJbDg,556
22
- repo_review-0.11.0.dist-info/METADATA,sha256=KbsSwIu3142cRcV_SKA5ubvX6EvzU65OOlylD7ucIeI,11370
23
- repo_review-0.11.0.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
24
- repo_review-0.11.0.dist-info/entry_points.txt,sha256=9XaDWanm31NNpXOpjZh2HxSXR5owVdYJ2cbNG5D8wY8,244
25
- repo_review-0.11.0.dist-info/licenses/LICENSE,sha256=X7yOxzyAEckYl17p01lZzbraqDVmWEWXE8BnKKRrh7c,1525
26
- repo_review-0.11.0.dist-info/RECORD,,
21
+ repo_review/resources/repo-review.schema.json,sha256=jAc7ZQV-Hc16ENrNFZm7nlIjiRQGTanq8EjBICkJKpE,791
22
+ repo_review-0.11.2.dist-info/METADATA,sha256=uCkBoPbRRxwzV-ZqOj070MBQiZL5sh4E3l7ENJhgs9M,11437
23
+ repo_review-0.11.2.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
24
+ repo_review-0.11.2.dist-info/entry_points.txt,sha256=9XaDWanm31NNpXOpjZh2HxSXR5owVdYJ2cbNG5D8wY8,244
25
+ repo_review-0.11.2.dist-info/licenses/LICENSE,sha256=X7yOxzyAEckYl17p01lZzbraqDVmWEWXE8BnKKRrh7c,1525
26
+ repo_review-0.11.2.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.24.2
2
+ Generator: hatchling 1.25.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any