Metadata-Version: 2.4
Name: dotenv-sync
Version: 1.0.0
Summary: Keep .env.example in sync with .env and validate environment variables before boot. Detect missing, extra and empty env vars in CI. A zero-dependency dotenv-linter alternative that stops apps crashing on a missing variable.
Project-URL: Homepage, https://pypi.org/project/dotenv-sync/
Project-URL: Repository, https://pypi.org/project/dotenv-sync/
Project-URL: Issues, https://pypi.org/project/dotenv-sync/
Project-URL: Changelog, https://pypi.org/project/dotenv-sync/
Author: envsync contributors
License-Expression: MIT
License-File: LICENSE
Keywords: app-config,automation,ci,cli,config,config-validation,configuration,container-config,cross-platform,deployment-config,developer-tools,devtools,docker-env,dotenv,dotenv-linter,dotenv-linter-alternative,dotenv-sync,env,env-example,env-sample,env-sync,env-template,env-validation,environment-config,environment-variables,missing-env,missing-env-vars,pre-commit,preflight,secrets-management,sync,sync-env,twelve-factor,twelve-factor-app,validate-env,validation,zero-dependency
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
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 :: Build Tools
Classifier: Topic :: Utilities
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown

<div align="center">

# 🔐 envsync

### Keep `.env.example` in sync with `.env` — and never boot with a missing variable again.

The number one "works on my machine" bug: someone adds `STRIPE_KEY` to their `.env`,
forgets to update `.env.example`, and a teammate's app crashes with a cryptic error.
`envsync` fixes both sides of that — automatically, with **zero dependencies**.

[![PyPI version](https://img.shields.io/pypi/v/dotenv-sync.svg?color=3775A9&logo=pypi&logoColor=white)](https://pypi.org/project/dotenv-sync/)
[![Python versions](https://img.shields.io/pypi/pyversions/dotenv-sync.svg?color=3775A9)](https://pypi.org/project/dotenv-sync/)
[![zero dependencies](https://img.shields.io/badge/dependencies-0-brightgreen.svg)](https://pypi.org/project/dotenv-sync/)
[![license](https://img.shields.io/pypi/l/dotenv-sync.svg?color=blue)](./LICENSE)

</div>

> Installed from PyPI as **`dotenv-sync`**; it gives you the **`envsync`** command
> (and a `dotenv-sync` alias).

---

## The problem

`.env.example` is the contract every teammate copies. But it drifts the instant someone
adds a variable to their local `.env` and forgets the template:

- New devs `cp .env.example .env`, run the app → **crash**, because a required key was
  never in the template.
- Code reviews can't see that a PR introduced a new required env var.
- Secrets occasionally get pasted into `.env.example` by hand and **leak into git**.

## The fix

```bash
uvx dotenv-sync             # add new keys from .env to .env.example (values stripped)
uvx dotenv-sync check       # CI: fail if the template drifted
uvx dotenv-sync validate    # preflight: fail if your local .env is missing required keys
```

```text
$ uvx dotenv-sync
✔ added 2 key(s) to .env.example:
  + STRIPE_KEY
  + REDIS_URL

$ uvx dotenv-sync validate
✖ missing 1 required key(s) (declared in .env.example):
  ✖ DATABASE_URL
Your app may crash on boot. Fill these in .env (copy from .env.example).
```

- ✅ **Never leaks values.** Only keys are written to `.env.example` (`KEY=`), and your
  curated placeholders/comments are preserved.
- ✅ **Non-destructive & idempotent.** Existing lines are never touched; running twice is
  a no-op.
- ✅ **Zero dependencies.** Installs instantly, nothing to audit.

## Install

```bash
uvx dotenv-sync            # run without installing (uv)
pipx install dotenv-sync   # or install the CLI globally
pip install dotenv-sync    # or into your project
```

## Commands

| Command | What it does |
| --- | --- |
| `envsync` / `envsync sync` | Append keys in `.env` missing from `.env.example` (values stripped) |
| `envsync check` | CI mode — exit 1 if `.env.example` is missing keys from `.env` |
| `envsync validate` | Preflight — exit 1 if your `.env` is missing keys the template requires |
| `envsync init` | Create `.env.example` from `.env` (values stripped) or a starter |

Options: `--env <file>`, `--example <file>`, `--cwd <dir>`, `--allow-empty`, `--process`
(also accept keys from the process environment during `validate`), `--quiet`.

## Use it in CI

```yaml
# .github/workflows/env.yml
name: env
on: [push, pull_request]
jobs:
  envsync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/setup-uv@v5
      - run: uvx dotenv-sync check   # fail if someone forgot to update .env.example
```

Pre-commit hook:

```yaml
# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: envsync
        name: envsync check
        entry: envsync check
        language: system
        pass_filenames: false
```

## Preflight before your app starts

Catch missing config *before* a confusing runtime crash — e.g. in a container entrypoint:

```bash
envsync validate && python -m myapp
```

## Python API

```python
from envsync import validate

result = validate()
if not result.ok:
    raise SystemExit(f"Missing env: {result.missing}")
```

## How keys are parsed

`KEY=VALUE`, `export KEY=VALUE`, single/double-quoted values, `# comments`, and blank
lines. Unrecognized lines are preserved verbatim, so envsync never mangles your files.

## FAQ

### How do I keep .env.example in sync with .env in Python?

Run `uvx dotenv-sync` (or `pip install dotenv-sync` then `envsync`). It adds any key in
`.env` that's missing from `.env.example`, values stripped, preserving your comments. Add
`uvx dotenv-sync check` to CI so the build fails when the template drifts.

### How do I validate required environment variables before the app starts?

`uvx dotenv-sync validate` reads the keys declared in `.env.example` and exits `1` listing
any missing or empty ones in your `.env` or process environment — a preflight that catches
misconfiguration before a confusing runtime crash.

### Does it leak secrets into .env.example?

Never. Only keys are written (`KEY=`); values are always stripped and existing lines are
preserved.

### dotenv-sync vs dotenv-linter / python-dotenv / pydantic-settings?

`python-dotenv`/`pydantic-settings` *load* env vars; `dotenv-sync` *keeps the template
honest and validates it* — sync, CI drift-check, and preflight validation, with **zero
dependencies**. It's the Python twin of the npm `envsync` package (byte-identical output).

## Also on npm

JavaScript project? The same tool ships on npm — `npx envsync`.

## License

[MIT](./LICENSE) — free for personal and commercial use.
