Metadata-Version: 2.4
Name: compose-doctor
Version: 0.1.0
Summary: A modular linter and auto-fixer for Docker Compose files
Author: Mehdi
License-Expression: MIT
Keywords: compose,devops,docker,lint,yaml
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.10
Requires-Dist: ruamel-yaml>=0.17.0
Provides-Extra: dev
Requires-Dist: mypy>=1.11; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Description-Content-Type: text/markdown

# Compose Doctor

**Lint. Teach. Fix — safely.**

Compose Doctor is a modular Python CLI that reviews Docker Compose files, reports production footguns, and applies **safe, deterministic** auto-fixes without destroying comments or formatting (`ruamel.yaml` round-trip + atomic writes).

## Problem

Compose files often “work on my machine” while carrying floating tags, missing restart policies, privileged containers, hardcoded secrets, unbounded resources, or missing healthchecks. Teams need a small, boring tool that catches these issues early — and fixes only what is safe.

## Status

**MVP (v0.1.0) — usable locally / in CI.** Core engine, CLI, reporters, and rules **R001–R006** are implemented. Interactive `$EDITOR` review and PyPI publishing are **not** available yet (see [Roadmap](docs/ROADMAP.md)).

## Features

- Four-phase engine: **Analyze → Fix (in memory) → Re-analyze → Report**
- Format-preserving YAML load/dump with **atomic** writes (`fsync` + `os.replace`)
- Automatic rule discovery (one file per rule; **no** central registry)
- Safe auto-fixes only (R001, R002); other findings are report-only
- Human **text** output and machine **JSON** output
- Flag-based CLI (`argparse`) — **no subcommands**
- Stable exit codes for CI

## Supported rules

| ID | Name | Severity | Auto-fix |
| --- | --- | --- | --- |
| R001 | `restart_policy` | warning | Yes → `restart: always` |
| R002 | `no_latest_tag` | warning | Yes → `:pinned` placeholder + TODO comment |
| R003 | `security_privileged` | error | No |
| R004 | `environment_variable_leaks` | error | No |
| R005 | `resource_limits_missing` | warning | No |
| R006 | `healthcheck_missing` | warning | No |

Details: [docs/RULES.md](docs/RULES.md).

## Installation

Requires **Python 3.10+**.

```bash
git clone <repository-url>
cd compose-doctor
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
```

This installs the `compose-doctor` console script and the `compose_doctor` package.

## Basic usage

The CLI is **flag-based** (not subcommands):

```bash
compose-doctor --help
compose-doctor --version
compose-doctor --list-rules

compose-doctor compose.yaml              # report findings (no write)
compose-doctor --preview compose.yaml    # in-memory fixes + re-analyze (no write)
compose-doctor --fix compose.yaml        # apply safe fixes atomically
compose-doctor --json compose.yaml       # JSON RunReport on stdout
```

Short aliases: `-p` preview · `-f` fix · `-j` json · `-l` list-rules · `-v` version.

`--preview` and `--fix` **cannot** be combined (exit code 2).

Full guide: [docs/USAGE.md](docs/USAGE.md).

### Preview example

```bash
compose-doctor -p compose.yaml
```

Runs fixable rules in memory, re-analyzes, prints a text report, **does not** modify the file.

### Fix example

```bash
compose-doctor -f compose.yaml
```

Same as preview, then atomically writes the fixed document when `apply_fixes` succeeds.

### JSON example

```bash
compose-doctor -j compose.yaml
echo $?
```

Stdout is **only** JSON (errors go to stderr). Schema keys: `source_path`, `options`, `findings_before`, `fix_results`, `findings_after`, `new_findings`, `wrote_file`. The in-memory YAML tree (`fixed_doc`) is **not** included.

### List rules

```bash
compose-doctor -l
```

## Exit codes

| Code | Meaning |
| --- | --- |
| `0` | Clean run, or all remaining issues were fixed |
| `1` | Missing file, invalid YAML, or unexpected runtime error |
| `2` | CLI usage / argument validation error |
| `10` | Completed successfully, but **unresolved findings** (or failed/regression fixes) remain |

## Development

```bash
pip install -e ".[dev]"
pytest
ruff check src tests
mypy
```

Architecture: [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)  
Contributing: [CONTRIBUTING.md](CONTRIBUTING.md)  
Changelog: [CHANGELOG.md](CHANGELOG.md)

## Architecture overview

```text
CLI (argparse) → discover_rules() → Engine (4 phases) → TextReporter | JsonReporter
                      ↑                      ↓
                   rules/*              YAMLHandler (load / dump_atomic)
```

Rules are **stateless**, operate on in-memory Compose data, and never import the CLI or reporters.

## Current limitations

- No subcommands (flags only)
- No `--select` / `--ignore` rule filters in the CLI (loader supports them internally)
- No unified-diff “suggest” printer (preview updates findings in memory; text/JSON report only)
- No interactive `$EDITOR` review
- No config file (e.g. `compose-doctor.toml`)
- R002’s `:pinned` tag is a **placeholder** — you must replace it with a real version
- R005 does **not** invent CPU/memory defaults
- R006 does **not** invent healthcheck commands
- Not published to PyPI yet (install from source)

## Roadmap

See [docs/ROADMAP.md](docs/ROADMAP.md) for milestones (interactive mode, CI publishing, more rules).

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md). Short version: one concern per branch (`feat/` / `fix/` / `docs/` / `chore/`), add tests with every rule, never leak secrets in findings or docs.

## License

Declared as **MIT** in `pyproject.toml`. A root `LICENSE` file may be added in a follow-up docs/legal pass.
