pycmdcheck 0.1.0__tar.gz → 0.1.1__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.
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/.github/workflows/ci.yml +4 -4
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/.github/workflows/release.yml +5 -5
- pycmdcheck-0.1.1/CHANGELOG.md +69 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/PKG-INFO +13 -23
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/README.md +9 -19
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_quarto.yml +1 -1
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/cli.qmd +23 -8
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/configuration.qmd +1 -1
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/getting-started.qmd +11 -20
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/index.qmd +2 -7
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/pyproject.toml +4 -4
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/__init__.py +5 -6
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/checks/metadata.py +4 -2
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/checks/structure.py +4 -1
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/checks/tests.py +2 -1
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/checks/typing.py +2 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/cli.py +15 -2
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/discovery.py +9 -15
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/profiles.py +8 -4
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/runner.py +8 -8
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_cli.py +28 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_profiles.py +30 -1
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/uv.lock +1 -1
- pycmdcheck-0.1.0/CHANGELOG.md +0 -78
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/.devcontainer/Dockerfile +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/.devcontainer/devcontainer.json +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/.devcontainer/requirements-dev.txt +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/.gitignore +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/LICENSE +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/.gitignore +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_extensions/machow/interlinks/.gitignore +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_extensions/machow/interlinks/_extension.yml +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_extensions/machow/interlinks/interlinks.lua +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_extensions/machow/interlinks/objects.txt +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_extensions/machow/interlinks/test.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_inv/python_objects.json +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/changelog.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/cli.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/configuration.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/custom-checks.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/getting-started.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/index.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/reference/CheckResult.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/reference/CheckStatus.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/reference/Report.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/reference/check.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/reference/checks.base.BaseCheck.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/reference/checks.base.Check.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/reference/checks.docs.DocsCheck.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/reference/checks.imports.ImportsCheck.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/reference/checks.license.LicenseCheck.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/reference/checks.linting.LintingCheck.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/reference/checks.metadata.MetadataCheck.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/reference/checks.structure.StructureCheck.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/reference/checks.tests.TestsCheck.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/reference/checks.typing.TypingCheck.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/reference/config.get_check_config.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/reference/config.is_check_enabled.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/reference/config.load_config.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/reference/discovery.discover_checks.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/reference/discovery.list_available_checks.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/reference/index.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/reference/runner.run_checks.html +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/search.json +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/site_libs/bootstrap/bootstrap-5b4ad623e5705c0698d39aec6f10cf02.min.css +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/site_libs/bootstrap/bootstrap-icons.css +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/site_libs/bootstrap/bootstrap-icons.woff +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/site_libs/bootstrap/bootstrap.min.js +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/site_libs/clipboard/clipboard.min.js +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/site_libs/quarto-html/anchor.min.js +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/site_libs/quarto-html/axe/axe-check.js +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/site_libs/quarto-html/popper.min.js +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/site_libs/quarto-html/quarto-syntax-highlighting-587c61ba64f3a5504c4d52d930310e48.css +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/site_libs/quarto-html/quarto.js +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/site_libs/quarto-html/tabsets/tabsets.js +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/site_libs/quarto-html/tippy.css +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/site_libs/quarto-html/tippy.umd.min.js +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/site_libs/quarto-nav/headroom.min.js +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/site_libs/quarto-nav/quarto-nav.js +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/site_libs/quarto-search/autocomplete.umd.js +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/site_libs/quarto-search/fuse.min.js +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/_site/site_libs/quarto-search/quarto-search.js +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/changelog.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/custom-checks.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/objects.json +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/reference/CheckResult.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/reference/CheckStatus.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/reference/Report.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/reference/_sidebar.yml +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/reference/check.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/reference/checks.base.BaseCheck.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/reference/checks.base.Check.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/reference/checks.docs.DocsCheck.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/reference/checks.imports.ImportsCheck.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/reference/checks.license.LicenseCheck.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/reference/checks.linting.LintingCheck.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/reference/checks.metadata.MetadataCheck.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/reference/checks.structure.StructureCheck.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/reference/checks.tests.TestsCheck.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/reference/checks.typing.TypingCheck.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/reference/config.get_check_config.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/reference/config.is_check_enabled.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/reference/config.load_config.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/reference/discovery.discover_checks.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/reference/discovery.list_available_checks.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/reference/index.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/docs/reference/runner.run_checks.qmd +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/__main__.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/ast_cache.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/checks/__init__.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/checks/base.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/checks/build.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/checks/changelog.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/checks/ci.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/checks/citation.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/checks/community.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/checks/dependencies.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/checks/docs.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/checks/doctests.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/checks/formatting.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/checks/imports.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/checks/license.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/checks/linting.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/checks/py_typed.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/checks/python_versions.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/checks/urls.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/checks/version.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/config.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/constants.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/package_layout.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/py.typed +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/pyproject_reader.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/results.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/src/pycmdcheck/subprocess_runner.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/__init__.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/conftest.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_ast_cache.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_check_build.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_check_changelog.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_check_ci.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_check_citation.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_check_community.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_check_dependencies.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_check_deps_enhanced.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_check_docs.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_check_doctests.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_check_formatting.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_check_license.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_check_metadata.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_check_py_typed.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_check_python_versions.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_check_urls.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_check_version.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_checks.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_config.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_config_validation.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_integration.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_package_layout.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_pyproject_reader.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_results.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_runner.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_subprocess_runner.py +0 -0
- {pycmdcheck-0.1.0 → pycmdcheck-0.1.1}/tests/test_tool_checks_mocked.py +0 -0
|
@@ -17,9 +17,9 @@ jobs:
|
|
|
17
17
|
name: Lint & type-check
|
|
18
18
|
runs-on: ubuntu-latest
|
|
19
19
|
steps:
|
|
20
|
-
- uses: actions/checkout@
|
|
20
|
+
- uses: actions/checkout@v7
|
|
21
21
|
- name: Install uv
|
|
22
|
-
uses: astral-sh/setup-uv@
|
|
22
|
+
uses: astral-sh/setup-uv@v8.2.0
|
|
23
23
|
with:
|
|
24
24
|
# 3.10 matches [tool.mypy] python_version and installs tomli
|
|
25
25
|
# (a conditional dependency) so mypy can resolve the tomllib fallback.
|
|
@@ -42,9 +42,9 @@ jobs:
|
|
|
42
42
|
matrix:
|
|
43
43
|
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
44
44
|
steps:
|
|
45
|
-
- uses: actions/checkout@
|
|
45
|
+
- uses: actions/checkout@v7
|
|
46
46
|
- name: Install uv
|
|
47
|
-
uses: astral-sh/setup-uv@
|
|
47
|
+
uses: astral-sh/setup-uv@v8.2.0
|
|
48
48
|
with:
|
|
49
49
|
python-version: ${{ matrix.python-version }}
|
|
50
50
|
enable-cache: true
|
|
@@ -13,9 +13,9 @@ jobs:
|
|
|
13
13
|
name: Test & build distributions
|
|
14
14
|
runs-on: ubuntu-latest
|
|
15
15
|
steps:
|
|
16
|
-
- uses: actions/checkout@
|
|
16
|
+
- uses: actions/checkout@v7
|
|
17
17
|
- name: Install uv
|
|
18
|
-
uses: astral-sh/setup-uv@
|
|
18
|
+
uses: astral-sh/setup-uv@v8.2.0
|
|
19
19
|
with:
|
|
20
20
|
python-version: "3.12"
|
|
21
21
|
enable-cache: true
|
|
@@ -26,7 +26,7 @@ jobs:
|
|
|
26
26
|
- name: Build sdist and wheel
|
|
27
27
|
run: uv build
|
|
28
28
|
- name: Upload distributions
|
|
29
|
-
uses: actions/upload-artifact@
|
|
29
|
+
uses: actions/upload-artifact@v7
|
|
30
30
|
with:
|
|
31
31
|
name: dist
|
|
32
32
|
path: dist/
|
|
@@ -44,9 +44,9 @@ jobs:
|
|
|
44
44
|
id-token: write # OIDC: required for PyPI Trusted Publishing (no token)
|
|
45
45
|
steps:
|
|
46
46
|
- name: Download distributions
|
|
47
|
-
uses: actions/download-artifact@
|
|
47
|
+
uses: actions/download-artifact@v8
|
|
48
48
|
with:
|
|
49
49
|
name: dist
|
|
50
50
|
path: dist/
|
|
51
51
|
- name: Publish to PyPI
|
|
52
|
-
uses: pypa/gh-action-pypi-publish@
|
|
52
|
+
uses: pypa/gh-action-pypi-publish@v1.14.0
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to pycmdcheck will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.1] - 2026-06-25
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `--exit-zero` CLI flag: always exit `0` regardless of check results, so the
|
|
13
|
+
exit code reflects whether pycmdcheck ran rather than what it found. Intended
|
|
14
|
+
for CI/automation that parses the results (e.g. `--json`) itself.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Project URLs now point to the actual repository
|
|
19
|
+
(`github.com/coatless-py-pkg/pycmdcheck`); the previously declared
|
|
20
|
+
`pycmdcheck/pycmdcheck` URLs referenced a repository that does not exist (404).
|
|
21
|
+
- Installation instructions use `pip install pycmdcheck` now that the package is
|
|
22
|
+
published on PyPI.
|
|
23
|
+
- Corrected inaccurate docstrings (the `metadata`/`tests`/`structure`/`typing`
|
|
24
|
+
Returns sections, the `check`/`run_checks` built-in-check lists, `get_profile`,
|
|
25
|
+
and `discover_checks`) and the illustrative API doctests that crashed under
|
|
26
|
+
`pytest --doctest-modules`.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- Documentation and docstrings no longer hard-code the built-in check list;
|
|
31
|
+
they reference `pycmdcheck --list`, and a test keeps `ALL_CHECKS` in sync with
|
|
32
|
+
the registered entry points.
|
|
33
|
+
- Updated GitHub Actions to current versions (`checkout` v7, `setup-uv` v8.2.0,
|
|
34
|
+
`upload-artifact` v7, `download-artifact` v8, `gh-action-pypi-publish` v1.14.0).
|
|
35
|
+
|
|
36
|
+
## [0.1.0] - 2026-06-25
|
|
37
|
+
|
|
38
|
+
First release of pycmdcheck on PyPI.
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- Core `check()` function and `pycmdcheck` CLI, with Rich terminal output and
|
|
43
|
+
JSON output for CI integration.
|
|
44
|
+
- Built-in checks: `metadata`, `structure`, `tests`, `linting`, `typing`,
|
|
45
|
+
`imports`, `license`, `docs`, `dependencies`, `build`, `formatting`,
|
|
46
|
+
`version`, `py_typed`, `community`, `ci`, `changelog`, `citation`,
|
|
47
|
+
`python_versions`, `urls`, `doctests`.
|
|
48
|
+
- Profile system — `minimal`, `triage`, `default`, `pyopensci`, `strict` — with
|
|
49
|
+
`--profile` and `--list-profiles`. The `triage` profile runs only static,
|
|
50
|
+
no-install/no-network checks, intended for CI triage of arbitrary
|
|
51
|
+
(un-installed) repositories.
|
|
52
|
+
- Configuration via `[tool.pycmdcheck]` in pyproject.toml, a plugin system via
|
|
53
|
+
entry points for custom checks, and parallel check execution.
|
|
54
|
+
- Support for legacy Poetry projects (`[tool.poetry]` with no PEP 621
|
|
55
|
+
`[project]` table) across the metadata, version, python_versions, and
|
|
56
|
+
dependencies checks.
|
|
57
|
+
- Recognition of PEP 420 namespace packages, single-file modules, and
|
|
58
|
+
native-extension build backends (maturin/scikit-build/setuptools-rust) in the
|
|
59
|
+
`structure` check.
|
|
60
|
+
- `formatting` check auto-detects the configured formatter (ruff vs black) and
|
|
61
|
+
is skipped when none is configured.
|
|
62
|
+
- GitHub Actions: CI (lint + type-check + pytest on 3.10–3.13) and a
|
|
63
|
+
tag-triggered PyPI release via Trusted Publishing (OIDC).
|
|
64
|
+
- Public API: `CheckResult`, `CheckStatus`, `Report`, and the `BaseCheck`
|
|
65
|
+
abstract class for custom checks.
|
|
66
|
+
|
|
67
|
+
The checks are intentionally lenient to avoid false positives on legitimate
|
|
68
|
+
real-world packages (PEP 621 `dynamic` fields, dual-license filenames, RST
|
|
69
|
+
READMEs, community files under `.github/`/`docs/`, dependency extras, and more).
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pycmdcheck
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: Python package quality checker inspired by R CMD check
|
|
5
|
-
Project-URL: Homepage, https://github.com/
|
|
6
|
-
Project-URL: Repository, https://github.com/
|
|
7
|
-
Project-URL: Issues, https://github.com/
|
|
5
|
+
Project-URL: Homepage, https://github.com/coatless-py-pkg/pycmdcheck
|
|
6
|
+
Project-URL: Repository, https://github.com/coatless-py-pkg/pycmdcheck
|
|
7
|
+
Project-URL: Issues, https://github.com/coatless-py-pkg/pycmdcheck/issues
|
|
8
8
|
Author: pycmdcheck contributors
|
|
9
9
|
License-Expression: MIT
|
|
10
10
|
License-File: LICENSE
|
|
@@ -46,40 +46,30 @@ A Python package quality checker inspired by R's `R CMD check`.
|
|
|
46
46
|
|
|
47
47
|
## Installation
|
|
48
48
|
|
|
49
|
-
> **Note:** pycmdcheck is not yet published to PyPI. Install it directly from
|
|
50
|
-
> GitHub for now. Once it is released, `pip install pycmdcheck` will work too.
|
|
51
|
-
|
|
52
49
|
```bash
|
|
53
|
-
pip install
|
|
50
|
+
pip install pycmdcheck
|
|
54
51
|
```
|
|
55
52
|
|
|
56
53
|
Or with uv:
|
|
57
54
|
|
|
58
55
|
```bash
|
|
59
|
-
uv
|
|
56
|
+
uv add pycmdcheck
|
|
60
57
|
```
|
|
61
58
|
|
|
62
|
-
To pin a specific branch, tag, or commit, append `@<ref>` to the URL — for
|
|
63
|
-
example `git+https://github.com/coatless-py-pkg/pycmdcheck@main`.
|
|
64
|
-
|
|
65
59
|
### Optional dependencies
|
|
66
60
|
|
|
67
|
-
pycmdcheck can use external tools for linting and type checking. Request the
|
|
68
|
-
matching extra in the install command. For a GitHub install, the extra goes in
|
|
69
|
-
the PEP 508 `pycmdcheck[extra] @ <url>` form:
|
|
70
|
-
|
|
71
61
|
```bash
|
|
72
62
|
# For mypy type checking
|
|
73
|
-
pip install
|
|
63
|
+
pip install pycmdcheck[typing-mypy]
|
|
74
64
|
|
|
75
65
|
# For pyright type checking
|
|
76
|
-
pip install
|
|
66
|
+
pip install pycmdcheck[typing-pyright]
|
|
77
67
|
|
|
78
68
|
# For ruff linting
|
|
79
|
-
pip install
|
|
69
|
+
pip install pycmdcheck[linting]
|
|
80
70
|
|
|
81
71
|
# All optional dependencies
|
|
82
|
-
pip install
|
|
72
|
+
pip install pycmdcheck[all]
|
|
83
73
|
```
|
|
84
74
|
|
|
85
75
|
## Usage
|
|
@@ -204,9 +194,9 @@ Profiles bundle checks for common use cases:
|
|
|
204
194
|
|---------|-------------|--------|
|
|
205
195
|
| `minimal` | Quick sanity checks | metadata, structure, license |
|
|
206
196
|
| `triage` | Static checks only — no install, external tools, or network (for CI triage of arbitrary repos) | All static checks (excludes tests, imports, dependencies, build, linting, typing, formatting, doctests, urls) |
|
|
207
|
-
| `default` | Standard quality checks | All
|
|
208
|
-
| `pyopensci` | pyOpenSci onboarding | All
|
|
209
|
-
| `strict` | Maximum strictness | All
|
|
197
|
+
| `default` | Standard quality checks | All original core checks |
|
|
198
|
+
| `pyopensci` | pyOpenSci onboarding | All checks with stricter docs settings |
|
|
199
|
+
| `strict` | Maximum strictness | All checks with strict typing |
|
|
210
200
|
|
|
211
201
|
```bash
|
|
212
202
|
# Run pyOpenSci onboarding checks
|
|
@@ -4,40 +4,30 @@ A Python package quality checker inspired by R's `R CMD check`.
|
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
|
-
> **Note:** pycmdcheck is not yet published to PyPI. Install it directly from
|
|
8
|
-
> GitHub for now. Once it is released, `pip install pycmdcheck` will work too.
|
|
9
|
-
|
|
10
7
|
```bash
|
|
11
|
-
pip install
|
|
8
|
+
pip install pycmdcheck
|
|
12
9
|
```
|
|
13
10
|
|
|
14
11
|
Or with uv:
|
|
15
12
|
|
|
16
13
|
```bash
|
|
17
|
-
uv
|
|
14
|
+
uv add pycmdcheck
|
|
18
15
|
```
|
|
19
16
|
|
|
20
|
-
To pin a specific branch, tag, or commit, append `@<ref>` to the URL — for
|
|
21
|
-
example `git+https://github.com/coatless-py-pkg/pycmdcheck@main`.
|
|
22
|
-
|
|
23
17
|
### Optional dependencies
|
|
24
18
|
|
|
25
|
-
pycmdcheck can use external tools for linting and type checking. Request the
|
|
26
|
-
matching extra in the install command. For a GitHub install, the extra goes in
|
|
27
|
-
the PEP 508 `pycmdcheck[extra] @ <url>` form:
|
|
28
|
-
|
|
29
19
|
```bash
|
|
30
20
|
# For mypy type checking
|
|
31
|
-
pip install
|
|
21
|
+
pip install pycmdcheck[typing-mypy]
|
|
32
22
|
|
|
33
23
|
# For pyright type checking
|
|
34
|
-
pip install
|
|
24
|
+
pip install pycmdcheck[typing-pyright]
|
|
35
25
|
|
|
36
26
|
# For ruff linting
|
|
37
|
-
pip install
|
|
27
|
+
pip install pycmdcheck[linting]
|
|
38
28
|
|
|
39
29
|
# All optional dependencies
|
|
40
|
-
pip install
|
|
30
|
+
pip install pycmdcheck[all]
|
|
41
31
|
```
|
|
42
32
|
|
|
43
33
|
## Usage
|
|
@@ -162,9 +152,9 @@ Profiles bundle checks for common use cases:
|
|
|
162
152
|
|---------|-------------|--------|
|
|
163
153
|
| `minimal` | Quick sanity checks | metadata, structure, license |
|
|
164
154
|
| `triage` | Static checks only — no install, external tools, or network (for CI triage of arbitrary repos) | All static checks (excludes tests, imports, dependencies, build, linting, typing, formatting, doctests, urls) |
|
|
165
|
-
| `default` | Standard quality checks | All
|
|
166
|
-
| `pyopensci` | pyOpenSci onboarding | All
|
|
167
|
-
| `strict` | Maximum strictness | All
|
|
155
|
+
| `default` | Standard quality checks | All original core checks |
|
|
156
|
+
| `pyopensci` | pyOpenSci onboarding | All checks with stricter docs settings |
|
|
157
|
+
| `strict` | Maximum strictness | All checks with strict typing |
|
|
168
158
|
|
|
169
159
|
```bash
|
|
170
160
|
# Run pyOpenSci onboarding checks
|
|
@@ -51,6 +51,19 @@ pycmdcheck --fail-on error --fail-on warning
|
|
|
51
51
|
pycmdcheck --fail-on error --fail-on warning --fail-on note
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
+
### `--exit-zero`
|
|
55
|
+
|
|
56
|
+
Always exit `0` regardless of check results — report status only via the output
|
|
57
|
+
(or `--json`). The exit code then reflects whether pycmdcheck *ran*, not what it
|
|
58
|
+
*found*: `0` means it ran successfully, and a non-zero code means pycmdcheck
|
|
59
|
+
itself could not run (e.g. a usage error). This is the recommended mode for CI
|
|
60
|
+
that parses the results itself and should only treat tool failures as job
|
|
61
|
+
failures.
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pycmdcheck --json --exit-zero --profile triage
|
|
65
|
+
```
|
|
66
|
+
|
|
54
67
|
### `--profile`
|
|
55
68
|
|
|
56
69
|
Run a predefined set of checks. Available profiles:
|
|
@@ -59,9 +72,9 @@ Run a predefined set of checks. Available profiles:
|
|
|
59
72
|
|---------|--------|
|
|
60
73
|
| `minimal` | metadata, structure, license |
|
|
61
74
|
| `triage` | static checks only — no install, external tools, or network (for CI triage of arbitrary repos) |
|
|
62
|
-
| `default` | the
|
|
63
|
-
| `pyopensci` | all
|
|
64
|
-
| `strict` | all
|
|
75
|
+
| `default` | the original core checks |
|
|
76
|
+
| `pyopensci` | all checks, with stricter docs settings |
|
|
77
|
+
| `strict` | all checks at maximum strictness |
|
|
65
78
|
|
|
66
79
|
```bash
|
|
67
80
|
# pyOpenSci onboarding checks
|
|
@@ -89,7 +102,7 @@ List all available checks and exit.
|
|
|
89
102
|
pycmdcheck --list
|
|
90
103
|
```
|
|
91
104
|
|
|
92
|
-
Output
|
|
105
|
+
Output:
|
|
93
106
|
```
|
|
94
107
|
Available Checks
|
|
95
108
|
┏━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
@@ -168,7 +181,9 @@ pycmdcheck --no-parallel
|
|
|
168
181
|
|
|
169
182
|
### `-x, --fail-fast`
|
|
170
183
|
|
|
171
|
-
Stop after the first check
|
|
184
|
+
Stop after the first check that returns an ERROR status. This is independent of
|
|
185
|
+
`--fail-on` (which only affects the final exit code) — fail-fast always triggers
|
|
186
|
+
on ERROR.
|
|
172
187
|
|
|
173
188
|
```bash
|
|
174
189
|
pycmdcheck -x
|
|
@@ -203,9 +218,9 @@ pycmdcheck --help
|
|
|
203
218
|
|
|
204
219
|
| Code | Meaning |
|
|
205
220
|
|------|---------|
|
|
206
|
-
| 0 | All checks passed (no status matching `--fail-on`) |
|
|
207
|
-
| 1 | One or more checks failed (status matched `--fail-on`) |
|
|
208
|
-
| 2 | Invalid usage (e.g., an unknown check name passed to `-c`/`--check`) |
|
|
221
|
+
| 0 | All checks passed (no status matching `--fail-on`), or any result with `--exit-zero` |
|
|
222
|
+
| 1 | One or more checks failed (status matched `--fail-on`); suppressed by `--exit-zero` |
|
|
223
|
+
| 2 | Invalid usage (e.g., an unknown check name passed to `-c`/`--check`); **not** suppressed by `--exit-zero` |
|
|
209
224
|
|
|
210
225
|
## Examples
|
|
211
226
|
|
|
@@ -12,7 +12,7 @@ pycmdcheck is configured via the `[tool.pycmdcheck]` section in your `pyproject.
|
|
|
12
12
|
fail_on = ["error"]
|
|
13
13
|
|
|
14
14
|
[tool.pycmdcheck.checks]
|
|
15
|
-
# Enable/disable checks (
|
|
15
|
+
# Enable/disable checks (every check is enabled by default; list only the
|
|
16
16
|
# ones you want to turn off or configure).
|
|
17
17
|
metadata = true
|
|
18
18
|
structure = true
|
|
@@ -4,44 +4,34 @@ title: Getting Started
|
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
|
-
::: {.callout-note}
|
|
8
|
-
pycmdcheck is not yet published to PyPI. Install it directly from GitHub for
|
|
9
|
-
now. Once it is released, `pip install pycmdcheck` will work too.
|
|
10
|
-
:::
|
|
11
|
-
|
|
12
7
|
### Using pip
|
|
13
8
|
|
|
14
9
|
```bash
|
|
15
|
-
pip install
|
|
10
|
+
pip install pycmdcheck
|
|
16
11
|
```
|
|
17
12
|
|
|
18
13
|
### Using uv
|
|
19
14
|
|
|
20
15
|
```bash
|
|
21
|
-
uv
|
|
16
|
+
uv add pycmdcheck
|
|
22
17
|
```
|
|
23
18
|
|
|
24
|
-
To pin a specific branch, tag, or commit, append `@<ref>` to the URL — for
|
|
25
|
-
example `git+https://github.com/coatless-py-pkg/pycmdcheck@main`.
|
|
26
|
-
|
|
27
19
|
### Optional Dependencies
|
|
28
20
|
|
|
29
|
-
pycmdcheck can use external tools for linting and type checking.
|
|
30
|
-
matching extra when installing. For a GitHub install, the extra goes in the
|
|
31
|
-
PEP 508 `pycmdcheck[extra] @ <url>` form:
|
|
21
|
+
pycmdcheck can use external tools for linting and type checking. Install the optional dependencies based on your needs:
|
|
32
22
|
|
|
33
23
|
```bash
|
|
34
24
|
# For mypy type checking
|
|
35
|
-
pip install
|
|
25
|
+
pip install pycmdcheck[typing-mypy]
|
|
36
26
|
|
|
37
27
|
# For pyright type checking
|
|
38
|
-
pip install
|
|
28
|
+
pip install pycmdcheck[typing-pyright]
|
|
39
29
|
|
|
40
30
|
# For ruff linting
|
|
41
|
-
pip install
|
|
31
|
+
pip install pycmdcheck[linting]
|
|
42
32
|
|
|
43
33
|
# All optional dependencies
|
|
44
|
-
pip install
|
|
34
|
+
pip install pycmdcheck[all]
|
|
45
35
|
```
|
|
46
36
|
|
|
47
37
|
## Your First Check
|
|
@@ -54,7 +44,7 @@ Navigate to your Python package directory and run:
|
|
|
54
44
|
pycmdcheck
|
|
55
45
|
```
|
|
56
46
|
|
|
57
|
-
You'll see output like (abbreviated — a default run executes
|
|
47
|
+
You'll see output like (abbreviated — a default run executes every enabled check):
|
|
58
48
|
|
|
59
49
|
```
|
|
60
50
|
Checking package: /path/to/your/package
|
|
@@ -72,7 +62,7 @@ Checking package: /path/to/your/package
|
|
|
72
62
|
│ ✓ │ typing │ No type errors found │
|
|
73
63
|
│ ✓ │ version │ Version 0.1.0 is consistent │
|
|
74
64
|
│ ℹ │ ci │ No CI configuration found │
|
|
75
|
-
│ … │ … │ … (all
|
|
65
|
+
│ … │ … │ … (all enabled checks run) │
|
|
76
66
|
└─────┴─────────────────┴─────────────────────────────┘
|
|
77
67
|
|
|
78
68
|
18 ok | 2 note
|
|
@@ -111,7 +101,8 @@ Each check returns one of five statuses:
|
|
|
111
101
|
|
|
112
102
|
## Built-in Checks
|
|
113
103
|
|
|
114
|
-
pycmdcheck
|
|
104
|
+
pycmdcheck ships the following built-in checks (run `pycmdcheck --list` for the
|
|
105
|
+
authoritative, up-to-date set):
|
|
115
106
|
|
|
116
107
|
| Check | Description |
|
|
117
108
|
|-------|-------------|
|
|
@@ -52,19 +52,14 @@ else:
|
|
|
52
52
|
|
|
53
53
|
## Installation
|
|
54
54
|
|
|
55
|
-
::: {.callout-note}
|
|
56
|
-
pycmdcheck is not yet published to PyPI. Install it directly from GitHub for
|
|
57
|
-
now. Once it is released, `pip install pycmdcheck` will work too.
|
|
58
|
-
:::
|
|
59
|
-
|
|
60
55
|
```bash
|
|
61
|
-
pip install
|
|
56
|
+
pip install pycmdcheck
|
|
62
57
|
```
|
|
63
58
|
|
|
64
59
|
Or with uv:
|
|
65
60
|
|
|
66
61
|
```bash
|
|
67
|
-
uv
|
|
62
|
+
uv add pycmdcheck
|
|
68
63
|
```
|
|
69
64
|
|
|
70
65
|
## Next Steps
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pycmdcheck"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.1"
|
|
8
8
|
description = "Python package quality checker inspired by R CMD check"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -67,9 +67,9 @@ urls = "pycmdcheck.checks.urls:URLsCheck"
|
|
|
67
67
|
doctests = "pycmdcheck.checks.doctests:DoctestsCheck"
|
|
68
68
|
|
|
69
69
|
[project.urls]
|
|
70
|
-
Homepage = "https://github.com/
|
|
71
|
-
Repository = "https://github.com/
|
|
72
|
-
Issues = "https://github.com/
|
|
70
|
+
Homepage = "https://github.com/coatless-py-pkg/pycmdcheck"
|
|
71
|
+
Repository = "https://github.com/coatless-py-pkg/pycmdcheck"
|
|
72
|
+
Issues = "https://github.com/coatless-py-pkg/pycmdcheck/issues"
|
|
73
73
|
|
|
74
74
|
[tool.hatch.build.targets.wheel]
|
|
75
75
|
packages = ["src/pycmdcheck"]
|
|
@@ -66,10 +66,9 @@ def check(
|
|
|
66
66
|
|
|
67
67
|
Args:
|
|
68
68
|
path: Path to the package directory. Defaults to current directory.
|
|
69
|
-
checks:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
structure, tests, typing, version.
|
|
69
|
+
checks: Names of checks to run. If None, runs all enabled checks from
|
|
70
|
+
configuration. The available check names are discovered dynamically
|
|
71
|
+
via entry points; run ``pycmdcheck --list`` to see the current set.
|
|
73
72
|
skip: List of check names to skip, even if enabled in configuration.
|
|
74
73
|
config: Pre-loaded configuration dictionary. If None, configuration
|
|
75
74
|
is loaded from the package's pyproject.toml.
|
|
@@ -84,8 +83,8 @@ def check(
|
|
|
84
83
|
Basic usage - check current directory:
|
|
85
84
|
|
|
86
85
|
>>> from pycmdcheck import check # doctest: +SKIP
|
|
87
|
-
>>> report = check(".")
|
|
88
|
-
>>> report.passed
|
|
86
|
+
>>> report = check(".") # doctest: +SKIP
|
|
87
|
+
>>> report.passed # doctest: +SKIP
|
|
89
88
|
True
|
|
90
89
|
|
|
91
90
|
Run only specific checks:
|
|
@@ -65,8 +65,10 @@ class MetadataCheck(BaseCheck):
|
|
|
65
65
|
Returns:
|
|
66
66
|
A CheckResult with:
|
|
67
67
|
|
|
68
|
-
- OK status if all required and
|
|
69
|
-
|
|
68
|
+
- OK status if all required, recommended, and extended (authors,
|
|
69
|
+
urls, classifiers) fields are present
|
|
70
|
+
- NOTE status if required fields are present but some recommended
|
|
71
|
+
or extended fields are missing
|
|
70
72
|
- WARNING status if using legacy setup.py/setup.cfg
|
|
71
73
|
- ERROR status if pyproject.toml is invalid or missing required fields
|
|
72
74
|
"""
|
|
@@ -73,7 +73,10 @@ class StructureCheck(BaseCheck):
|
|
|
73
73
|
Returns:
|
|
74
74
|
A CheckResult with:
|
|
75
75
|
|
|
76
|
-
- OK status if valid src or
|
|
76
|
+
- OK status if a valid src, flat, single-module, or PEP 420
|
|
77
|
+
namespace layout is found
|
|
78
|
+
- NOTE status if src/ has no Python package but a native-extension
|
|
79
|
+
build backend (maturin/scikit-build/setuptools-rust) is declared
|
|
77
80
|
- WARNING status if packages missing ``__init__.py``
|
|
78
81
|
- ERROR status if no package or module found
|
|
79
82
|
"""
|
|
@@ -70,7 +70,8 @@ class TestsCheck(BaseCheck):
|
|
|
70
70
|
|
|
71
71
|
- OK status if all tests pass
|
|
72
72
|
- WARNING status if no tests found
|
|
73
|
-
- ERROR status if tests fail
|
|
73
|
+
- ERROR status if tests fail, time out, fail to launch, or an
|
|
74
|
+
unknown runner is configured
|
|
74
75
|
- SKIPPED status if the test runner is not installed
|
|
75
76
|
"""
|
|
76
77
|
runner = config.get("runner", "pytest")
|
|
@@ -74,6 +74,8 @@ class TypingCheck(BaseCheck):
|
|
|
74
74
|
A CheckResult with:
|
|
75
75
|
|
|
76
76
|
- OK status if no type errors found
|
|
77
|
+
- WARNING status if mypy cannot analyze the package due to a
|
|
78
|
+
configuration/layout error (mypy exit code 2)
|
|
77
79
|
- ERROR status if type errors found or checker fails
|
|
78
80
|
- SKIPPED status if the type checker is not installed
|
|
79
81
|
"""
|
|
@@ -40,6 +40,16 @@ console = Console()
|
|
|
40
40
|
default=["error"],
|
|
41
41
|
help="Exit with non-zero code on these statuses. Default: error",
|
|
42
42
|
)
|
|
43
|
+
@click.option(
|
|
44
|
+
"--exit-zero",
|
|
45
|
+
"exit_zero",
|
|
46
|
+
is_flag=True,
|
|
47
|
+
help=(
|
|
48
|
+
"Always exit 0 regardless of check results (report status via output "
|
|
49
|
+
"or --json only). The exit code then reflects whether pycmdcheck ran, "
|
|
50
|
+
"not what it found — useful for CI that parses results itself."
|
|
51
|
+
),
|
|
52
|
+
)
|
|
43
53
|
@click.option(
|
|
44
54
|
"--list",
|
|
45
55
|
"list_checks",
|
|
@@ -89,6 +99,7 @@ def main(
|
|
|
89
99
|
check: tuple[str, ...],
|
|
90
100
|
skip: tuple[str, ...],
|
|
91
101
|
fail_on: tuple[str, ...],
|
|
102
|
+
exit_zero: bool,
|
|
92
103
|
list_checks: bool,
|
|
93
104
|
verbose: bool,
|
|
94
105
|
json_output: bool,
|
|
@@ -197,8 +208,10 @@ def main(
|
|
|
197
208
|
else:
|
|
198
209
|
_output_rich(report, verbose)
|
|
199
210
|
|
|
200
|
-
# Determine exit code
|
|
201
|
-
|
|
211
|
+
# Determine exit code. With --exit-zero, findings never change the exit
|
|
212
|
+
# code (the caller is expected to read the results), so a non-zero exit
|
|
213
|
+
# then reflects only that pycmdcheck itself could not run.
|
|
214
|
+
if report.failed_on(list(fail_on)) and not exit_zero:
|
|
202
215
|
sys.exit(1)
|
|
203
216
|
|
|
204
217
|
|
|
@@ -34,8 +34,8 @@ def discover_checks() -> dict[str, type["Check"]]:
|
|
|
34
34
|
package's pyproject.toml, and third-party packages can register
|
|
35
35
|
additional checks.
|
|
36
36
|
|
|
37
|
-
If a check fails to load (e.g., due to an import error), a
|
|
38
|
-
|
|
37
|
+
If a check fails to load (e.g., due to an import error), a warning is
|
|
38
|
+
logged (via ``logger.warning``) but discovery continues with other checks.
|
|
39
39
|
|
|
40
40
|
Returns:
|
|
41
41
|
A dictionary mapping check names (strings) to check classes.
|
|
@@ -43,20 +43,17 @@ def discover_checks() -> dict[str, type["Check"]]:
|
|
|
43
43
|
pycmdcheck.checks.base.
|
|
44
44
|
|
|
45
45
|
Examples:
|
|
46
|
-
Discover all available checks:
|
|
46
|
+
Discover all available checks (returns a name -> class mapping):
|
|
47
47
|
|
|
48
48
|
>>> checks = discover_checks()
|
|
49
|
-
>>>
|
|
50
|
-
True
|
|
51
|
-
>>> "tests" in checks
|
|
49
|
+
>>> isinstance(checks, dict)
|
|
52
50
|
True
|
|
53
51
|
|
|
54
|
-
Get a specific check class
|
|
52
|
+
Get a specific check class (requires the package to be installed so its
|
|
53
|
+
entry points are registered):
|
|
55
54
|
|
|
56
|
-
>>>
|
|
57
|
-
>>> MetadataCheck
|
|
58
|
-
>>> instance = MetadataCheck()
|
|
59
|
-
>>> instance.name
|
|
55
|
+
>>> MetadataCheck = discover_checks()["metadata"] # doctest: +SKIP
|
|
56
|
+
>>> MetadataCheck().name # doctest: +SKIP
|
|
60
57
|
'metadata'
|
|
61
58
|
"""
|
|
62
59
|
checks: dict[str, type[Check]] = {}
|
|
@@ -100,10 +97,7 @@ def list_available_checks() -> list[tuple[str, str]]:
|
|
|
100
97
|
List all checks for display:
|
|
101
98
|
|
|
102
99
|
>>> checks = list_available_checks()
|
|
103
|
-
>>>
|
|
104
|
-
True
|
|
105
|
-
>>> name, description = checks[0]
|
|
106
|
-
>>> isinstance(name, str) and isinstance(description, str)
|
|
100
|
+
>>> isinstance(checks, list)
|
|
107
101
|
True
|
|
108
102
|
|
|
109
103
|
Display in CLI:
|