envshield 4.7.4__tar.gz → 4.8.0__tar.gz
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.
- {envshield-4.7.4 → envshield-4.8.0}/PKG-INFO +9 -5
- {envshield-4.7.4 → envshield-4.8.0}/README.md +8 -4
- envshield-4.8.0/envshield/__init__.py +1 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/cli.py +274 -113
- {envshield-4.7.4 → envshield-4.8.0}/envshield/config/manager.py +452 -65
- {envshield-4.7.4 → envshield-4.8.0}/envshield/core/contract_diff.py +133 -51
- {envshield-4.7.4 → envshield-4.8.0}/envshield/core/dependency_diff.py +24 -3
- {envshield-4.7.4 → envshield-4.8.0}/envshield/core/dependency_snapshot.py +26 -6
- {envshield-4.7.4 → envshield-4.8.0}/envshield/core/discovery.py +312 -21
- {envshield-4.7.4 → envshield-4.8.0}/envshield/core/doctor.py +66 -48
- {envshield-4.7.4 → envshield-4.8.0}/envshield/core/enforcement.py +6 -0
- envshield-4.8.0/envshield/core/evaluator.py +598 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/core/exceptions.py +116 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/core/explain.py +62 -92
- envshield-4.8.0/envshield/core/file_updater.py +296 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/core/generator.py +31 -15
- envshield-4.8.0/envshield/core/hooks_manager.py +669 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/core/importer.py +15 -2
- {envshield-4.7.4 → envshield-4.8.0}/envshield/core/scanner.py +187 -503
- {envshield-4.7.4 → envshield-4.8.0}/envshield/core/schema_manager.py +255 -108
- envshield-4.8.0/envshield/core/schema_scope.py +296 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/core/schema_snapshot.py +66 -6
- {envshield-4.7.4 → envshield-4.8.0}/envshield/core/schema_types.py +139 -24
- {envshield-4.7.4 → envshield-4.8.0}/envshield/core/service_discovery.py +20 -7
- {envshield-4.7.4 → envshield-4.8.0}/envshield/core/setup_manager.py +54 -24
- envshield-4.8.0/envshield/core/source_files.py +124 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/parsers/_base.py +6 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/parsers/_docker_compose.py +32 -13
- {envshield-4.7.4 → envshield-4.8.0}/envshield.egg-info/PKG-INFO +9 -5
- {envshield-4.7.4 → envshield-4.8.0}/envshield.egg-info/SOURCES.txt +3 -0
- {envshield-4.7.4 → envshield-4.8.0}/pyproject.toml +1 -1
- envshield-4.7.4/envshield/__init__.py +0 -1
- envshield-4.7.4/envshield/core/file_updater.py +0 -135
- envshield-4.7.4/envshield/core/hooks_manager.py +0 -216
- {envshield-4.7.4 → envshield-4.8.0}/LICENSE.md +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/__main__.py +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/classifier/__init__.py +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/classifier/context_classifier.py +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/classifier/tokenizer.py +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/config/__init__.py +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/core/__init__.py +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/core/inspector.py +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/core/service_manager.py +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/parsers/__init__.py +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/parsers/_deployment.py +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/parsers/_dotenv.py +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/parsers/_kubernetes.py +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/parsers/_python.py +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/parsers/factory.py +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/state.py +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/utils/__init__.py +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/utils/git_utils.py +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield/utils/paths.py +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield.egg-info/dependency_links.txt +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield.egg-info/entry_points.txt +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield.egg-info/requires.txt +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/envshield.egg-info/top_level.txt +0 -0
- {envshield-4.7.4 → envshield-4.8.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: envshield
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.8.0
|
|
4
4
|
Summary: EnvShield: environment variables as a version-controlled configuration contract.
|
|
5
5
|
Author-email: Rabbil Yasar Sajal <rabbilyasar@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -165,10 +165,11 @@ What each field actually means:
|
|
|
165
165
|
| `enum` | Value must be one of this list. Implies an enum type regardless of `type`. |
|
|
166
166
|
| `pattern` | A regex the value must also match, e.g. `pattern = "^v\\d+\\.\\d+\\.\\d+$"`. |
|
|
167
167
|
| `secret` | Marks the variable sensitive — masked input in `setup`, masked in generated code. `import` auto-suggests it from the variable's name/value; it never overwrites a `secret` value you've already committed. |
|
|
168
|
-
| `defaultValue` | What `setup` writes automatically. A variable still has to be explicitly present in your local file
|
|
168
|
+
| `defaultValue` | What `setup` writes automatically (and `.env.example` and generated code show). A default never makes a variable optional: it still has to be explicitly present in your local file — `check`/`doctor` name the default inline so a missing one is obvious. |
|
|
169
|
+
| `required` | Optional. `required = false` makes a variable optional: it may be absent or blank, but a value that is set must still be valid. `required = true` is the default. Can't be combined with `requiredIf`. |
|
|
169
170
|
| `description` | Shown in `setup`, copied into generated code. |
|
|
170
171
|
|
|
171
|
-
|
|
172
|
+
Requiredness: every variable is required unless `required = false`, or `requiredIf` makes it conditional (see below). Any other key, or an unknown `type`, is an error — a typo like `default = "8000"` is reported (`did you mean 'defaultValue'?`) instead of silently ignored.
|
|
172
173
|
|
|
173
174
|
### Conditional requirements (`requiredIf`)
|
|
174
175
|
|
|
@@ -210,7 +211,7 @@ Four stages, in order: define the contract, validate against it, discover what c
|
|
|
210
211
|
|
|
211
212
|
### Validate
|
|
212
213
|
|
|
213
|
-
**`envshield check`** — validate local configuration, and commonly-used Docker Compose and Kubernetes deployment-manifest patterns, against the same schema (see [Known limitations](#known-limitations)).
|
|
214
|
+
**`envshield check`** — validate local configuration, and commonly-used Docker Compose and Kubernetes deployment-manifest patterns, against the same schema (see [Known limitations](#known-limitations)). It also scans the service's own source code and fails on a variable the code reads but the schema doesn't declare (the same files the pre-commit `scan` checks). `--process-env` also counts variables set in your shell (for a name the schema declares, the shell's value wins over the file's). `--json` adds a versioned, value-free report per service.
|
|
214
215
|
|
|
215
216
|
```bash
|
|
216
217
|
$ envshield check
|
|
@@ -569,12 +570,15 @@ envshield uninstall --yes # skip the confirmation prompt
|
|
|
569
570
|
|
|
570
571
|
## Known limitations
|
|
571
572
|
|
|
572
|
-
EnvShield is built around the patterns real projects actually use. A few narrower cases aren't handled yet
|
|
573
|
+
EnvShield is built around the patterns real projects actually use. A few narrower cases aren't handled yet. None of them let a secret leak; the first one can let a value EnvShield couldn't see pass `check`:
|
|
573
574
|
|
|
575
|
+
- **Unverified manifest values pass the v4 gate.** When a deployment manifest only *points* at a value — a Kubernetes `secretKeyRef`/`configMapKeyRef` to an object outside the file, a Secret key in the same file, a Compose `${VAR}` or bare `KEY`, or a `${VAR-x}`/`${VAR:-x}` fallback — EnvShield can't see the deployed value. `check` reports these variables as unverified (`valid: null`, status `not_visible`, listed in `summary.unverified`, and named in the human output), but they still pass: exit code and `success` are unchanged. A fallback that itself violates the contract still fails. Making the gate act on unverified values is planned for v5.
|
|
574
576
|
- **Docker Compose:** `${VAR}`, `${VAR:-default}`, and the no-colon `${VAR-default}` form are all supported. The `${VAR:?}`/`${VAR:+}` forms and embedded/multiple interpolation references in one value aren't evaluated yet.
|
|
575
577
|
- **Kubernetes:** `env[].valueFrom.secretKeyRef`/`configMapKeyRef` are matched by the container's environment-variable name (`env[].name`) — name your schema variable after the env var, not the key — and, when the referenced Secret/ConfigMap is defined in the same manifest, the referenced key is validated to actually exist there. `envFrom.prefix` is applied. `initContainers` are selectable via `--container` but never auto-selected by default.
|
|
576
578
|
- **Source discovery:** Python is AST-based; JavaScript/TypeScript is pattern-based. No other language is discovered yet.
|
|
577
579
|
- **.env:** multiline quoted values aren't supported.
|
|
580
|
+
- **Windows:** the write-safety fix for a failed permission change (BL-162) hasn't been run on Windows; where `os.fchmod` is missing (Windows before Python 3.13) it's skipped, which is tested on Linux by simulation only.
|
|
581
|
+
- **CI:** runs on Ubuntu only (Python 3.10–3.12).
|
|
578
582
|
|
|
579
583
|
These are bounded, tracked engineering work — see the [roadmap](ROADMAP.md) for what's next and what EnvShield deliberately isn't building.
|
|
580
584
|
|
|
@@ -106,10 +106,11 @@ What each field actually means:
|
|
|
106
106
|
| `enum` | Value must be one of this list. Implies an enum type regardless of `type`. |
|
|
107
107
|
| `pattern` | A regex the value must also match, e.g. `pattern = "^v\\d+\\.\\d+\\.\\d+$"`. |
|
|
108
108
|
| `secret` | Marks the variable sensitive — masked input in `setup`, masked in generated code. `import` auto-suggests it from the variable's name/value; it never overwrites a `secret` value you've already committed. |
|
|
109
|
-
| `defaultValue` | What `setup` writes automatically. A variable still has to be explicitly present in your local file
|
|
109
|
+
| `defaultValue` | What `setup` writes automatically (and `.env.example` and generated code show). A default never makes a variable optional: it still has to be explicitly present in your local file — `check`/`doctor` name the default inline so a missing one is obvious. |
|
|
110
|
+
| `required` | Optional. `required = false` makes a variable optional: it may be absent or blank, but a value that is set must still be valid. `required = true` is the default. Can't be combined with `requiredIf`. |
|
|
110
111
|
| `description` | Shown in `setup`, copied into generated code. |
|
|
111
112
|
|
|
112
|
-
|
|
113
|
+
Requiredness: every variable is required unless `required = false`, or `requiredIf` makes it conditional (see below). Any other key, or an unknown `type`, is an error — a typo like `default = "8000"` is reported (`did you mean 'defaultValue'?`) instead of silently ignored.
|
|
113
114
|
|
|
114
115
|
### Conditional requirements (`requiredIf`)
|
|
115
116
|
|
|
@@ -151,7 +152,7 @@ Four stages, in order: define the contract, validate against it, discover what c
|
|
|
151
152
|
|
|
152
153
|
### Validate
|
|
153
154
|
|
|
154
|
-
**`envshield check`** — validate local configuration, and commonly-used Docker Compose and Kubernetes deployment-manifest patterns, against the same schema (see [Known limitations](#known-limitations)).
|
|
155
|
+
**`envshield check`** — validate local configuration, and commonly-used Docker Compose and Kubernetes deployment-manifest patterns, against the same schema (see [Known limitations](#known-limitations)). It also scans the service's own source code and fails on a variable the code reads but the schema doesn't declare (the same files the pre-commit `scan` checks). `--process-env` also counts variables set in your shell (for a name the schema declares, the shell's value wins over the file's). `--json` adds a versioned, value-free report per service.
|
|
155
156
|
|
|
156
157
|
```bash
|
|
157
158
|
$ envshield check
|
|
@@ -510,12 +511,15 @@ envshield uninstall --yes # skip the confirmation prompt
|
|
|
510
511
|
|
|
511
512
|
## Known limitations
|
|
512
513
|
|
|
513
|
-
EnvShield is built around the patterns real projects actually use. A few narrower cases aren't handled yet
|
|
514
|
+
EnvShield is built around the patterns real projects actually use. A few narrower cases aren't handled yet. None of them let a secret leak; the first one can let a value EnvShield couldn't see pass `check`:
|
|
514
515
|
|
|
516
|
+
- **Unverified manifest values pass the v4 gate.** When a deployment manifest only *points* at a value — a Kubernetes `secretKeyRef`/`configMapKeyRef` to an object outside the file, a Secret key in the same file, a Compose `${VAR}` or bare `KEY`, or a `${VAR-x}`/`${VAR:-x}` fallback — EnvShield can't see the deployed value. `check` reports these variables as unverified (`valid: null`, status `not_visible`, listed in `summary.unverified`, and named in the human output), but they still pass: exit code and `success` are unchanged. A fallback that itself violates the contract still fails. Making the gate act on unverified values is planned for v5.
|
|
515
517
|
- **Docker Compose:** `${VAR}`, `${VAR:-default}`, and the no-colon `${VAR-default}` form are all supported. The `${VAR:?}`/`${VAR:+}` forms and embedded/multiple interpolation references in one value aren't evaluated yet.
|
|
516
518
|
- **Kubernetes:** `env[].valueFrom.secretKeyRef`/`configMapKeyRef` are matched by the container's environment-variable name (`env[].name`) — name your schema variable after the env var, not the key — and, when the referenced Secret/ConfigMap is defined in the same manifest, the referenced key is validated to actually exist there. `envFrom.prefix` is applied. `initContainers` are selectable via `--container` but never auto-selected by default.
|
|
517
519
|
- **Source discovery:** Python is AST-based; JavaScript/TypeScript is pattern-based. No other language is discovered yet.
|
|
518
520
|
- **.env:** multiline quoted values aren't supported.
|
|
521
|
+
- **Windows:** the write-safety fix for a failed permission change (BL-162) hasn't been run on Windows; where `os.fchmod` is missing (Windows before Python 3.13) it's skipped, which is tested on Linux by simulation only.
|
|
522
|
+
- **CI:** runs on Ubuntu only (Python 3.10–3.12).
|
|
519
523
|
|
|
520
524
|
These are bounded, tracked engineering work — see the [roadmap](ROADMAP.md) for what's next and what EnvShield deliberately isn't building.
|
|
521
525
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "4.8.0"
|