Metadata-Version: 2.4
Name: php-cs-fixer-py
Version: 0.1.6
Summary: Python wrapper for PHP-CS-Fixer with a bundled static PHP binary
License-Expression: GPL-2.0-only
License-File: LICENSE
License-File: PHP-CS-Fixer-LICENSE
License-File: PHP-LICENSE
License-File: Zend-Engine-LICENSE
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: static-php-py>=0.2.0
Description-Content-Type: text/markdown

# php-cs-fixer-py

> PHP-CS-Fixer in Python — check and fix PHP code style through a typed API.

Python wrapper for [PHP-CS-Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) — no local PHP or Composer required.

## Install

```bash
# via uv
uv add php-cs-fixer-py

# or via pip
pip install php-cs-fixer-py
```

Requires Python >= 3.10. Platform wheels bundle PHP-CS-Fixer **3.95.3** (as PHAR) and a static PHP 8.4 binary (built on [static-php-py](https://pypi.org/project/static-php-py/)); a `php` on `PATH` is the fallback when no bundled binary matches the host. `fixer_version()` reports the bundled version at runtime.

## Usage

```python
from php_cs_fixer_py import fix, check, Source

# Two verbs. fix changes, check diagnoses. Both return a FixResult.

# Fix files in place
result = fix("src/", rules={"@Symfony": True, "array_syntax": {"syntax": "short"}})
print(f"changed {len(result.files)} files")

# Check files (dry-run) — nothing written
report = check("src/", rules={"@PSR12": True})
if not report.compliant:                 # CI gate
    for f in report.files:
        print(f.name, f.applied_fixers)
    raise SystemExit(1)

# Fix a source string — wrap in Source.code, read the fixed text off .code
clean = fix(Source.code("<?php $a = array(1,2);"), rules={"@PSR12": True}).code

# Check a source string — same FixResult, ask for .compliant
ok = check(Source.code(clean), rules={"@PSR12": True}).compliant
```

## API

Two verbs split on Command/Query Separation: `fix` (command) and `check` (query). Both return a unified `FixResult`, so the return type depends on the verb, never on the input. Input kind is carried by `Source`; a bare path works directly, raw source needs `Source.code(...)`.

| Function / Class | Signature | Description |
|------------------|-----------|-------------|
| `fix` | `(source, rules, *, risky=False, **opts) -> FixResult` | Apply fixes (in place for paths) |
| `check` | `(source, rules, *, risky=False, **opts) -> FixResult` | Dry-run; report what would change |
| `Source.code` | `(text) -> Source` | Tag raw PHP source (staged to a temp file) |
| `Source.path` | `(*targets) -> Source` | Tag file/directory paths |
| `list_rule_sets` | `() -> list[str]` | Available `@`-prefixed rule sets |
| `fixer_version` | `() -> str` | Bundled PHP-CS-Fixer version |
| `Fixer` | `(php=None)` | Class form; reuse one PHP/PHAR resolution |
| `FixerConfig` | `(rules, risky=…, …)` | Optional reusable configuration object |
| `FixResult.code` | `-> str` | Fixed source (after `fix` on a code source) |
| `FixResult.compliant` | `-> bool` | `True` when nothing would change |
| `FixResult.files` | `-> tuple[FileResult, …]` | Per-file diffs and applied fixers |
| `FixResult.changed` | `-> bool` | Any file changed / would change |
| `FixResult.status` | `-> FixStatus` | Decoded exit-code flags |

Full specifications in [docs/design.md](docs/design.md).

## Documentation

- **[Concepts](docs/concept.md)** — problem scope, data flow, and core terminology.
- **[Design](docs/design.md)** — class specifications, public API, module structure.
- **[Implementation](docs/impl.md)** — library APIs, CLI invocation, report schema, exit codes.

## For Agents

Agent-consumable documentation index at `docs/llms.txt` (llmstxt.org format).

## Citation

If you use this project in academic work, please cite our paper. BibTeX (placeholder until the paper is released):

```bibtex
@misc{beluga_placeholder,
  title  = {{TODO: paper title — not yet released}},
  author = {{TODO: authors}},
  year   = {{TODO}},
  note   = {Paper not yet released. Citation entry will be updated on publication.}
}
```

## License

GPL-2.0 — see [LICENSE](LICENSE).
