envstack 0.6.4__tar.gz → 0.7.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.
- envstack-0.7.0/PKG-INFO +432 -0
- envstack-0.7.0/README.md +409 -0
- envstack-0.7.0/dist.json +45 -0
- {envstack-0.6.4 → envstack-0.7.0}/lib/envstack/__init__.py +2 -2
- {envstack-0.6.4 → envstack-0.7.0}/lib/envstack/cli.py +29 -17
- {envstack-0.6.4 → envstack-0.7.0}/lib/envstack/config.py +13 -14
- {envstack-0.6.4 → envstack-0.7.0}/lib/envstack/env.py +194 -413
- envstack-0.7.0/lib/envstack/util.py +301 -0
- {envstack-0.6.4 → envstack-0.7.0}/lib/envstack/wrapper.py +14 -12
- envstack-0.7.0/lib/envstack.egg-info/PKG-INFO +432 -0
- {envstack-0.6.4 → envstack-0.7.0}/lib/envstack.egg-info/SOURCES.txt +2 -3
- {envstack-0.6.4 → envstack-0.7.0}/setup.py +1 -37
- envstack-0.7.0/tests/test_cmds.py +211 -0
- envstack-0.7.0/tests/test_env.py +236 -0
- envstack-0.7.0/tests/test_util.py +171 -0
- envstack-0.6.4/PKG-INFO +0 -336
- envstack-0.6.4/README.md +0 -313
- envstack-0.6.4/dev.env +0 -23
- envstack-0.6.4/dist.json +0 -29
- envstack-0.6.4/lib/envstack/util.py +0 -106
- envstack-0.6.4/lib/envstack.egg-info/PKG-INFO +0 -336
- envstack-0.6.4/stack.env +0 -34
- envstack-0.6.4/tests/test_env.py +0 -626
- envstack-0.6.4/tests/test_path.py +0 -36
- {envstack-0.6.4 → envstack-0.7.0}/LICENSE +0 -0
- {envstack-0.6.4 → envstack-0.7.0}/lib/envstack/exceptions.py +0 -0
- {envstack-0.6.4 → envstack-0.7.0}/lib/envstack/logger.py +0 -0
- {envstack-0.6.4 → envstack-0.7.0}/lib/envstack/path.py +0 -0
- {envstack-0.6.4 → envstack-0.7.0}/lib/envstack.egg-info/dependency_links.txt +0 -0
- {envstack-0.6.4 → envstack-0.7.0}/lib/envstack.egg-info/entry_points.txt +0 -0
- {envstack-0.6.4 → envstack-0.7.0}/lib/envstack.egg-info/not-zip-safe +0 -0
- {envstack-0.6.4 → envstack-0.7.0}/lib/envstack.egg-info/requires.txt +0 -0
- {envstack-0.6.4 → envstack-0.7.0}/lib/envstack.egg-info/top_level.txt +0 -0
- {envstack-0.6.4 → envstack-0.7.0}/setup.cfg +0 -0
envstack-0.7.0/PKG-INFO
ADDED
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: envstack
|
|
3
|
+
Version: 0.7.0
|
|
4
|
+
Summary: Stacked environment variable management system
|
|
5
|
+
Home-page: http://github.com/rsgalloway/envstack
|
|
6
|
+
Author: Ryan Galloway
|
|
7
|
+
Author-email: ryan@rsgalloway.com
|
|
8
|
+
License: BSD 3-Clause License
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.6
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Requires-Python: >=3.6
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: PyYAML==5.1.2
|
|
23
|
+
|
|
24
|
+
envstack
|
|
25
|
+
========
|
|
26
|
+
|
|
27
|
+
Environment variable management system.
|
|
28
|
+
|
|
29
|
+
| Feature | Description |
|
|
30
|
+
|---------|-------------|
|
|
31
|
+
| Environment stacks | Allows you to manage environment variables using .env files called environment stacks. These stacks provide a hierarchical and contextual approach to managing variables. |
|
|
32
|
+
| Hierarchical structure | Stacks can be combined and have a defined order of priority. Variables defined in higher scope stacks flow from higher scope to lower scope, left to right. |
|
|
33
|
+
| Variable expansion modifiers | Supports bash-like variable expansion modifiers, allowing you to set default values for variables and override them in the environment or by higher scope stacks. |
|
|
34
|
+
| Platform-specific variables | Stacks can have platform-specific variables and values. This allows you to define different values for variables based on the platform. |
|
|
35
|
+
| Variable references | Variables can reference other variables, allowing for more flexibility and dynamic value assignment. |
|
|
36
|
+
| Includes | Stack files can include other stacks, making it easy to reuse and combine different stacks. |
|
|
37
|
+
| Python API | Provides a Python API that allows you to initialize and work with environment stacks programmatically. Easily initialize pre-defined environments with Python scripts, tools, and wrappers. |
|
|
38
|
+
| Running commands | Allows you to run command line executables inside an environment stack, providing a convenient way to execute commands with a pre-defined environment. |
|
|
39
|
+
| Wrappers | Supports wrappers, which are command line executable scripts that automatically run a given command in the environment stack. This allows for easy customization and management of environments. |
|
|
40
|
+
| Shell integration | Provides instructions for sourcing the environment stack in your current shell, allowing you to set and clear the environment easily. |
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
43
|
+
|
|
44
|
+
The easiest way to install:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
$ pip install -U envstack
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Alternatively,
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
$ git clone https://github.com/rsgalloway/envstack
|
|
54
|
+
$ cd envstack
|
|
55
|
+
$ python setup.py install
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
#### distman
|
|
59
|
+
|
|
60
|
+
If installing from source to a network location, you can use
|
|
61
|
+
[distman](https://github.com/rsgalloway/distman) to
|
|
62
|
+
install envstack using the provided `dist.json` file:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
$ ENVPATH=./env distman [-d]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Using distman will deploy the targets defined in the `dist.json` file to the
|
|
69
|
+
root folder defined by `${DEPLOY_ROOT}` (defined in `env/default.env`).
|
|
70
|
+
|
|
71
|
+
## Quickstart
|
|
72
|
+
|
|
73
|
+
Envstack looks for .env files in directories specified by `${ENVPATH}` and in
|
|
74
|
+
the current working directory. Get the latest `default.env` stack file:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
$ wget -O default.env \
|
|
78
|
+
https://raw.githubusercontent.com/rsgalloway/envstack/master/env/default.env
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Set `$ENVPATH` to the directory containing your environment stack files:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
$ export ENVPATH=/path/to/env/stack/files
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Define as many paths as you want, and envstack will search for stack file in
|
|
88
|
+
order from left to right, for example:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
$ export ENVPATH=/mnt/pipe/dev/env:/mnt/pipe/prod/env
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
In the case above, stack files in `/mnt/pipe/dev/env` will take precedence over those
|
|
95
|
+
found in `/mnt/pipe/prod/env`.
|
|
96
|
+
|
|
97
|
+
#### Basic Usage
|
|
98
|
+
|
|
99
|
+
Running the `envstack` command will show you the default environment stack,
|
|
100
|
+
defined in the `default.env` stack file:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
$ envstack
|
|
104
|
+
DEPLOY_ROOT=${ROOT}/${ENV}
|
|
105
|
+
ENV=prod
|
|
106
|
+
ENVPATH=${DEPLOY_ROOT}/env:${ENVPATH}
|
|
107
|
+
HELLO=${HELLO:=world}
|
|
108
|
+
LOG_LEVEL=${LOG_LEVEL:=INFO}
|
|
109
|
+
PATH=${DEPLOY_ROOT}/bin:${PATH}
|
|
110
|
+
PYTHONPATH=${DEPLOY_ROOT}/lib/python:${PYTHONPATH}
|
|
111
|
+
ROOT=/mnt/pipe
|
|
112
|
+
STACK=default
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Note:** The name of the current stack will always be stored in `${STACK}`.
|
|
116
|
+
|
|
117
|
+
To see stacks, pass the stack name as the first arg. Environment stacks can be
|
|
118
|
+
combined, in order of priority (variables defined in stacks flow from higher
|
|
119
|
+
scope to lower scope, left to right):
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
$ envstack [STACK [STACK ...]]
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Setting Values
|
|
126
|
+
|
|
127
|
+
Envstack uses bash-like variable expansion modifiers. Setting `$VAR` to a fixed
|
|
128
|
+
value means `$VAR` will always use that value. Using an expansion modifier
|
|
129
|
+
allows you to override the value:
|
|
130
|
+
|
|
131
|
+
| Value | Description |
|
|
132
|
+
|---------------------|-------------|
|
|
133
|
+
| value | 'value' |
|
|
134
|
+
| ${VAR:-default} | os.environ.get('VAR', 'default') |
|
|
135
|
+
| ${VAR:=default} | VAR = VAR or 'default' |
|
|
136
|
+
| ${VAR:?error message} | if not VAR: raise ValueError() |
|
|
137
|
+
|
|
138
|
+
Without the expansion modifier, values are set and do not change (but can be
|
|
139
|
+
overridden by lower scope stacks, i.e. a lower scope stack file may override
|
|
140
|
+
a higher one).
|
|
141
|
+
|
|
142
|
+
If we define `$HELLO` like this:
|
|
143
|
+
|
|
144
|
+
```yaml
|
|
145
|
+
HELLO: world
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Then the value is set and cannot be modified (except by lower scope stacks):
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
$ envstack -- echo {HELLO}
|
|
152
|
+
world
|
|
153
|
+
$ HELLO=goodbye envstack -- echo {HELLO}
|
|
154
|
+
world
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
With an expansion modifier, variables have a default value and can also be
|
|
158
|
+
overridden in the environment, or by higher scope stacks:
|
|
159
|
+
|
|
160
|
+
```yaml
|
|
161
|
+
HELLO: ${HELLO:=world}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Here we show the default value, and how we can override it in the environment:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
$ envstack -- echo {HELLO}
|
|
168
|
+
world
|
|
169
|
+
$ HELLO=goodbye envstack -- echo {HELLO}
|
|
170
|
+
goodbye
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Creating Stacks
|
|
174
|
+
|
|
175
|
+
Several example or starter stacks are available in the [env folder of the
|
|
176
|
+
envstack repo](https://github.com/rsgalloway/envstack/tree/master/env).
|
|
177
|
+
|
|
178
|
+
To create a blank environment stack, create a new namespaced .env file and
|
|
179
|
+
declare some variables.
|
|
180
|
+
|
|
181
|
+
For example `foo.env` (the stack name is "foo"):
|
|
182
|
+
|
|
183
|
+
```yaml
|
|
184
|
+
all: &default
|
|
185
|
+
FOO: bar
|
|
186
|
+
BAR: ${FOO}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
To see the resolved environment for the `foo` environment stack, run:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
$ envstack foo
|
|
193
|
+
FOO=bar
|
|
194
|
+
BAR=$FOO
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
To see resolved values:
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
$ envstack foo -r
|
|
201
|
+
FOO=bar
|
|
202
|
+
BAR=bar
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Variables can be platform specific (but always inherit from `all`):
|
|
206
|
+
|
|
207
|
+
```yaml
|
|
208
|
+
linux:
|
|
209
|
+
<<: *default
|
|
210
|
+
HELLO: world
|
|
211
|
+
|
|
212
|
+
windows:
|
|
213
|
+
<<: *default
|
|
214
|
+
HELLO: goodbye
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Variables can reference other variables:
|
|
218
|
+
|
|
219
|
+
```yaml
|
|
220
|
+
all: &default
|
|
221
|
+
FOO: ${BAR}
|
|
222
|
+
BAR: ${BAZ}
|
|
223
|
+
BAZ: ${BIZ}
|
|
224
|
+
BIZ: ${BIZ:=foo}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
As you might expect, the above resolves to:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
$ envstack -r
|
|
231
|
+
BAR=foo
|
|
232
|
+
BAZ=foo
|
|
233
|
+
BIZ=foo
|
|
234
|
+
FOO=foo
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
#### Includes
|
|
238
|
+
|
|
239
|
+
Environment stack files can include other namespaced environments (you should
|
|
240
|
+
probably always include the `default` stack):
|
|
241
|
+
|
|
242
|
+
```yaml
|
|
243
|
+
include: [default, test]
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Usage
|
|
247
|
+
|
|
248
|
+
To see the unresolved environment for one or more environment stacks (values are
|
|
249
|
+
defined in the stacks from left to right):
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
$ envstack [STACK [STACK ...]]
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
To resolve one or more environment vars for a given stack:
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
$ envstack [STACK] -r [VAR [VAR ...]]
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
To trace where one or more environment vars is being set:
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
$ envstack [STACK] -t [VAR [VAR ...]]
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
To get the list of source files for a given stack:
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
$ envstack [STACK] --sources
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## Python API
|
|
274
|
+
|
|
275
|
+
To initialize the environment stack in Python, use the `init` function:
|
|
276
|
+
|
|
277
|
+
```python
|
|
278
|
+
>>> envstack.init()
|
|
279
|
+
>>> os.getenv("HELLO")
|
|
280
|
+
'world'
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
To initialize the "dev" stack:
|
|
284
|
+
|
|
285
|
+
```python
|
|
286
|
+
>>> envstack.init("dev")
|
|
287
|
+
>>> os.getenv("ENV")
|
|
288
|
+
'dev'
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
To revert the original environment:
|
|
292
|
+
|
|
293
|
+
```python
|
|
294
|
+
>>> envstack.revert()
|
|
295
|
+
>>> os.getenv("HELLO")
|
|
296
|
+
>>>
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Creating and resolving environments:
|
|
300
|
+
|
|
301
|
+
```python
|
|
302
|
+
>>> from envstack.env import Env, resolve_environ
|
|
303
|
+
>>> env = Env({"BAR": "${FOO}", "FOO": "foo"})
|
|
304
|
+
>>> resolve_environ(env)
|
|
305
|
+
{'BAR': 'foo', 'FOO': 'foo'}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Loading and resolving predefined environments from stack files:
|
|
309
|
+
|
|
310
|
+
```python
|
|
311
|
+
>>> from envstack.env import load_environ, resolve_environ
|
|
312
|
+
>>> env = resolve_environ(load_environ("prod"))
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
## Running Commands
|
|
316
|
+
|
|
317
|
+
To run any command line executable inside of an environment stack, where
|
|
318
|
+
`[COMMAND]` is the command to run:
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
$ envstack [STACK] -- [COMMAND]
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
For example:
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
$ envstack -- echo {HELLO}
|
|
328
|
+
world
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Running Python commands in the default stack:
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
$ envstack -- python -c "import os; print(os.environ['HELLO'])"
|
|
335
|
+
world
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
Overriding values in the stack:
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
$ HELLO=goodbye envstack -- python -c "import os; print(os.environ['HELLO'])"
|
|
342
|
+
goodbye
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
Same command but using the "thing" stack"
|
|
346
|
+
|
|
347
|
+
```bash
|
|
348
|
+
$ envstack thing -- python -c "import os; print(os.environ['FOO'])"
|
|
349
|
+
bar
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
## Wrappers
|
|
353
|
+
|
|
354
|
+
Wrappers are command line executable scripts that automatically run a given
|
|
355
|
+
command in the environment stack.
|
|
356
|
+
|
|
357
|
+
Here is a simple example that runs a `python -c` command in the `hello`
|
|
358
|
+
environment stack that sets a value for `${PYEXE}`:
|
|
359
|
+
|
|
360
|
+
#### hello.env
|
|
361
|
+
```yaml
|
|
362
|
+
all: &default
|
|
363
|
+
PYEXE: python
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
#### bin/hello
|
|
367
|
+
```python
|
|
368
|
+
import sys
|
|
369
|
+
from envstack.wrapper import Wrapper
|
|
370
|
+
|
|
371
|
+
class HelloWrapper(Wrapper):
|
|
372
|
+
def __init__(self, *args, **kwargs):
|
|
373
|
+
super(HelloWrapper, self).__init__(*args, **kwargs)
|
|
374
|
+
|
|
375
|
+
def executable(self):
|
|
376
|
+
"""Return the command to run."""
|
|
377
|
+
return "${PYEXE} -c 'import os,sys;print(os.getenv(sys.argv[1]))'"
|
|
378
|
+
|
|
379
|
+
if __name__ == "__main__":
|
|
380
|
+
hello = HelloWrapper("hello", sys.argv[1:])
|
|
381
|
+
hello.launch()
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
Running the wrapper:
|
|
385
|
+
|
|
386
|
+
```bash
|
|
387
|
+
$ hello HELLO
|
|
388
|
+
world
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
## Shells
|
|
392
|
+
|
|
393
|
+
In order to set an environment stack in your current shell, the stack must be
|
|
394
|
+
sourced (that's because Python processes and subshells cannot alter the
|
|
395
|
+
environment of the parent process).
|
|
396
|
+
|
|
397
|
+
To source the environment in your current shell, create an alias that sources
|
|
398
|
+
the output of the `--export` command:
|
|
399
|
+
|
|
400
|
+
#### bash
|
|
401
|
+
```bash
|
|
402
|
+
alias envstack-init='source <(envstack --export)';
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
#### cmd
|
|
406
|
+
```cmd
|
|
407
|
+
doskey envstack-set=for /f "usebackq" %i in (`envstack --export $*`) do %%i
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
Then you can set the environment stack in your shell with the `envstack-init`
|
|
411
|
+
command. To clear the environment in your current shell, create an alias that
|
|
412
|
+
sources the output of the `--clear` command:
|
|
413
|
+
|
|
414
|
+
#### bash
|
|
415
|
+
```bash
|
|
416
|
+
alias envstack-clear='source <(envstack --clear)';
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
#### cmd
|
|
420
|
+
```cmd
|
|
421
|
+
doskey envstack-clear=for /f "usebackq" %i in (`envstack --clear $*`) do %%i
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
## Config
|
|
425
|
+
|
|
426
|
+
The following environment variables are used to help manage functionality:
|
|
427
|
+
|
|
428
|
+
| Name | Description |
|
|
429
|
+
|------|-------------|
|
|
430
|
+
| ENVPATH | Colon-separated paths to search for stack files |
|
|
431
|
+
| IGNORE_MISSING | Ignore missing stack files when resolving environments |
|
|
432
|
+
| STACK | Name of the current stack |
|