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.
Files changed (141) hide show
  1. pyossmtool-0.0.2/PKG-INFO +351 -0
  2. pyossmtool-0.0.2/README.md +322 -0
  3. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/pyproject.toml +1 -1
  4. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/__init__.py +1 -1
  5. pyossmtool-0.0.2/src/pyossmtool/bundle/suites/all.yaml +51 -0
  6. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/cli.py +25 -11
  7. pyossmtool-0.0.2/src/pyossmtool/error_formatters.py +218 -0
  8. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/models.py +26 -0
  9. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/reporter.py +1 -1
  10. pyossmtool-0.0.2/src/pyossmtool.egg-info/PKG-INFO +351 -0
  11. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool.egg-info/SOURCES.txt +3 -0
  12. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/tests/test_check_modes.py +7 -0
  13. pyossmtool-0.0.2/tests/test_error_formatters.py +117 -0
  14. pyossmtool-0.0.1/PKG-INFO +0 -94
  15. pyossmtool-0.0.1/README.md +0 -65
  16. pyossmtool-0.0.1/src/pyossmtool.egg-info/PKG-INFO +0 -94
  17. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/LICENSE +0 -0
  18. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/setup.cfg +0 -0
  19. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/bandit.scan.yaml +0 -0
  20. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/codespell.spelling.yaml +0 -0
  21. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/deadcode.scan.yaml +0 -0
  22. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/gate.acronym-allowlist.yaml +0 -0
  23. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/gate.folder-breadth.yaml +0 -0
  24. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/gate.module-private-vars.yaml +0 -0
  25. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/gate.module-size.yaml +0 -0
  26. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/gitleaks.secrets.yaml +0 -0
  27. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/hadolint.dockerfile.yaml +0 -0
  28. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/jscpd.duplication.yaml +0 -0
  29. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/markdownlint.check.yaml +0 -0
  30. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/mdformat.apply.yaml +0 -0
  31. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/mdformat.format.yaml +0 -0
  32. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/mutmut.run.yaml +0 -0
  33. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/pydeps.cycles.yaml +0 -0
  34. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/pytest.coverage.yaml +0 -0
  35. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/pytest.test.yaml +0 -0
  36. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/radon.cc.yaml +0 -0
  37. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/radon.mi.yaml +0 -0
  38. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/ruff.format.apply.yaml +0 -0
  39. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/ruff.format.yaml +0 -0
  40. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/ruff.lint.yaml +0 -0
  41. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/ruff.unused.yaml +0 -0
  42. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/semgrep.scan.yaml +0 -0
  43. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/shellcheck.yaml +0 -0
  44. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/shfmt.apply.yaml +0 -0
  45. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/shfmt.format.yaml +0 -0
  46. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/sourcery.review.yaml +0 -0
  47. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/ty.check.yaml +0 -0
  48. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/vulture.scan.yaml +0 -0
  49. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/yamlfmt.apply.yaml +0 -0
  50. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/yamlfmt.format.yaml +0 -0
  51. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/checks/yamllint.check.yaml +0 -0
  52. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/bandit.yaml +0 -0
  53. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/codespell.yaml +0 -0
  54. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/deadcode.yaml +0 -0
  55. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/gitleaks.yaml +0 -0
  56. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/hadolint.yaml +0 -0
  57. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/jscpd.yaml +0 -0
  58. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/markdownlint.yaml +0 -0
  59. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/mdformat.yaml +0 -0
  60. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/mutmut.yaml +0 -0
  61. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/pydeps.yaml +0 -0
  62. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/pytest.yaml +0 -0
  63. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/radon.yaml +0 -0
  64. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/ruff.yaml +0 -0
  65. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/script.yaml +0 -0
  66. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/semgrep.yaml +0 -0
  67. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/shellcheck.yaml +0 -0
  68. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/shfmt.yaml +0 -0
  69. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/sourcery.yaml +0 -0
  70. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/ty.yaml +0 -0
  71. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/vulture.yaml +0 -0
  72. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/yamlfmt.yaml +0 -0
  73. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/catalog/tools/yamllint.yaml +0 -0
  74. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/allowlists/acronyms.yaml +0 -0
  75. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/allowlists/folder-breadth.txt +0 -0
  76. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/allowlists/module-private-vars.txt +0 -0
  77. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/allowlists/module-size.txt +0 -0
  78. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/configs/bandit.yaml +0 -0
  79. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/configs/gates/acronym-allowlist.yaml +0 -0
  80. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/configs/gates/folder-breadth.yaml +0 -0
  81. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/configs/gates/module-private-vars.yaml +0 -0
  82. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/configs/gates/module-size.yaml +0 -0
  83. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/configs/markdownlint.json +0 -0
  84. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/configs/ruff.toml +0 -0
  85. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/configs/ty.toml +0 -0
  86. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/configs/yamlfmt.yaml +0 -0
  87. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/configs/yamllint.yaml +0 -0
  88. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/gates/README.md +0 -0
  89. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/gates/acronym-allowlist.sh +0 -0
  90. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/gates/folder-breadth.sh +0 -0
  91. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/gates/lib.sh +0 -0
  92. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/gates/module-private-vars.sh +0 -0
  93. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/gates/module-size.sh +0 -0
  94. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/defaults/semgrep/python-quality.yml +0 -0
  95. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/suites/demo.yaml +0 -0
  96. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/suites/extended.yaml +0 -0
  97. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/suites/format.yaml +0 -0
  98. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/suites/formatting.yaml +0 -0
  99. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/suites/policy.yaml +0 -0
  100. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/suites/python-quality.yaml +0 -0
  101. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/suites/reslab-parity.yaml +0 -0
  102. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/bundle/suites/standard.yaml +0 -0
  103. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/config_resolver.py +0 -0
  104. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/discovery.py +0 -0
  105. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/gate_config.py +0 -0
  106. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/gates.py +0 -0
  107. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/ignore.py +0 -0
  108. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/ignore_materialize.py +0 -0
  109. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/installer.py +0 -0
  110. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/parsers/__init__.py +0 -0
  111. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/parsers/analysis.py +0 -0
  112. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/parsers/base.py +0 -0
  113. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/parsers/common.py +0 -0
  114. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/parsers/format_text.py +0 -0
  115. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/parsers/gates.py +0 -0
  116. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/parsers/patterns.py +0 -0
  117. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/parsers/prose.py +0 -0
  118. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/parsers/ruff.py +0 -0
  119. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/parsers/shell.py +0 -0
  120. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/policy/__init__.py +0 -0
  121. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/policy/acronym_allowlist.py +0 -0
  122. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/policy/folder_breadth.py +0 -0
  123. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/registry.py +0 -0
  124. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/resolver.py +0 -0
  125. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/runner.py +0 -0
  126. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/runner_script.py +0 -0
  127. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool/target_expand.py +0 -0
  128. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool.egg-info/dependency_links.txt +0 -0
  129. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool.egg-info/entry_points.txt +0 -0
  130. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool.egg-info/requires.txt +0 -0
  131. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/src/pyossmtool.egg-info/top_level.txt +0 -0
  132. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/tests/test_cli.py +0 -0
  133. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/tests/test_config_and_targets.py +0 -0
  134. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/tests/test_discovery.py +0 -0
  135. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/tests/test_gate_config.py +0 -0
  136. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/tests/test_ignore.py +0 -0
  137. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/tests/test_npm_install.py +0 -0
  138. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/tests/test_packaging.py +0 -0
  139. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/tests/test_parser_registry.py +0 -0
  140. {pyossmtool-0.0.1 → pyossmtool-0.0.2}/tests/test_script_gates.py +0 -0
  141. {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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pyossmtool"
3
- version = "0.0.1"
3
+ version = "0.0.2"
4
4
  description = "Quality-gate orchestrator for AI-assisted development"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11,<3.14"
@@ -1,3 +1,3 @@
1
1
  """pyossmtool — quality-gate orchestrator for AI-assisted development."""
2
2
 
3
- __version__ = "0.0.1"
3
+ __version__ = "0.0.2"