dotguard-cli 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,361 @@
1
+ Metadata-Version: 2.4
2
+ Name: dotguard-cli
3
+ Version: 0.2.0
4
+ Summary: Validate .env files against a documented .env.example, and keep real secrets out of git.
5
+ Author: Kanhaiya Kumar
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/K70281095/dotguard
8
+ Project-URL: Issues, https://github.com/K70281095/dotguard/issues
9
+ Project-URL: Changelog, https://github.com/K70281095/dotguard/blob/main/CHANGELOG.md
10
+ Keywords: dotenv,env,environment-variables,config,validation,secrets,cli,ci
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Software Development :: Quality Assurance
23
+ Classifier: Topic :: Security
24
+ Requires-Python: >=3.9
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Provides-Extra: dev
28
+ Requires-Dist: ruff>=0.6; extra == "dev"
29
+ Dynamic: license-file
30
+
31
+ # dotguard
32
+
33
+ **Validate `.env` files against a documented `.env.example`, and keep real secrets out of git.**
34
+
35
+ [![CI](https://github.com/K70281095/dotguard/actions/workflows/ci.yml/badge.svg)](https://github.com/K70281095/dotguard/actions/workflows/ci.yml)
36
+ ![Python](https://img.shields.io/badge/python-3.9%20%E2%80%93%203.13-blue)
37
+ ![Dependencies](https://img.shields.io/badge/dependencies-0-brightgreen)
38
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)
39
+
40
+ Almost every project has a `.env.example` that says which environment variables the app needs.
41
+ Almost every project also has that file drift out of date: a new variable gets added to the code
42
+ but not to the example, someone sets `PORT=80O0`, or a real API key slips into the example and
43
+ gets committed.
44
+
45
+ `dotguard` turns `.env.example` into a lightweight, human-readable **schema** and checks your
46
+ real `.env` against it, locally, in a pre-commit hook or in CI.
47
+
48
+ ```console
49
+ $ dotguard check --env examples/.env --example examples/.env.example
50
+ examples/.env:3 error DG004 PORT=80O0: expected a port number between 1 and 65535
51
+ examples/.env:4 error DG007 APP_ENV=prod is not one of: development, staging, production
52
+ examples/.env:6 error DG006 WORKERS=64 is above the @max of 32
53
+ examples/.env:7 error DG004 BASE_URL=localhost:8080: expected a URL with a scheme and host, e.g. https://example.com
54
+ examples/.env error DG001 DATABASE_URL is missing (documented in examples/.env.example:32)
55
+ examples/.env:8 error DG003 PAYMENTS_API_TOKEN is required but empty
56
+ examples/.env:10 warning DG008 VERBOSE is deprecated: use LOG_LEVEL=debug instead
57
+ examples/.env:11 warning DG002 OLD_FEATURE_FLAG is not documented in examples/.env.example
58
+
59
+ 6 error(s), 2 warning(s)
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Table of contents
65
+
66
+ - [Why dotguard?](#why-dotguard)
67
+ - [Install](#install)
68
+ - [Quick start](#quick-start)
69
+ - [Annotating `.env.example`](#annotating-envexample)
70
+ - [Commands](#commands)
71
+ - [Output formats and exit codes](#output-formats-and-exit-codes)
72
+ - [Using dotguard in CI](#using-dotguard-in-ci)
73
+ - [Using it from Python](#using-it-from-python)
74
+ - [`.env` syntax supported](#env-syntax-supported)
75
+ - [Roadmap](#roadmap)
76
+ - [Contributing](#contributing)
77
+ - [License](#license)
78
+
79
+ ## Why dotguard?
80
+
81
+ | | |
82
+ |---|---|
83
+ | **Zero dependencies** | Pure Python standard library. Nothing to audit, nothing to break. |
84
+ | **No new config file** | The schema lives as comments in the `.env.example` you already have. |
85
+ | **Catches real mistakes** | Missing keys, typos, wrong types, values outside an allowed list or range. |
86
+ | **Secret scanning** | Flags real-looking AWS, GitHub, Slack, Stripe, Google and OpenAI-style keys, private keys and JWTs in files you commit. |
87
+ | **Never leaks values** | Keys marked `@secret` are printed as `****` in every message and CI log. |
88
+ | **CI-friendly** | Stable rule codes, JSON output, GitHub Actions annotations, clear exit codes. |
89
+
90
+ ## Install
91
+
92
+ From PyPI (the package is called `dotguard-cli`; the command is `dotguard`):
93
+
94
+ ```bash
95
+ pip install dotguard-cli
96
+ ```
97
+
98
+ Or the latest code straight from GitHub:
99
+
100
+ ```bash
101
+ pip install git+https://github.com/K70281095/dotguard.git
102
+ ```
103
+
104
+ Or run it from a clone without installing:
105
+
106
+ ```bash
107
+ git clone https://github.com/K70281095/dotguard.git
108
+ cd dotguard
109
+ PYTHONPATH=src python3 -m dotguard --help
110
+ ```
111
+
112
+ Requires Python 3.9 or newer.
113
+
114
+ ## Quick start
115
+
116
+ 1. **Already have a `.env` but no example?** Generate one. Sensitive-looking keys get `@secret`
117
+ and every value is blanked, so the result is safe to commit:
118
+
119
+ ```bash
120
+ dotguard init # writes .env.example from .env
121
+ dotguard init --keep-values # keep non-secret values as defaults
122
+ ```
123
+
124
+ 2. **Document the rules** by adding annotation comments (see below).
125
+
126
+ 3. **Check your environment**:
127
+
128
+ ```bash
129
+ dotguard check
130
+ ```
131
+
132
+ 4. **Make sure nobody commits a real secret** in the example:
133
+
134
+ ```bash
135
+ dotguard scan .env.example
136
+ ```
137
+
138
+ A full, working example lives in [`examples/`](examples/).
139
+
140
+ ## Annotating `.env.example`
141
+
142
+ Write annotations as comments directly above a key. Ordinary comments become the key's
143
+ documentation. A blank line ends the block.
144
+
145
+ ```bash
146
+ # Port the HTTP server listens on.
147
+ # @type port
148
+ # @required
149
+ PORT=8080
150
+
151
+ # Which deployment this is.
152
+ # @values development, staging, production
153
+ APP_ENV=development
154
+
155
+ # Number of background workers.
156
+ # @type int
157
+ # @min 1
158
+ # @max 32
159
+ WORKERS=4
160
+
161
+ # Postgres connection string.
162
+ # @type url
163
+ # @secret
164
+ DATABASE_URL=
165
+
166
+ # Sentry DSN. Leave empty to disable error reporting.
167
+ # @optional
168
+ SENTRY_DSN=
169
+
170
+ # @deprecated use LOG_LEVEL instead
171
+ # @optional
172
+ VERBOSE=
173
+ ```
174
+
175
+ | Annotation | Meaning |
176
+ |---|---|
177
+ | `@type T` | Value must be of type `T`: `string` (default), `int`, `float`, `bool`, `port`, `url`, `email`. |
178
+ | `@required` | Value must not be empty. |
179
+ | `@optional` | Key may be absent from `.env`. Without it, every documented key must be present. |
180
+ | `@pattern REGEX` | Value must fully match the Python regular expression. |
181
+ | `@values a, b, c` | Value must be one of the listed choices. |
182
+ | `@min N` / `@max N` | Inclusive bounds for numeric types. |
183
+ | `@secret` | Never print the value; also makes `scan` treat the key as sensitive. |
184
+ | `@deprecated [reason]` | Warn when the key is still set. |
185
+
186
+ Full reference: [docs/annotations.md](docs/annotations.md). Every rule code (`DG001`…) is
187
+ explained in [docs/rules.md](docs/rules.md).
188
+
189
+ ## Commands
190
+
191
+ ### `dotguard check`
192
+
193
+ ```
194
+ dotguard check [--env .env] [--example .env.example] [--strict]
195
+ [--format text|json|github] [--fail-on-warning]
196
+ ```
197
+
198
+ Checks every key documented in the example against the env file. With `--strict`, keys that
199
+ exist in `.env` but not in the example are errors instead of warnings, which helps keep the
200
+ example complete.
201
+
202
+ ### `dotguard scan`
203
+
204
+ ```
205
+ dotguard scan [FILES ...] [--format text|json|github] [--fail-on-warning]
206
+ ```
207
+
208
+ Scans files you intend to commit (default: `.env.example`) for:
209
+
210
+ - **DS001 (error):** well-known credential formats (AWS, GitHub, Slack, Stripe live keys,
211
+ Google API keys, OpenAI-style keys, PEM private keys, JWTs).
212
+ - **DS002 (warning):** long, high-entropy values under sensitive-looking names
213
+ (`*_TOKEN`, `*_SECRET`, `*PASSWORD*`, `*API_KEY*`, …) or keys marked `@secret`.
214
+
215
+ Obvious placeholders such as `changeme`, `<your-token>`, `xxxx` and `${VAR}` are ignored.
216
+
217
+ ### `dotguard diff`
218
+
219
+ ```
220
+ dotguard diff LEFT RIGHT [--values] [--format text|json|github] [--fail-on-warning]
221
+ ```
222
+
223
+ Compares two environment files, for example staging and production, and reports keys that
224
+ exist in only one of them (**DD001**, **DD002**). With `--values` it also lists keys whose values
225
+ differ (**DD003**, warning). Values themselves are never printed, so the output is safe to paste
226
+ into a ticket or a CI log.
227
+
228
+ ```console
229
+ $ dotguard diff .env.staging .env.production --values
230
+ .env.staging:4 error DD001 FEATURE_X is set in .env.staging but missing from .env.production
231
+ .env.staging:2 warning DD003 DATABASE_URL has a different value in .env.production:2
232
+ ```
233
+
234
+ ### `dotguard init`
235
+
236
+ ```
237
+ dotguard init [--env .env] [--output .env.example] [--keep-values] [--force]
238
+ ```
239
+
240
+ Creates a starter `.env.example` from an existing `.env`, guessing `@type` for ports, numbers,
241
+ booleans, URLs and emails and marking sensitive keys `@secret`. Secret values are never copied,
242
+ even with `--keep-values`. It refuses to overwrite an existing file unless you pass `--force`.
243
+
244
+ ## Output formats and exit codes
245
+
246
+ | `--format` | Use it for |
247
+ |---|---|
248
+ | `text` (default) | People. Colored when writing to a terminal; respects `NO_COLOR` and `FORCE_COLOR`. |
249
+ | `json` | Other tools. `{"issues": [...], "summary": {"errors": N, "warnings": N}}` |
250
+ | `github` | GitHub Actions. Issues appear as inline annotations on the pull request. |
251
+
252
+ | Exit code | Meaning |
253
+ |---|---|
254
+ | `0` | No errors (warnings allowed unless `--fail-on-warning`). |
255
+ | `1` | Problems found. |
256
+ | `2` | Usage error: a file is missing or cannot be parsed. |
257
+
258
+ ## Using dotguard in CI
259
+
260
+ ### GitHub Actions
261
+
262
+ This repository is also a composite action:
263
+
264
+ ```yaml
265
+ - uses: actions/checkout@v5
266
+ - uses: K70281095/dotguard@v0.2.0
267
+ with:
268
+ command: scan
269
+ args: .env.example
270
+ ```
271
+
272
+ Or install and run it yourself:
273
+
274
+ ```yaml
275
+ - uses: actions/setup-python@v6
276
+ with:
277
+ python-version: "3.12"
278
+ - run: pip install git+https://github.com/K70281095/dotguard.git
279
+ - run: dotguard scan .env.example --format github
280
+ ```
281
+
282
+ ### pre-commit
283
+
284
+ ```yaml
285
+ # .pre-commit-config.yaml
286
+ repos:
287
+ - repo: https://github.com/K70281095/dotguard
288
+ rev: v0.2.0
289
+ hooks:
290
+ - id: dotguard-scan
291
+ ```
292
+
293
+ More recipes, including GitLab CI and a plain git hook: [docs/ci.md](docs/ci.md).
294
+
295
+ ## Using it from Python
296
+
297
+ ```python
298
+ import dotguard
299
+
300
+ env = dotguard.parse_file(".env")
301
+ example = dotguard.parse_file(".env.example")
302
+
303
+ for issue in dotguard.check(env, example, strict=True):
304
+ print(issue.code, issue.severity.value, issue.message)
305
+
306
+ for issue in dotguard.scan(example):
307
+ print("possible secret:", issue.key)
308
+ ```
309
+
310
+ ## `.env` syntax supported
311
+
312
+ ```bash
313
+ # comments on their own line
314
+ KEY=value
315
+ export KEY=value # "export" prefix is allowed
316
+ KEY=value # trailing comment # needs whitespace before "#"
317
+ URL=https://example.com/#anchor # "#" inside a value is kept
318
+ KEY="double \"quoted\"\nwith escapes" # \n \t \r \" \\ \$
319
+ KEY='single quoted, taken literally, even $HOME'
320
+ EMPTY=
321
+
322
+ # Quoted values can span several lines (handy for certificates):
323
+ CERT="-----BEGIN CERTIFICATE-----
324
+ MIIB...
325
+ -----END CERTIFICATE-----"
326
+
327
+ # References to keys defined earlier in the same file:
328
+ HOST=localhost
329
+ PORT=5432
330
+ DATABASE_URL=postgres://${HOST}:${PORT}/app # also $HOST
331
+ LOG_DIR=${LOG_ROOT:-/var/log}/app # default if unset or empty
332
+ LOG_FILE=${LOG_NAME-app.log} # default only if unset
333
+ PRICE="costs \$5" # \$ keeps a literal dollar sign
334
+ ```
335
+
336
+ References work in unquoted and double-quoted values, never in single-quoted ones. A reference to
337
+ a key that is not defined above it expands to an empty string and `check` warns about it
338
+ (`DG011`). Values are never read from your shell's environment, so results are the same on every
339
+ machine.
340
+
341
+ Duplicate keys and malformed lines are reported with their file and line number.
342
+
343
+ ## Roadmap
344
+
345
+ - [x] `${VAR}` interpolation when checking values
346
+ - [x] Multi-line quoted values
347
+ - [x] Publish to PyPI (as `dotguard-cli`)
348
+ - [x] `dotguard diff` to compare two environments (e.g. staging vs production keys)
349
+ - [ ] Optional JSON Schema export
350
+
351
+ Ideas and pull requests are welcome. See the [issues](https://github.com/K70281095/dotguard/issues).
352
+
353
+ ## Contributing
354
+
355
+ Contributions of every size are welcome: bug reports, docs fixes, new secret patterns, new
356
+ `@type`s. Please read [CONTRIBUTING.md](CONTRIBUTING.md) and our
357
+ [Code of Conduct](CODE_OF_CONDUCT.md). To report a vulnerability, see [SECURITY.md](SECURITY.md).
358
+
359
+ ## License
360
+
361
+ [MIT](LICENSE) © 2026 Kanhaiya Kumar
@@ -0,0 +1,16 @@
1
+ dotguard/__init__.py,sha256=_Fs5MveEP5v1YA1ETx829RFf0vY4ZMuLiR36llRNanc,462
2
+ dotguard/__main__.py,sha256=9oo8mSr8UFrTSuvycEZ5vwbpfD3ATAztgq0-w2JOQgE,60
3
+ dotguard/checker.py,sha256=2fc2PEA3oBZSZVu2CM7Xnz1ClDUrWlF1r2xc_aiw93o,6172
4
+ dotguard/cli.py,sha256=wzkXgyChGFu6ZU5Ck30vSJzezb0OkFmX0pVmJADcXew,6736
5
+ dotguard/differ.py,sha256=0J8YaUi-7dr2HFZ8bFhQOQY3owCmbGy8XkHBHy-h470,1913
6
+ dotguard/models.py,sha256=k_fNs1gL6TWm6waqmvX8cJdlIxnN2keAu3HRlZZIi3o,1555
7
+ dotguard/parser.py,sha256=_3LN4r0Jwtvmvwp67XkZUgZlT9N349gnTGC4hW8Am3g,6611
8
+ dotguard/report.py,sha256=tnqz_jSO6W5GZLvDMpIp9Z4huHAcvnirA-xjjDwMrOw,2768
9
+ dotguard/secrets.py,sha256=T_5FTFeLUXHNTt4kOZ4LE8bxQpOHPZ3lNSW3Rw8kzu4,3064
10
+ dotguard/types.py,sha256=8-8H6CYSDzj96CGJWjZLWl_-VtQj4Y5nSiBA08gHxBI,1779
11
+ dotguard_cli-0.2.0.dist-info/licenses/LICENSE,sha256=DiKGOUDmnu9L4s92hKgB3PReJXEvjSFYMtycfNQ7RSY,1071
12
+ dotguard_cli-0.2.0.dist-info/METADATA,sha256=JEw_Drg4K6_LajKsqsXpSMCyFBLIcWL23VgvYg1r6-4,12180
13
+ dotguard_cli-0.2.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
14
+ dotguard_cli-0.2.0.dist-info/entry_points.txt,sha256=82CJmKU7qHWeoJ_BPCLiwkGTYa1xfFgIqCFGqd1beR8,47
15
+ dotguard_cli-0.2.0.dist-info/top_level.txt,sha256=W78Zeo-YFMtyutbuTcscMcEQKlW2tBR9SAkfPC6MDu4,9
16
+ dotguard_cli-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.2.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ dotguard = dotguard.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kanhaiya Kumar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ dotguard