{"id":42194637,"url":"https://github.com/scientific-python/repo-review","last_synced_at":"2026-04-03T18:01:24.913Z","repository":{"id":37830511,"uuid":"472940552","full_name":"scientific-python/repo-review","owner":"scientific-python","description":"Framework that can run checks on repos","archived":false,"fork":false,"pushed_at":"2026-03-27T02:31:44.000Z","size":585,"stargazers_count":87,"open_issues_count":2,"forks_count":7,"subscribers_count":5,"default_branch":"main","last_synced_at":"2026-03-27T07:50:10.559Z","etag":null,"topics":["linter","python"],"latest_commit_sha":null,"homepage":"https://repo-review.readthedocs.io","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/scientific-python.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2022-03-22T21:17:20.000Z","updated_at":"2026-03-27T02:31:46.000Z","dependencies_parsed_at":"2024-01-29T22:07:35.175Z","dependency_job_id":"44307c21-56fa-4a78-ae27-31310cb09345","html_url":"https://github.com/scientific-python/repo-review","commit_stats":{"total_commits":303,"total_committers":7,"mean_commits":"43.285714285714285","dds":0.5478547854785478,"last_synced_commit":"df151f1e9327ccc7b7debd36dc60bdbc5d85f0a8"},"previous_names":["scikit-hep/repo-review"],"tags_count":47,"template":false,"template_full_name":null,"purl":"pkg:github/scientific-python/repo-review","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scientific-python%2Frepo-review","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scientific-python%2Frepo-review/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scientific-python%2Frepo-review/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scientific-python%2Frepo-review/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scientific-python","download_url":"https://codeload.github.com/scientific-python/repo-review/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scientific-python%2Frepo-review/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31368156,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-03T17:53:18.093Z","status":"ssl_error","status_checked_at":"2026-04-03T17:53:17.617Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["linter","python"],"created_at":"2026-01-27T00:02:05.083Z","updated_at":"2026-04-03T18:01:24.871Z","avatar_url":"https://github.com/scientific-python.png","language":"Python","readme":"# repo-review\n\n[![Actions Status][actions-badge]][actions-link]\n[![Documentation Status][docs-badge]][docs-link]\n\n[![PyPI version][pypi-version]][pypi-link]\n[![Conda-Forge][conda-badge]][conda-link]\n[![PyPI platforms][pypi-platforms]][pypi-link]\n\n\u003c!-- SPHINX-START --\u003e\n\nThis is a framework for building checks designed to check to see if a\nrepository follows guidelines. By itself, it does nothing - it requires at\nleast one plugin to be installed.\n\nWith one or more plugins, it will produce a list of results - green checkmarks\nmean this rule is followed, red x’s mean the rule is not. A yellow warning sign\nmeans that the check was skipped because a previous required check failed. Four\noutput formats are supported: `rich`, `svg`, `html`, and `json`.\n\n## Plugins\n\nThese are some known plugins. Feel free to request your plugin be added to this\nlist.\n\n- [sp-repo-review][]: Checks based on the [Scientific-Python Development Guide][] at [scientific-python/cookie][].\n- [validate-pyproject][]: Adds a check to validate pyproject sections, also supports plugins (like [validate-pyproject-schema-store][]).\n\n`repo-review` itself also acts as a plugin for [validate-pyproject][], allowing\nyou to validate the `[tool.repo-review]` section of your `pyproject.toml`.\n\nA live WebAssembly demo using [sp-repo-review][] and [validate-pyproject][] is\n[available here][repo-review-demo].\n\n## Running repo-review\n\nRepo-review supports running multiple ways:\n\n- [From the command line][cli] on a local folder (or multiple folders).\n- From the command line on a remote repository on GitHub (`gh:org/repo[@branch][:path]`)\n- [From WebAssembly][webapp] in [Pyodide][] (example in `docs/index.html`)\n- [From pre-commit][intro-pre-commit] (see caveats there)\n- [From GitHub Actions][intro-github-actions]\n- [From Python][programmatic-usage]\n\nWhen installing, make sure you also install at least one plugin, as\n`repo-review` has no integrated checks. If you are using the command line\ninterface, make sure you include the `cli` extra (`repo-review[cli]`). Some\nplugins, like `sp-repo-review`, support running directly, such as:\n\n```bash\npipx run sp-repo-review[cli] \u003cargs\u003e\n```\n\nIf the root of a package is not the repository root, pass `--package-dir a/b/c`.\n\n## Configuration\n\nRepo-review [supports configuration][intro-configuring] via `pyproject.toml`:\n\n```toml\n[tool.repo-review]\nselect = [\"A\", \"B\", \"C100\"]\nignore = [\"A100\"]\n```\n\nThe ignore list can also be a table, with reasons for values.\n\nIf `--select` or `--ignore` are given on the command line, they will override\nthe `pyproject.toml` config. You can use `--extend-select` and `--extend-ignore`\non the command line to extend the `pyproject.toml` config. These CLI options\nare comma separated.\n\n## Comparison to other frameworks\n\nRepo-review was inspired by frameworks like [Flake8][] and [Ruff][]. It is\nprimarily different in two ways: It was designed to look at configuration files\nrather than Python files; which means it also only needs a subset of the\nrepository (since most files are not configuration files). And it was designed\nto be runnable on external repositories, rather than pre-configured and run\nfrom inside the repository (which it can be). These differences also power the\nWebAssembly/remote version, which only needs to make a few API calls to look at\nthe files that interest the plugin in question.\n\nSo if you want to lint Python code, use Flake8 or Ruff. But if you want to\ncheck Flake8 or Ruff's configuration, use repo-review! Generally, repo-review\nplugins are more about requiring things to be present, like making sure all your\nrepos have some [pre-commit][] check.\n\n## Development of repo-review and plugins\n\nThis project is intended to be fun and easy to develop and design checks for -\nit requires and uses Python 3.10+, and uses a lot of the new features in 3.9 and\n3.10. It's maybe not entirely conventional, but it enables very simple plugin\ndevelopment. It works locally, remotely, and in WebAssembly (using\n[Pyodide][]). [See the docs][writing-a-plugin].\n\nThere are a few key designs that are very useful and make this possible. First,\nall paths are handled as Traversables. This allows a simple Traversable\nimplementation based on `open_url` to provide a web interface for use in the\nwebapp. It also would allow `zipfile.Path` to work just as well, too - no need\nto extract.\n\n[Checks][] can request [fixtures][] (like [pytest][]) as arguments. Check files\ncan add new fixtures as needed. Fixtures are specified with entry points,\nand take any other fixture as arguments as well - the `root` and `package`\nfixtures represents the root of the repository and of the package you are\nchecking, respectively, and are the basis for the other fixtures, which are\ntopologically sorted and cached. `pyproject` is provided as well. Checks are\nspecified via an entrypoint that returns a dict of checks; this can also can\naccept fixtures, allowing dynamic check listings.\n\nCheck files do not depend on the main library, and can be extended (similar to\nFlake8). You register new check files via entry-points - so extending this is\nwith custom checks or custom fixtures is easy and trivial. There's no need to\nsubclass or do anything with the base library - no dependency on repo-review required.\n\nChecks are as simple as possible so they are easy to write. A check is a class\nwith the name (1-2 letters + number) and a docstring (the check message). It\nshould define a set of `requires` with any checks it depends on (by name), and\nhave a check classmethod. The docstring of this method is the failure message,\nand supports substitution. Arguments to this method are fixtures, and `root` or\n`package` are built-in providing a Traversable. Any other fixtures are available\nby name. A new fixture can use any other fixtures, and can produce anything;\nfixtures are topologically sorted, pre-computed and cached.\n\nThe runner will topologically sort the checks, and checks that do not run will\nget a `None` result and the check method will not run. The front-end (Rich\npowered CLI or Pyodide webapp) will render the markdown-formatted check\ndocstring only if the result is `False`.\n\nChecks are organized by [Families][]. A plugin can customize the display name,\nchange the sort order, and add an optional (dynamic) description. Like the other\ncollection functions, the family entry-point also supports fixtures.\n\n## Links\n\nThis project inspired [Try-PyHF](https://kratsg.github.io/try-pyhf/), an\ninterface for a High Energy Physics package in Scikit-HEP.\n\nThis project inspired [abSENSE](https://princetonuniversity.github.io/abSENSE/), a\nweb interface to abSENSE.\n\nThis was developed for [Scikit-HEP][] before moving to Scientific-Python.\n\n\u003c!-- prettier-ignore-start --\u003e\n\n[actions-badge]: https://github.com/scientific-python/repo-review/workflows/CI/badge.svg\n[actions-link]: https://github.com/scientific-python/repo-review/actions\n[docs-badge]: https://readthedocs.org/projects/repo-review/badge/?version=latest\n[docs-link]: https://repo-review.readthedocs.io/en/latest/?badge=latest\n[flake8]: https://flake8.pycqa.org\n[pre-commit]: https://pre-commit.com\n[pyodide]: https://pyodide.org\n[pypi-link]: https://pypi.org/project/repo-review/\n[pypi-platforms]: https://img.shields.io/pypi/pyversions/repo-review\n[pypi-version]: https://badge.fury.io/py/repo-review.svg\n[pytest]: https://pytest.org\n[repo-review-demo]: https://scientific-python.github.io/repo-review\n[ruff]: https://beta.ruff.rs\n[scientific-python development guide]: https://learn.scientific-python.org/development\n[scientific-python/cookie]: https://github.com/scientific-python/cookie\n[scikit-hep]: https://scikit-hep.org\n[sp-repo-review]: https://pypi.org/project/sp-repo-review\n[validate-pyproject]: https://validate-pyproject.readthedocs.io\n[validate-pyproject-schema-store]: https://github.com/henryiii/validate-pyproject-schema-store\n[conda-badge]: https://img.shields.io/conda/vn/conda-forge/repo-review\n[conda-link]: https://github.com/conda-forge/repo-review-feedstock\n\n[intro-pre-commit]: https://repo-review.readthedocs.io/en/latest/intro.html#pre-commit\n[intro-github-actions]: https://repo-review.readthedocs.io/en/latest/intro.html#github-actions\n[cli]: https://repo-review.readthedocs.io/en/latest/cli.html\n[programmatic-usage]: https://repo-review.readthedocs.io/en/latest/programmatic.html\n[webapp]: https://repo-review.readthedocs.io/en/latest/webapp.html\n[intro-configuring]: https://repo-review.readthedocs.io/en/latest/intro.html#configuring\n[writing-a-plugin]: https://repo-review.readthedocs.io/en/latest/plugins.html\n[fixtures]: https://repo-review.readthedocs.io/en/latest/fixtures.html\n[checks]: https://repo-review.readthedocs.io/en/latest/checks.html\n[families]: https://repo-review.readthedocs.io/en/latest/families.html\n[changelog]: https://repo-review.readthedocs.io/en/latest/changelog.html\n[api]: https://repo-review.readthedocs.io/en/latest/api/repo_review.html\n\n\n\u003c!-- prettier-ignore-end --\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscientific-python%2Frepo-review","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscientific-python%2Frepo-review","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscientific-python%2Frepo-review/lists"}