Metadata-Version: 2.4
Name: dotdrift
Version: 0.1.0
Summary: Detect drift between .env files — missing, extra, and unset keys
Project-URL: Homepage, https://github.com/Wombatfreak6/envdiff
Project-URL: Repository, https://github.com/Wombatfreak6/envdiff
Project-URL: Bug Tracker, https://github.com/Wombatfreak6/envdiff/issues
License: MIT License
        
        Copyright (c) 2026 wombfrk.exe
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: cli,devtools,dotdrift,dotenv,drift,env,environment
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
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 :: Libraries
Classifier: Topic :: Utilities
Requires-Python: >=3.11
Requires-Dist: rich>=13.0
Requires-Dist: typer>=0.12
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: typer>=0.12; extra == 'dev'
Description-Content-Type: text/markdown

# dotdrift

> Detect drift between your `.env` files — locally, in CI, and against your live environment.

[![PyPI version](https://img.shields.io/pypi/v/dotdrift.svg)](https://pypi.org/project/dotdrift/)
[![Python versions](https://img.shields.io/pypi/pyversions/dotdrift.svg)](https://pypi.org/project/dotdrift/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![CI](https://github.com/Wombatfreak6/envdiff/actions/workflows/ci.yml/badge.svg)](https://github.com/Wombatfreak6/envdiff/actions/workflows/ci.yml)
[![npm](https://img.shields.io/npm/v/dotdrift.svg)](https://www.npmjs.com/package/dotdrift)

---

## Install

```bash
pip install dotdrift
```

Or via npm (requires Python 3.11+ on `$PATH`):

```bash
npx dotdrift
```

---

## Quick start

```bash
# Compare .env against .env.example (the defaults)
dotdrift check

# Compare two specific files
dotdrift check .env .env.staging

# Fail the build if any extra, undocumented keys exist
dotdrift check --strict

# Pipe JSON output into jq
dotdrift check --json | jq .missing

# Generate a redacted .env.example from your real .env
dotdrift sync .env --output .env.example

# Check the live process environment against a reference
dotdrift live .env.example

# Re-run check every time .env changes (Ctrl+C to stop)
dotdrift watch
```

---

## Python API

```python
from envdiff import compare, parse

# Programmatic diff — accepts file paths, raw strings, or plain dicts
result = compare(".env", ".env.example", strict=True, check_conflicts=True)

if not result.is_clean():
    print("Missing keys:", result.missing)
    print("Unset keys:  ", result.unset)
    print("Conflicts:   ", result.conflicts)
    print(result.summary())

# Parse a .env file directly
parsed = parse(".env")
for key, entry in parsed.entries.items():
    print(f"{key} = {entry.value!r}  (line {entry.line_number})")
```

---

## Commands

### `check`

```
dotdrift check [SOURCE] [REFERENCE] [OPTIONS]
```

Compare SOURCE (default: `.env`) against REFERENCE (default: `.env.example`)
and report missing, extra, unset, or conflicting keys.

| Option | Description |
|--------|-------------|
| `--strict` | Exit 2 when extra (undocumented) keys exist |
| `--ignore KEY` | Exclude KEY from all comparisons (repeatable) |
| `--conflicts` | Also detect keys that differ in value |
| `--json` | Emit JSON parseable by `jq` |
| `--quiet` / `-q` | Suppress all output; only set exit code |

**Exit codes:** `0` clean · `1` missing/unset · `2` strict+extra · `3` file not found

---

### `sync`

```
dotdrift sync [SOURCE] [OPTIONS]
```

Generate a `.env.example` from SOURCE with every value redacted (set to `""`).
A header comment block is prepended automatically.

| Option | Description |
|--------|-------------|
| `--output` / `-o` | Output file path (default: `.env.example`) |
| `--overwrite` | Allow overwriting an existing file |
| `--dry-run` | Print to stdout; write nothing |

---

### `live`

```
dotdrift live [REFERENCE] [OPTIONS]
```

Compare `os.environ` (the live running environment) against REFERENCE.
Useful in Docker entrypoints and CI environments to verify all required
variables are injected before the application starts.

| Option | Description |
|--------|-------------|
| `--ignore KEY` | Exclude KEY (repeatable) |
| `--json` | JSON output |

---

### `watch`

```
dotdrift watch [SOURCE] [REFERENCE] [OPTIONS]
```

Poll SOURCE for file changes and re-run `check` on every save.
Uses `stat().st_mtime` — no external dependencies.

| Option | Description |
|--------|-------------|
| `--interval` | Poll interval in seconds (default: 2) |
| `--json` | JSON output per check |

Press **Ctrl+C** to stop cleanly (exit 0).

---

## CI integration

Add this step to your workflow to gate merges on a clean env:

```yaml
- name: Check .env drift
  run: |
    pip install dotdrift
    dotdrift check .env.ci .env.example --strict
```

Or pipe JSON results into a downstream step:

```yaml
- name: Env drift report
  run: dotdrift check --json --quiet > env_report.json
```

---

## Why not just use `python-dotenv`?

`python-dotenv` **loads** `.env` files into `os.environ`. `dotdrift` **audits**
them — it tells you what is missing, what is undocumented, and what has drifted
between environments. They solve different problems and work well together.

---

## License

MIT — see [LICENSE](LICENSE).
