Metadata-Version: 2.4
Name: epubcheck-bridge
Version: 0.1.1
Summary: Install and run a pinned official EPUBCheck distribution from Python environments
Keywords: epub,epubcheck,publishing,validation
License-Expression: MIT
License-File: LICENSE
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 :: Only
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Text Processing :: Markup :: XML
Classifier: Typing :: Typed
Requires-Python: >=3.10
Project-URL: Documentation, https://github.com/yamaton/epubcheck-bridge#readme
Project-URL: Repository, https://github.com/yamaton/epubcheck-bridge
Project-URL: Issues, https://github.com/yamaton/epubcheck-bridge/issues
Description-Content-Type: text/markdown

# epubcheck-bridge

[![PyPI](https://img.shields.io/pypi/v/epubcheck-bridge.svg)](https://pypi.org/project/epubcheck-bridge/)
[![test](https://github.com/yamaton/epubcheck-bridge/actions/workflows/test.yml/badge.svg)](https://github.com/yamaton/epubcheck-bridge/actions/workflows/test.yml)

`epubcheck-bridge` installs a pinned, checksum-verified copy of the official
[EPUBCheck](https://github.com/w3c/epubcheck) distribution into the active
Python environment. It exposes the upstream CLI as `epubcheck` and provides a
small Python API for consuming JSON validation results.

It is a bridge to the official Java implementation, not a reimplementation of
EPUB validation. This project is not affiliated with or endorsed by W3C or the
DAISY Consortium.

The current release pins official EPUBCheck 5.3.0.

## Requirements

- Python 3.10 or newer
- Java available as `java` on `PATH`
- Network access when installing the pinned EPUBCheck distribution

## Installation

### Project dependency

Add the bridge, then explicitly install its pinned official distribution:

```console
uv add epubcheck-bridge
uv run epubcheck-install
uv run epubcheck --version
```

Use `uv add --dev epubcheck-bridge` instead when validation is only a
development or release task.

Inside an already activated virtual environment, pip can be used instead:

```console
python -m pip install epubcheck-bridge
epubcheck-install
epubcheck --version
```

### Standalone command

Install the two commands in an isolated uv tool environment:

```console
uv tool install epubcheck-bridge
epubcheck-install
epubcheck --version
```

The installer must run from a virtual or tool environment. It places the
official distribution under that environment's `share/epubcheck-bridge/`
directory. Re-running it is a no-op when the expected version and checksum are
already installed; pass `--force` to replace it.

The download is explicit rather than an install hook or a first-run side
effect. This keeps dependency installation predictable and lets offline
validation fail with an actionable message.

## Command-line usage

All arguments and the exit status are forwarded to the official command:

```console
uv run epubcheck book.epub
uv run epubcheck --json report.json book.epub
```

When installed as a standalone tool, omit `uv run`.

## Python API

Python callers can request a structured result:

```python
from epubcheck_bridge import EpubCheckRunner

result = EpubCheckRunner().validate("book.epub")
if not result.passed:
    raise SystemExit(
        f"{result.fatals} fatal, {result.errors} error, {result.warnings} warning"
    )
```

`EpubCheckResult` includes the source and report paths, checker version, fatal,
error and warning counts, subprocess exit code, parsed messages, and a `passed`
property. Pass `fail_on_warnings=True` to `validate()` when warnings should
also make the upstream command fail.

`EpubCheckUnavailable` reports resolution failures.
`EpubCheckExecutionError` reports launch failures, timeouts, and unreadable or
unexpected JSON reports.

## Command resolution

The bridge resolves EPUBCheck in this order:

1. `command_path` passed to `EpubCheckRunner`;
2. the `EPUBCHECK` environment variable;
3. the `EPUBCHECK_JAR` environment variable;
4. the managed distribution installed by `epubcheck-install`;
5. an external `epubcheck` command on `PATH`;
6. `/usr/share/java/epubcheck.jar`.

An executable path is run directly. A `.jar` path is launched with `java -jar`.

## Security and release policy

The upstream EPUBCheck version, archive URL, byte size, and SHA-256 digest are
pinned in the package. Updating EPUBCheck requires a reviewed
`epubcheck-bridge` release; runtime commands never resolve a moving "latest"
download.

The EPUBCheck archive is downloaded directly from the upstream W3C GitHub
release and retains its own license files. It is not bundled in this Python
distribution.

`epubcheck-bridge` and EPUBCheck have independent version numbers and release
cycles. A new bridge release is required whenever its pinned upstream
distribution changes.

## Development

The unit suite uses local fixtures and does not download EPUBCheck. The package
repository owns one CI smoke test that downloads the pinned archive and runs
the official Java version command.

```console
uv sync --frozen
uv run ruff check .
uv run ruff format --check .
uv run pytest -q
uv build --no-sources
```

## License

The Python bridge is released under the
[MIT License](https://github.com/yamaton/epubcheck-bridge/blob/main/LICENSE).
The separately downloaded official EPUBCheck distribution is not part of this
package and retains its own license.
