Metadata-Version: 2.4
Name: kryptorious-pkgcheck
Version: 1.0.0
Summary: Pre-publish packaging sanity scanner — verify PEP 621 metadata, license, changelog/version match, README links, and that every declared entry point actually imports and runs.
Author: Kryptorious Quantum Biosciences, Inc.
License: MIT
Project-URL: Homepage, https://kryptorious.gumroad.com/l/jbvet
Keywords: packaging,pypi,ci,publish,entry-points,lint,twine,hygiene
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Software Development :: Build Tools
Classifier: Topic :: Utilities
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click>=8.0
Requires-Dist: rich>=13.0
Requires-Dist: build>=1.0
Requires-Dist: tomli>=2.0; python_version < "3.11"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Dynamic: license-file

# pkgcheck

**Pre-publish packaging sanity scanner for Python packages.**

`twine check` validates metadata syntax. It does **not** verify that your
declared console scripts actually import and run. `pkgcheck` does — it builds
your wheel and *actually imports and invokes* every entry point, so an
`ImportError` or a broken CLI surfaces **before** you ship a broken sdist to
PyPI.

Part of the [Kryptorious](https://kryptorious.gumroad.com/l/jbvet) developer
tool fleet.

## What it checks

| Check | Severity | Catches |
|-------|----------|---------|
| PEP 621 fields | error/warning | Missing `name`, `version`, `readme`, `requires-python`, etc. |
| License file | error | `license` declared but no `LICENSE` at repo root |
| Changelog vs version | error | Top `CHANGELOG` entry doesn't match `pyproject` version |
| README links | warning | Dead URLs (opt-in, `--check-links`) |
| Entry-point resolvability | error | `module.attr` target doesn't import (module or symbol missing) |
| Entry-point callable | error | Target resolves to a non-callable |
| Package importable | error | Top-level package raises on import (e.g. bad `__init__`) |
| CLI actually runs | error | CLI produces no output when invoked (`--help`) |

The last four are the differentiator: `pkgcheck` builds a wheel into a temp dir
and imports from it, so it catches publish-breaking bugs that static metadata
checks miss.

## Install

```bash
pip install kryptorious-pkgcheck
```

## Usage

```bash
# Scan the current package (builds a wheel and tests entry points)
pkgcheck check

# Scan a specific path
pkgcheck check ./my-package

# Machine-readable output for CI — exits non-zero if not publish-ready
pkgcheck check --json

# Skip building a wheel (uses the installed/editable package instead)
pkgcheck check --no-build

# Probe README URLs over the network
pkgcheck check --check-links
```

### In CI

```yaml
- name: Packaging gate
  run: pkgcheck check --json
```

`pkgcheck` exits `0` only when the package is `publish_ready` (no errors,
no blocking issues). Wire it as a required status check before your publish job.

## Exit codes

- `0` — publish ready (or `--json` with zero blocking issues)
- `1` — not publish ready (errors present) or human report has errors
- `1` — CI JSON mode with blocking issues

## License

MIT — see [LICENSE](LICENSE).
