pyossmtool 0.0.1__tar.gz → 0.0.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.
- pyossmtool-0.0.2/PKG-INFO +351 -0
- pyossmtool-0.0.2/README.md +322 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/pyproject.toml +1 -1
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/__init__.py +1 -1
- pyossmtool-0.0.2/src/pyossmtool/bundle/suites/all.yaml +51 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/cli.py +25 -11
- pyossmtool-0.0.2/src/pyossmtool/error_formatters.py +218 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/models.py +26 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/reporter.py +1 -1
- pyossmtool-0.0.2/src/pyossmtool.egg-info/PKG-INFO +351 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool.egg-info/SOURCES.txt +3 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/tests/test_check_modes.py +7 -0
- pyossmtool-0.0.2/tests/test_error_formatters.py +117 -0
- pyossmtool-0.0.1/PKG-INFO +0 -94
- pyossmtool-0.0.1/README.md +0 -65
- pyossmtool-0.0.1/src/pyossmtool.egg-info/PKG-INFO +0 -94
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/LICENSE +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/setup.cfg +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/bandit.scan.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/codespell.spelling.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/deadcode.scan.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/gate.acronym-allowlist.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/gate.folder-breadth.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/gate.module-private-vars.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/gate.module-size.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/gitleaks.secrets.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/hadolint.dockerfile.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/jscpd.duplication.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/markdownlint.check.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/mdformat.apply.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/mdformat.format.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/mutmut.run.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/pydeps.cycles.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/pytest.coverage.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/pytest.test.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/radon.cc.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/radon.mi.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/ruff.format.apply.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/ruff.format.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/ruff.lint.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/ruff.unused.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/semgrep.scan.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/shellcheck.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/shfmt.apply.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/shfmt.format.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/sourcery.review.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/ty.check.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/vulture.scan.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/yamlfmt.apply.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/yamlfmt.format.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/yamllint.check.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/bandit.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/codespell.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/deadcode.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/gitleaks.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/hadolint.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/jscpd.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/markdownlint.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/mdformat.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/mutmut.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/pydeps.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/pytest.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/radon.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/ruff.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/script.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/semgrep.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/shellcheck.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/shfmt.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/sourcery.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/ty.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/vulture.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/yamlfmt.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/yamllint.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/allowlists/acronyms.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/allowlists/folder-breadth.txt +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/allowlists/module-private-vars.txt +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/allowlists/module-size.txt +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/configs/bandit.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/configs/gates/acronym-allowlist.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/configs/gates/folder-breadth.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/configs/gates/module-private-vars.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/configs/gates/module-size.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/configs/markdownlint.json +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/configs/ruff.toml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/configs/ty.toml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/configs/yamlfmt.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/configs/yamllint.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/gates/README.md +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/gates/acronym-allowlist.sh +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/gates/folder-breadth.sh +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/gates/lib.sh +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/gates/module-private-vars.sh +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/gates/module-size.sh +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/semgrep/python-quality.yml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/suites/demo.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/suites/extended.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/suites/format.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/suites/formatting.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/suites/policy.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/suites/python-quality.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/suites/reslab-parity.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/suites/standard.yaml +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/config_resolver.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/discovery.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/gate_config.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/gates.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/ignore.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/ignore_materialize.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/installer.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/parsers/__init__.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/parsers/analysis.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/parsers/base.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/parsers/common.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/parsers/format_text.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/parsers/gates.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/parsers/patterns.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/parsers/prose.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/parsers/ruff.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/parsers/shell.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/policy/__init__.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/policy/acronym_allowlist.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/policy/folder_breadth.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/registry.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/resolver.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/runner.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/runner_script.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/target_expand.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool.egg-info/dependency_links.txt +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool.egg-info/entry_points.txt +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool.egg-info/requires.txt +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool.egg-info/top_level.txt +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/tests/test_cli.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/tests/test_config_and_targets.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/tests/test_discovery.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/tests/test_gate_config.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/tests/test_ignore.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/tests/test_npm_install.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/tests/test_packaging.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/tests/test_parser_registry.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/tests/test_script_gates.py +0 -0
- {pyossmtool-0.0.1 → pyossmtool-0.0.2}/tests/test_wheel_install.py +0 -0
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyossmtool
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Summary: Quality-gate orchestrator for AI-assisted development
|
|
5
|
+
Author-email: Vishal Kumar Mishra <vishal.k.mishra2@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Changelog, https://github.com/inquilabee/pyossmtool/blob/main/CHANGELOG.md
|
|
8
|
+
Project-URL: Homepage, https://github.com/inquilabee/pyossmtool
|
|
9
|
+
Project-URL: Issues, https://github.com/inquilabee/pyossmtool/issues
|
|
10
|
+
Project-URL: Repository, https://github.com/inquilabee/pyossmtool
|
|
11
|
+
Keywords: quality,lint,format,pre-commit,python,static-analysis
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
21
|
+
Requires-Python: <3.14,>=3.11
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: pydantic>=2.0
|
|
25
|
+
Requires-Dist: pathspec>=0.12
|
|
26
|
+
Requires-Dist: pyyaml>=6.0
|
|
27
|
+
Requires-Dist: typer>=0.12
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
# pyossmtool
|
|
31
|
+
|
|
32
|
+
Portable quality-gate orchestrator for Python-first repositories. Inspired by Trunk and pre-commit: opinionated defaults, little required configuration, silent on success, structured failure reports for humans and AI agents.
|
|
33
|
+
|
|
34
|
+
## Why use it
|
|
35
|
+
|
|
36
|
+
- One config file and a shared CLI for lint, type-check, format, security, and custom gates
|
|
37
|
+
- `check` reports problems without rewriting files; `format` applies formatters
|
|
38
|
+
- Tools discover the right files from their own globs under your scan root
|
|
39
|
+
- `.gitignore` is always respected
|
|
40
|
+
- Failures produce JSON reports under `reports/failures/` for humans and AI agents
|
|
41
|
+
|
|
42
|
+
## Install
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install pyossmtool
|
|
46
|
+
# or
|
|
47
|
+
uv add --dev pyossmtool
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Requires Python 3.11–3.13.
|
|
51
|
+
|
|
52
|
+
## Quick start
|
|
53
|
+
|
|
54
|
+
Create `pyossmtool.yaml` in your repo (the `all` suite includes every bundled check):
|
|
55
|
+
|
|
56
|
+
```yaml
|
|
57
|
+
suite: all
|
|
58
|
+
env: auto
|
|
59
|
+
target: .
|
|
60
|
+
configs:
|
|
61
|
+
mode: auto
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Install the binaries for that suite, then run:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pyossmtool install --suite all
|
|
68
|
+
pyossmtool format --suite all # mode: format (writes)
|
|
69
|
+
pyossmtool check --suite all # mode: check (report-only)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`check` and `format` each run only their mode, so use both when you want full coverage from `all`.
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
pyossmtool list suites
|
|
76
|
+
pyossmtool list tools
|
|
77
|
+
pyossmtool list checks
|
|
78
|
+
pyossmtool check --check ruff.lint --target .
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Copy [`pyossmtool.yaml.example`](pyossmtool.yaml.example) for a fuller annotated config.
|
|
82
|
+
|
|
83
|
+
## Suites
|
|
84
|
+
|
|
85
|
+
The package ships the **full catalog** of tools and checks. A **suite** is a named subset — or `all` for everything.
|
|
86
|
+
|
|
87
|
+
| Suite | Role |
|
|
88
|
+
|-------|------|
|
|
89
|
+
| `all` | Every bundled check |
|
|
90
|
+
| `python-quality` | Core Python lint / format-check / types |
|
|
91
|
+
| `formatting` | Format **check** (report-only) across languages |
|
|
92
|
+
| `format` | Format **apply** only |
|
|
93
|
+
| `standard` | Broader portable quality set |
|
|
94
|
+
| `extended` | Slower / optional extras on top of standard |
|
|
95
|
+
| `policy` | Bundled script gates |
|
|
96
|
+
| `demo` | Sample-files fixture suite for development |
|
|
97
|
+
|
|
98
|
+
### Suite examples
|
|
99
|
+
|
|
100
|
+
**Full dogfood (every check):**
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
suite: all
|
|
104
|
+
env: auto
|
|
105
|
+
target: .
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
pyossmtool install --suite all
|
|
110
|
+
pyossmtool format --suite all
|
|
111
|
+
pyossmtool check --suite all
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Python-focused CI gate:**
|
|
115
|
+
|
|
116
|
+
```yaml
|
|
117
|
+
suite: python-quality
|
|
118
|
+
env: auto
|
|
119
|
+
target: .
|
|
120
|
+
error-format: compact
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
pyossmtool install --suite python-quality
|
|
125
|
+
pyossmtool check --suite python-quality
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Apply formatters only (writes files):**
|
|
129
|
+
|
|
130
|
+
```yaml
|
|
131
|
+
suite: format
|
|
132
|
+
env: auto
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
pyossmtool install --suite format
|
|
137
|
+
pyossmtool format --suite format
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**Report-only formatting drift (no writes):**
|
|
141
|
+
|
|
142
|
+
```yaml
|
|
143
|
+
suite: formatting
|
|
144
|
+
error-format: text
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
pyossmtool check --suite formatting
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**Broader portable set, GitHub Actions annotations:**
|
|
152
|
+
|
|
153
|
+
```yaml
|
|
154
|
+
suite: standard
|
|
155
|
+
error-format: github
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
pyossmtool check --suite standard
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Override the suite for one run without editing the file:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
pyossmtool check --suite extended
|
|
166
|
+
pyossmtool check --suite policy
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Success and failure output
|
|
170
|
+
|
|
171
|
+
Success is silent: no stdout, exit code `0`.
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
$ pyossmtool check --suite python-quality
|
|
175
|
+
$ echo $?
|
|
176
|
+
0
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
On failure, pyossmtool always writes `reports/failures/<check>-<timestamp>/report.json`, then prints that report to stderr using the configured **error formatter** (default: `json`). Exit code `1`. Setup problems print `SETUP …` and exit `2`.
|
|
180
|
+
|
|
181
|
+
### Error formatters
|
|
182
|
+
|
|
183
|
+
Set `error-format` in `pyossmtool.yaml`. Built-ins (plug in by name):
|
|
184
|
+
|
|
185
|
+
| Name | Use when |
|
|
186
|
+
|------|----------|
|
|
187
|
+
| `json` | Default — machines / AI agents (pretty JSON on stderr) |
|
|
188
|
+
| `log` | Timestamped log lines for aggregators |
|
|
189
|
+
| `text` | Short human summary in the terminal |
|
|
190
|
+
| `compact` | Editor-friendly `file:line:` one-liners |
|
|
191
|
+
| `github` | GitHub Actions workflow annotations |
|
|
192
|
+
|
|
193
|
+
On-disk `report.json` is **always** JSON regardless of `error-format`.
|
|
194
|
+
|
|
195
|
+
#### `json` (default)
|
|
196
|
+
|
|
197
|
+
```yaml
|
|
198
|
+
# error-format: json # or omit — same effect
|
|
199
|
+
suite: python-quality
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
{
|
|
204
|
+
"schema_version": "1.0",
|
|
205
|
+
"check_id": "ruff.lint",
|
|
206
|
+
"tool_id": "ruff",
|
|
207
|
+
"status": "failed",
|
|
208
|
+
"summary": { "finding_count": 1, "by_severity": { "error": 1 } },
|
|
209
|
+
"findings": [
|
|
210
|
+
{
|
|
211
|
+
"rule_id": "E501",
|
|
212
|
+
"severity": "error",
|
|
213
|
+
"message": "Line too long (121 > 120)",
|
|
214
|
+
"location": { "file": "src/app.py", "line": 42 }
|
|
215
|
+
}
|
|
216
|
+
],
|
|
217
|
+
"report_path": "reports/failures/ruff.lint-20260716T163000Z/report.json"
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
#### `log`
|
|
222
|
+
|
|
223
|
+
```yaml
|
|
224
|
+
suite: python-quality
|
|
225
|
+
error-format: log
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
```text
|
|
229
|
+
FAIL ruff.lint findings=1 -> reports/failures/ruff.lint-…/report.json
|
|
230
|
+
2026-07-16T12:00:00+00:00 [error] ruff.lint/E501 src/app.py:42: Line too long (121 > 120)
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
#### `text`
|
|
234
|
+
|
|
235
|
+
```yaml
|
|
236
|
+
suite: formatting
|
|
237
|
+
error-format: text
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
```text
|
|
241
|
+
FAIL ruff.lint -> reports/failures/ruff.lint-…/report.json
|
|
242
|
+
findings: 1
|
|
243
|
+
- [error] E501: Line too long (121 > 120) (src/app.py:42)
|
|
244
|
+
suggested:
|
|
245
|
+
ruff check --fix .
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
#### `compact`
|
|
249
|
+
|
|
250
|
+
```yaml
|
|
251
|
+
suite: standard
|
|
252
|
+
error-format: compact
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
```text
|
|
256
|
+
src/app.py:42: error: E501 Line too long (121 > 120)
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
#### `github`
|
|
260
|
+
|
|
261
|
+
```yaml
|
|
262
|
+
suite: standard
|
|
263
|
+
error-format: github
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
```text
|
|
267
|
+
::error file=src/app.py,title=ruff.lint/E501,line=42::Line too long (121 > 120)
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Severity maps to `::error`, `::warning`, or `::notice` so annotations show up on the PR file view in GitHub Actions.
|
|
271
|
+
|
|
272
|
+
### Custom formatters
|
|
273
|
+
|
|
274
|
+
Define named formatters under `error-formatters`, then select one with `error-format`:
|
|
275
|
+
|
|
276
|
+
```yaml
|
|
277
|
+
suite: all
|
|
278
|
+
error-format: short
|
|
279
|
+
error-formatters:
|
|
280
|
+
short:
|
|
281
|
+
kind: finding_line
|
|
282
|
+
template: "{severity}\t{rule_id}\t{file}:{line}\t{message}"
|
|
283
|
+
myjq:
|
|
284
|
+
kind: jq
|
|
285
|
+
program: >
|
|
286
|
+
.findings[] | "[\(.severity)] \(.rule_id) \(.location.file // "-"):\(.location.line // "?") \(.message)"
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
`finding_line` placeholders: `severity`, `rule_id`, `message`, `file`, `line`, `check_id`, `report_path`.
|
|
290
|
+
`jq` requires `jq` on `PATH`.
|
|
291
|
+
|
|
292
|
+
### Combined examples
|
|
293
|
+
|
|
294
|
+
**Local Python repo, readable failures:**
|
|
295
|
+
|
|
296
|
+
```yaml
|
|
297
|
+
suite: python-quality
|
|
298
|
+
env: auto
|
|
299
|
+
target: .
|
|
300
|
+
error-format: text
|
|
301
|
+
configs:
|
|
302
|
+
mode: auto
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
**CI on GitHub:**
|
|
306
|
+
|
|
307
|
+
```yaml
|
|
308
|
+
suite: standard
|
|
309
|
+
env: auto
|
|
310
|
+
error-format: github
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**Everything + compact lines:**
|
|
314
|
+
|
|
315
|
+
```yaml
|
|
316
|
+
suite: all
|
|
317
|
+
error-format: compact
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Schema
|
|
321
|
+
|
|
322
|
+
Print the JSON Schema for on-disk `FailureReport` files:
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
pyossmtool schema
|
|
326
|
+
pyossmtool schema > failure-report.schema.json
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
## Targeting
|
|
330
|
+
|
|
331
|
+
- Default scan root is `.` (override with `target:` in `pyossmtool.yaml` or in a suite)
|
|
332
|
+
- Each tool declares which files it cares about (for example `**/*.py`)
|
|
333
|
+
- `.gitignore` is always applied; you can add extra ignore profiles or paths in config
|
|
334
|
+
|
|
335
|
+
## Project-local gates
|
|
336
|
+
|
|
337
|
+
Scaffold a custom script gate:
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
pyossmtool gate init module-size --description "Cap module line counts"
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
Then enable the check in `pyossmtool.yaml` (see the example file for the steps).
|
|
344
|
+
|
|
345
|
+
## Contributing
|
|
346
|
+
|
|
347
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for local development, adding tools/checks, and release notes.
|
|
348
|
+
|
|
349
|
+
## License
|
|
350
|
+
|
|
351
|
+
MIT
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# pyossmtool
|
|
2
|
+
|
|
3
|
+
Portable quality-gate orchestrator for Python-first repositories. Inspired by Trunk and pre-commit: opinionated defaults, little required configuration, silent on success, structured failure reports for humans and AI agents.
|
|
4
|
+
|
|
5
|
+
## Why use it
|
|
6
|
+
|
|
7
|
+
- One config file and a shared CLI for lint, type-check, format, security, and custom gates
|
|
8
|
+
- `check` reports problems without rewriting files; `format` applies formatters
|
|
9
|
+
- Tools discover the right files from their own globs under your scan root
|
|
10
|
+
- `.gitignore` is always respected
|
|
11
|
+
- Failures produce JSON reports under `reports/failures/` for humans and AI agents
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install pyossmtool
|
|
17
|
+
# or
|
|
18
|
+
uv add --dev pyossmtool
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Requires Python 3.11–3.13.
|
|
22
|
+
|
|
23
|
+
## Quick start
|
|
24
|
+
|
|
25
|
+
Create `pyossmtool.yaml` in your repo (the `all` suite includes every bundled check):
|
|
26
|
+
|
|
27
|
+
```yaml
|
|
28
|
+
suite: all
|
|
29
|
+
env: auto
|
|
30
|
+
target: .
|
|
31
|
+
configs:
|
|
32
|
+
mode: auto
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Install the binaries for that suite, then run:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pyossmtool install --suite all
|
|
39
|
+
pyossmtool format --suite all # mode: format (writes)
|
|
40
|
+
pyossmtool check --suite all # mode: check (report-only)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`check` and `format` each run only their mode, so use both when you want full coverage from `all`.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pyossmtool list suites
|
|
47
|
+
pyossmtool list tools
|
|
48
|
+
pyossmtool list checks
|
|
49
|
+
pyossmtool check --check ruff.lint --target .
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Copy [`pyossmtool.yaml.example`](pyossmtool.yaml.example) for a fuller annotated config.
|
|
53
|
+
|
|
54
|
+
## Suites
|
|
55
|
+
|
|
56
|
+
The package ships the **full catalog** of tools and checks. A **suite** is a named subset — or `all` for everything.
|
|
57
|
+
|
|
58
|
+
| Suite | Role |
|
|
59
|
+
|-------|------|
|
|
60
|
+
| `all` | Every bundled check |
|
|
61
|
+
| `python-quality` | Core Python lint / format-check / types |
|
|
62
|
+
| `formatting` | Format **check** (report-only) across languages |
|
|
63
|
+
| `format` | Format **apply** only |
|
|
64
|
+
| `standard` | Broader portable quality set |
|
|
65
|
+
| `extended` | Slower / optional extras on top of standard |
|
|
66
|
+
| `policy` | Bundled script gates |
|
|
67
|
+
| `demo` | Sample-files fixture suite for development |
|
|
68
|
+
|
|
69
|
+
### Suite examples
|
|
70
|
+
|
|
71
|
+
**Full dogfood (every check):**
|
|
72
|
+
|
|
73
|
+
```yaml
|
|
74
|
+
suite: all
|
|
75
|
+
env: auto
|
|
76
|
+
target: .
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
pyossmtool install --suite all
|
|
81
|
+
pyossmtool format --suite all
|
|
82
|
+
pyossmtool check --suite all
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Python-focused CI gate:**
|
|
86
|
+
|
|
87
|
+
```yaml
|
|
88
|
+
suite: python-quality
|
|
89
|
+
env: auto
|
|
90
|
+
target: .
|
|
91
|
+
error-format: compact
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
pyossmtool install --suite python-quality
|
|
96
|
+
pyossmtool check --suite python-quality
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**Apply formatters only (writes files):**
|
|
100
|
+
|
|
101
|
+
```yaml
|
|
102
|
+
suite: format
|
|
103
|
+
env: auto
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
pyossmtool install --suite format
|
|
108
|
+
pyossmtool format --suite format
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Report-only formatting drift (no writes):**
|
|
112
|
+
|
|
113
|
+
```yaml
|
|
114
|
+
suite: formatting
|
|
115
|
+
error-format: text
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
pyossmtool check --suite formatting
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Broader portable set, GitHub Actions annotations:**
|
|
123
|
+
|
|
124
|
+
```yaml
|
|
125
|
+
suite: standard
|
|
126
|
+
error-format: github
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
pyossmtool check --suite standard
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Override the suite for one run without editing the file:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
pyossmtool check --suite extended
|
|
137
|
+
pyossmtool check --suite policy
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Success and failure output
|
|
141
|
+
|
|
142
|
+
Success is silent: no stdout, exit code `0`.
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
$ pyossmtool check --suite python-quality
|
|
146
|
+
$ echo $?
|
|
147
|
+
0
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
On failure, pyossmtool always writes `reports/failures/<check>-<timestamp>/report.json`, then prints that report to stderr using the configured **error formatter** (default: `json`). Exit code `1`. Setup problems print `SETUP …` and exit `2`.
|
|
151
|
+
|
|
152
|
+
### Error formatters
|
|
153
|
+
|
|
154
|
+
Set `error-format` in `pyossmtool.yaml`. Built-ins (plug in by name):
|
|
155
|
+
|
|
156
|
+
| Name | Use when |
|
|
157
|
+
|------|----------|
|
|
158
|
+
| `json` | Default — machines / AI agents (pretty JSON on stderr) |
|
|
159
|
+
| `log` | Timestamped log lines for aggregators |
|
|
160
|
+
| `text` | Short human summary in the terminal |
|
|
161
|
+
| `compact` | Editor-friendly `file:line:` one-liners |
|
|
162
|
+
| `github` | GitHub Actions workflow annotations |
|
|
163
|
+
|
|
164
|
+
On-disk `report.json` is **always** JSON regardless of `error-format`.
|
|
165
|
+
|
|
166
|
+
#### `json` (default)
|
|
167
|
+
|
|
168
|
+
```yaml
|
|
169
|
+
# error-format: json # or omit — same effect
|
|
170
|
+
suite: python-quality
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
```json
|
|
174
|
+
{
|
|
175
|
+
"schema_version": "1.0",
|
|
176
|
+
"check_id": "ruff.lint",
|
|
177
|
+
"tool_id": "ruff",
|
|
178
|
+
"status": "failed",
|
|
179
|
+
"summary": { "finding_count": 1, "by_severity": { "error": 1 } },
|
|
180
|
+
"findings": [
|
|
181
|
+
{
|
|
182
|
+
"rule_id": "E501",
|
|
183
|
+
"severity": "error",
|
|
184
|
+
"message": "Line too long (121 > 120)",
|
|
185
|
+
"location": { "file": "src/app.py", "line": 42 }
|
|
186
|
+
}
|
|
187
|
+
],
|
|
188
|
+
"report_path": "reports/failures/ruff.lint-20260716T163000Z/report.json"
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
#### `log`
|
|
193
|
+
|
|
194
|
+
```yaml
|
|
195
|
+
suite: python-quality
|
|
196
|
+
error-format: log
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
```text
|
|
200
|
+
FAIL ruff.lint findings=1 -> reports/failures/ruff.lint-…/report.json
|
|
201
|
+
2026-07-16T12:00:00+00:00 [error] ruff.lint/E501 src/app.py:42: Line too long (121 > 120)
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
#### `text`
|
|
205
|
+
|
|
206
|
+
```yaml
|
|
207
|
+
suite: formatting
|
|
208
|
+
error-format: text
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
```text
|
|
212
|
+
FAIL ruff.lint -> reports/failures/ruff.lint-…/report.json
|
|
213
|
+
findings: 1
|
|
214
|
+
- [error] E501: Line too long (121 > 120) (src/app.py:42)
|
|
215
|
+
suggested:
|
|
216
|
+
ruff check --fix .
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
#### `compact`
|
|
220
|
+
|
|
221
|
+
```yaml
|
|
222
|
+
suite: standard
|
|
223
|
+
error-format: compact
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
```text
|
|
227
|
+
src/app.py:42: error: E501 Line too long (121 > 120)
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
#### `github`
|
|
231
|
+
|
|
232
|
+
```yaml
|
|
233
|
+
suite: standard
|
|
234
|
+
error-format: github
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
```text
|
|
238
|
+
::error file=src/app.py,title=ruff.lint/E501,line=42::Line too long (121 > 120)
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Severity maps to `::error`, `::warning`, or `::notice` so annotations show up on the PR file view in GitHub Actions.
|
|
242
|
+
|
|
243
|
+
### Custom formatters
|
|
244
|
+
|
|
245
|
+
Define named formatters under `error-formatters`, then select one with `error-format`:
|
|
246
|
+
|
|
247
|
+
```yaml
|
|
248
|
+
suite: all
|
|
249
|
+
error-format: short
|
|
250
|
+
error-formatters:
|
|
251
|
+
short:
|
|
252
|
+
kind: finding_line
|
|
253
|
+
template: "{severity}\t{rule_id}\t{file}:{line}\t{message}"
|
|
254
|
+
myjq:
|
|
255
|
+
kind: jq
|
|
256
|
+
program: >
|
|
257
|
+
.findings[] | "[\(.severity)] \(.rule_id) \(.location.file // "-"):\(.location.line // "?") \(.message)"
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
`finding_line` placeholders: `severity`, `rule_id`, `message`, `file`, `line`, `check_id`, `report_path`.
|
|
261
|
+
`jq` requires `jq` on `PATH`.
|
|
262
|
+
|
|
263
|
+
### Combined examples
|
|
264
|
+
|
|
265
|
+
**Local Python repo, readable failures:**
|
|
266
|
+
|
|
267
|
+
```yaml
|
|
268
|
+
suite: python-quality
|
|
269
|
+
env: auto
|
|
270
|
+
target: .
|
|
271
|
+
error-format: text
|
|
272
|
+
configs:
|
|
273
|
+
mode: auto
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
**CI on GitHub:**
|
|
277
|
+
|
|
278
|
+
```yaml
|
|
279
|
+
suite: standard
|
|
280
|
+
env: auto
|
|
281
|
+
error-format: github
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
**Everything + compact lines:**
|
|
285
|
+
|
|
286
|
+
```yaml
|
|
287
|
+
suite: all
|
|
288
|
+
error-format: compact
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Schema
|
|
292
|
+
|
|
293
|
+
Print the JSON Schema for on-disk `FailureReport` files:
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
pyossmtool schema
|
|
297
|
+
pyossmtool schema > failure-report.schema.json
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## Targeting
|
|
301
|
+
|
|
302
|
+
- Default scan root is `.` (override with `target:` in `pyossmtool.yaml` or in a suite)
|
|
303
|
+
- Each tool declares which files it cares about (for example `**/*.py`)
|
|
304
|
+
- `.gitignore` is always applied; you can add extra ignore profiles or paths in config
|
|
305
|
+
|
|
306
|
+
## Project-local gates
|
|
307
|
+
|
|
308
|
+
Scaffold a custom script gate:
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
pyossmtool gate init module-size --description "Cap module line counts"
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Then enable the check in `pyossmtool.yaml` (see the example file for the steps).
|
|
315
|
+
|
|
316
|
+
## Contributing
|
|
317
|
+
|
|
318
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for local development, adding tools/checks, and release notes.
|
|
319
|
+
|
|
320
|
+
## License
|
|
321
|
+
|
|
322
|
+
MIT
|