Metadata-Version: 2.4
Name: pyossmtool
Version: 0.0.2
Summary: Quality-gate orchestrator for AI-assisted development
Author-email: Vishal Kumar Mishra <vishal.k.mishra2@gmail.com>
License-Expression: MIT
Project-URL: Changelog, https://github.com/inquilabee/pyossmtool/blob/main/CHANGELOG.md
Project-URL: Homepage, https://github.com/inquilabee/pyossmtool
Project-URL: Issues, https://github.com/inquilabee/pyossmtool/issues
Project-URL: Repository, https://github.com/inquilabee/pyossmtool
Keywords: quality,lint,format,pre-commit,python,static-analysis
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: <3.14,>=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pydantic>=2.0
Requires-Dist: pathspec>=0.12
Requires-Dist: pyyaml>=6.0
Requires-Dist: typer>=0.12
Dynamic: license-file

# pyossmtool

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.

## Why use it

- One config file and a shared CLI for lint, type-check, format, security, and custom gates
- `check` reports problems without rewriting files; `format` applies formatters
- Tools discover the right files from their own globs under your scan root
- `.gitignore` is always respected
- Failures produce JSON reports under `reports/failures/` for humans and AI agents

## Install

```bash
pip install pyossmtool
# or
uv add --dev pyossmtool
```

Requires Python 3.11–3.13.

## Quick start

Create `pyossmtool.yaml` in your repo (the `all` suite includes every bundled check):

```yaml
suite: all
env: auto
target: .
configs:
  mode: auto
```

Install the binaries for that suite, then run:

```bash
pyossmtool install --suite all
pyossmtool format --suite all   # mode: format (writes)
pyossmtool check --suite all    # mode: check (report-only)
```

`check` and `format` each run only their mode, so use both when you want full coverage from `all`.

```bash
pyossmtool list suites
pyossmtool list tools
pyossmtool list checks
pyossmtool check --check ruff.lint --target .
```

Copy [`pyossmtool.yaml.example`](pyossmtool.yaml.example) for a fuller annotated config.

## Suites

The package ships the **full catalog** of tools and checks. A **suite** is a named subset — or `all` for everything.

| Suite | Role |
|-------|------|
| `all` | Every bundled check |
| `python-quality` | Core Python lint / format-check / types |
| `formatting` | Format **check** (report-only) across languages |
| `format` | Format **apply** only |
| `standard` | Broader portable quality set |
| `extended` | Slower / optional extras on top of standard |
| `policy` | Bundled script gates |
| `demo` | Sample-files fixture suite for development |

### Suite examples

**Full dogfood (every check):**

```yaml
suite: all
env: auto
target: .
```

```bash
pyossmtool install --suite all
pyossmtool format --suite all
pyossmtool check --suite all
```

**Python-focused CI gate:**

```yaml
suite: python-quality
env: auto
target: .
error-format: compact
```

```bash
pyossmtool install --suite python-quality
pyossmtool check --suite python-quality
```

**Apply formatters only (writes files):**

```yaml
suite: format
env: auto
```

```bash
pyossmtool install --suite format
pyossmtool format --suite format
```

**Report-only formatting drift (no writes):**

```yaml
suite: formatting
error-format: text
```

```bash
pyossmtool check --suite formatting
```

**Broader portable set, GitHub Actions annotations:**

```yaml
suite: standard
error-format: github
```

```bash
pyossmtool check --suite standard
```

Override the suite for one run without editing the file:

```bash
pyossmtool check --suite extended
pyossmtool check --suite policy
```

## Success and failure output

Success is silent: no stdout, exit code `0`.

```bash
$ pyossmtool check --suite python-quality
$ echo $?
0
```

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`.

### Error formatters

Set `error-format` in `pyossmtool.yaml`. Built-ins (plug in by name):

| Name | Use when |
|------|----------|
| `json` | Default — machines / AI agents (pretty JSON on stderr) |
| `log` | Timestamped log lines for aggregators |
| `text` | Short human summary in the terminal |
| `compact` | Editor-friendly `file:line:` one-liners |
| `github` | GitHub Actions workflow annotations |

On-disk `report.json` is **always** JSON regardless of `error-format`.

#### `json` (default)

```yaml
# error-format: json   # or omit — same effect
suite: python-quality
```

```json
{
  "schema_version": "1.0",
  "check_id": "ruff.lint",
  "tool_id": "ruff",
  "status": "failed",
  "summary": { "finding_count": 1, "by_severity": { "error": 1 } },
  "findings": [
    {
      "rule_id": "E501",
      "severity": "error",
      "message": "Line too long (121 > 120)",
      "location": { "file": "src/app.py", "line": 42 }
    }
  ],
  "report_path": "reports/failures/ruff.lint-20260716T163000Z/report.json"
}
```

#### `log`

```yaml
suite: python-quality
error-format: log
```

```text
FAIL ruff.lint findings=1 -> reports/failures/ruff.lint-…/report.json
2026-07-16T12:00:00+00:00 [error] ruff.lint/E501 src/app.py:42: Line too long (121 > 120)
```

#### `text`

```yaml
suite: formatting
error-format: text
```

```text
FAIL ruff.lint -> reports/failures/ruff.lint-…/report.json
findings: 1
- [error] E501: Line too long (121 > 120) (src/app.py:42)
suggested:
  ruff check --fix .
```

#### `compact`

```yaml
suite: standard
error-format: compact
```

```text
src/app.py:42: error: E501 Line too long (121 > 120)
```

#### `github`

```yaml
suite: standard
error-format: github
```

```text
::error file=src/app.py,title=ruff.lint/E501,line=42::Line too long (121 > 120)
```

Severity maps to `::error`, `::warning`, or `::notice` so annotations show up on the PR file view in GitHub Actions.

### Custom formatters

Define named formatters under `error-formatters`, then select one with `error-format`:

```yaml
suite: all
error-format: short
error-formatters:
  short:
    kind: finding_line
    template: "{severity}\t{rule_id}\t{file}:{line}\t{message}"
  myjq:
    kind: jq
    program: >
      .findings[] | "[\(.severity)] \(.rule_id) \(.location.file // "-"):\(.location.line // "?") \(.message)"
```

`finding_line` placeholders: `severity`, `rule_id`, `message`, `file`, `line`, `check_id`, `report_path`.  
`jq` requires `jq` on `PATH`.

### Combined examples

**Local Python repo, readable failures:**

```yaml
suite: python-quality
env: auto
target: .
error-format: text
configs:
  mode: auto
```

**CI on GitHub:**

```yaml
suite: standard
env: auto
error-format: github
```

**Everything + compact lines:**

```yaml
suite: all
error-format: compact
```

### Schema

Print the JSON Schema for on-disk `FailureReport` files:

```bash
pyossmtool schema
pyossmtool schema > failure-report.schema.json
```

## Targeting

- Default scan root is `.` (override with `target:` in `pyossmtool.yaml` or in a suite)
- Each tool declares which files it cares about (for example `**/*.py`)
- `.gitignore` is always applied; you can add extra ignore profiles or paths in config

## Project-local gates

Scaffold a custom script gate:

```bash
pyossmtool gate init module-size --description "Cap module line counts"
```

Then enable the check in `pyossmtool.yaml` (see the example file for the steps).

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for local development, adding tools/checks, and release notes.

## License

MIT
