envstack 0.4.2__tar.gz → 0.5.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.4.2 → envstack-0.5.0}/PKG-INFO +74 -63
- {envstack-0.4.2 → envstack-0.5.0}/README.md +73 -61
- {envstack-0.4.2 → envstack-0.5.0}/lib/envstack/__init__.py +3 -2
- {envstack-0.4.2 → envstack-0.5.0}/lib/envstack/cli.py +26 -21
- {envstack-0.4.2 → envstack-0.5.0}/lib/envstack/config.py +17 -7
- {envstack-0.4.2 → envstack-0.5.0}/lib/envstack/env.py +16 -11
- {envstack-0.4.2 → envstack-0.5.0}/lib/envstack/logger.py +11 -1
- {envstack-0.4.2 → envstack-0.5.0}/lib/envstack/wrapper.py +31 -15
- {envstack-0.4.2 → envstack-0.5.0}/lib/envstack.egg-info/PKG-INFO +74 -63
- {envstack-0.4.2 → envstack-0.5.0}/lib/envstack.egg-info/SOURCES.txt +3 -1
- envstack-0.5.0/lib/envstack.egg-info/requires.txt +1 -0
- {envstack-0.4.2 → envstack-0.5.0}/setup.py +6 -4
- envstack-0.5.0/stack.env +29 -0
- envstack-0.5.0/tests/test_env.py +626 -0
- envstack-0.5.0/tests/test_path.py +36 -0
- envstack-0.4.2/lib/envstack.egg-info/requires.txt +0 -2
- envstack-0.4.2/stack.env +0 -25
- {envstack-0.4.2 → envstack-0.5.0}/lib/envstack/exceptions.py +0 -0
- {envstack-0.4.2 → envstack-0.5.0}/lib/envstack/path.py +0 -0
- {envstack-0.4.2 → envstack-0.5.0}/lib/envstack.egg-info/dependency_links.txt +0 -0
- {envstack-0.4.2 → envstack-0.5.0}/lib/envstack.egg-info/entry_points.txt +0 -0
- {envstack-0.4.2 → envstack-0.5.0}/lib/envstack.egg-info/not-zip-safe +0 -0
- {envstack-0.4.2 → envstack-0.5.0}/lib/envstack.egg-info/top_level.txt +0 -0
- {envstack-0.4.2 → envstack-0.5.0}/setup.cfg +0 -0
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: envstack
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Stacked environment variable management system.
|
|
5
5
|
Home-page: http://github.com/rsgalloway/envstack
|
|
6
6
|
Author: Ryan Galloway
|
|
7
7
|
Author-email: ryan@rsgalloway.com
|
|
8
8
|
Description-Content-Type: text/markdown
|
|
9
9
|
Requires-Dist: PyYAML>=5.1.2
|
|
10
|
-
Requires-Dist: siteconf>=0.1.7
|
|
11
10
|
|
|
12
11
|
envstack
|
|
13
12
|
========
|
|
@@ -16,11 +15,9 @@ Stacked environment variable management system. The lightweight, easy to use
|
|
|
16
15
|
"rez" alternative for production pipelines.
|
|
17
16
|
|
|
18
17
|
Environment variables are declared in namespaced .env files using yaml syntax.
|
|
19
|
-
The default stack
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
> **Note:** envstack works best combined with [siteconf](https://github.com/rsgalloway/siteconf).
|
|
18
|
+
The default stack declares env variables in `stack.env` files. You can create any
|
|
19
|
+
new stack by creating new `.env` files, e.g. to create a new `thing` stack just
|
|
20
|
+
create `thing.env` files in any given context.
|
|
24
21
|
|
|
25
22
|
## Installation
|
|
26
23
|
|
|
@@ -30,47 +27,66 @@ The easiest way to install:
|
|
|
30
27
|
$ pip install envstack
|
|
31
28
|
```
|
|
32
29
|
|
|
33
|
-
|
|
30
|
+
Alternatively,
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
$ git clone https://github.com/rsgalloway/envstack
|
|
34
|
+
$ cd envstack
|
|
35
|
+
$ python setup.py install
|
|
36
|
+
```
|
|
34
37
|
|
|
35
|
-
|
|
36
|
-
[
|
|
37
|
-
to your current working directory, the root of your project or $DEFAULT_ENV_DIR if defined (defaults: /etc/envstack on posix platforms and C:/ProgramData/envstack on Windows).
|
|
38
|
+
The install process will automatically attempt to install the default `stack.env` file to the
|
|
39
|
+
default env file directory defined `$DEFAULT_ENV_DIR`. **Note:** The [siteconf](https://github.com/rsgalloway/siteconf) sitecustomize.py module may override `$DEFAULT_ENV_DIR`.
|
|
38
40
|
|
|
41
|
+
If installing from source, you can use [distman](https://github.com/rsgalloway/distman) to
|
|
42
|
+
install envstack and the default `stack.env` file using the provided `dist.json` file:
|
|
39
43
|
|
|
40
|
-
```
|
|
41
|
-
$
|
|
44
|
+
```bash
|
|
45
|
+
$ distman
|
|
42
46
|
```
|
|
43
47
|
|
|
48
|
+
## Quickstart
|
|
49
|
+
|
|
44
50
|
The `stack` namespace is the default environment stack. Running the `envstack` command
|
|
45
|
-
should show you the
|
|
51
|
+
should show you the default environment stack:
|
|
46
52
|
|
|
47
53
|
```bash
|
|
48
54
|
$ envstack
|
|
49
|
-
ENV
|
|
50
|
-
HELLO
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
ROOT '/mnt/tools/lib/python3.11'
|
|
55
|
+
ENV=prod
|
|
56
|
+
HELLO=world
|
|
57
|
+
LOG_LEVEL=INFO
|
|
58
|
+
DEFAULT_ENV_DIR=${DEPLOY_ROOT}/env
|
|
59
|
+
DEPLOY_ROOT=${ROOT}/${ENV}
|
|
60
|
+
ROOT=${HOME}/.local/envstack
|
|
56
61
|
```
|
|
57
62
|
|
|
58
|
-
Modify the environment stack by
|
|
59
|
-
`stack.env` files up
|
|
63
|
+
Modify the environment stack by editing `stack.env` or by creating new contextual
|
|
64
|
+
`stack.env` files up on the filesystem.
|
|
60
65
|
|
|
61
66
|
You can execute any command inside the default stacked environment like this:
|
|
62
67
|
|
|
63
68
|
```bash
|
|
64
|
-
$ envstack --
|
|
69
|
+
$ envstack -- [COMMAND]
|
|
65
70
|
```
|
|
66
71
|
|
|
67
|
-
For example:
|
|
72
|
+
For example, use the `echo` command to see the resolved value of `$HELLO` (note: we
|
|
73
|
+
have to escape it first to it's not pre-expanded in the shell):
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
$ envstack -- echo \$HELLO
|
|
77
|
+
world
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Any command can be run in an envstack environment by preceeding the command
|
|
81
|
+
with `--`:
|
|
68
82
|
|
|
69
83
|
```bash
|
|
70
84
|
$ envstack -- python -c "import os; print(os.environ['HELLO'])"
|
|
71
85
|
world
|
|
72
86
|
```
|
|
73
87
|
|
|
88
|
+
## Creating Stacks
|
|
89
|
+
|
|
74
90
|
To create a new environment stack, create a new namespaced .env file.
|
|
75
91
|
For example `thing.env` (the stack namespace is "thing"):
|
|
76
92
|
|
|
@@ -86,16 +102,6 @@ $ envstack thing
|
|
|
86
102
|
FOO 'bar'
|
|
87
103
|
```
|
|
88
104
|
|
|
89
|
-
Environment stacks are hierarchical, so values for `$FOO` defined in .env files lower
|
|
90
|
-
in the filesystem (lower in scope) override those defined higher up (higher in scope):
|
|
91
|
-
|
|
92
|
-
```
|
|
93
|
-
/show/thing.env
|
|
94
|
-
/show/seq/thing.env
|
|
95
|
-
/show/seq/shot/thing.env
|
|
96
|
-
/show/seq/shot/task/thing.env
|
|
97
|
-
```
|
|
98
|
-
|
|
99
105
|
Variables can reference other variables defined elsewhere (but cannot be circular):
|
|
100
106
|
|
|
101
107
|
```yaml
|
|
@@ -117,71 +123,76 @@ Environment files can include other namespaced environments (all stacks inherit
|
|
|
117
123
|
include: ['other']
|
|
118
124
|
```
|
|
119
125
|
|
|
120
|
-
##
|
|
126
|
+
## Context
|
|
121
127
|
|
|
122
|
-
|
|
128
|
+
Environment stacks are hierarchical, so values for `$FOO` defined in .env files lower
|
|
129
|
+
in the filesystem (lower in scope) override those defined higher up (higher in scope):
|
|
123
130
|
|
|
124
|
-
```
|
|
125
|
-
$
|
|
131
|
+
```
|
|
132
|
+
${DEFAULT_ENV_DIR}
|
|
133
|
+
/stack.env
|
|
134
|
+
/show/stack.env
|
|
135
|
+
/show/seq/stack.env
|
|
136
|
+
/show/seq/shot/stack.env
|
|
137
|
+
/show/seq/shot/task/stack.env
|
|
126
138
|
```
|
|
127
139
|
|
|
128
|
-
|
|
140
|
+
If you are working in the task directory, those envstack $VARs will override the
|
|
141
|
+
$VARs defined in the shot, seq, show and root directories.
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
## Usage
|
|
145
|
+
|
|
146
|
+
To see the default environment for any given stack:
|
|
129
147
|
|
|
130
148
|
```bash
|
|
131
|
-
$ envstack
|
|
149
|
+
$ envstack [STACK]
|
|
132
150
|
```
|
|
133
151
|
|
|
134
|
-
To resolve
|
|
152
|
+
To resolve one or more environment vars for a given stack:
|
|
135
153
|
|
|
136
154
|
```bash
|
|
137
|
-
$ envstack
|
|
155
|
+
$ envstack [STACK] -r [VAR [VAR ...]]
|
|
138
156
|
```
|
|
139
157
|
|
|
140
|
-
To trace where
|
|
158
|
+
To trace where one or more environment vars is being set:
|
|
141
159
|
|
|
142
160
|
```bash
|
|
143
|
-
$ envstack
|
|
161
|
+
$ envstack [STACK] -t [VAR [VAR ...]]
|
|
144
162
|
```
|
|
145
163
|
|
|
146
|
-
To
|
|
164
|
+
To get the list of source files for a given stack:
|
|
147
165
|
|
|
148
166
|
```bash
|
|
149
|
-
$ envstack
|
|
167
|
+
$ envstack [STACK] --sources
|
|
150
168
|
```
|
|
151
169
|
|
|
152
170
|
## Python API
|
|
153
171
|
|
|
154
|
-
|
|
155
|
-
a drop-in replacement for `os.getenv`
|
|
156
|
-
|
|
157
|
-
```python
|
|
158
|
-
>>> import envstack
|
|
159
|
-
>>> envstack.getenv("HELLO")
|
|
160
|
-
'world'
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
To use a different stack, use the `init` function:
|
|
172
|
+
To init the environment stack, use the `init` function:
|
|
164
173
|
|
|
165
174
|
```python
|
|
166
175
|
>>> envstack.init("thing")
|
|
167
|
-
>>>
|
|
176
|
+
>>> os.getenv("FOO")
|
|
168
177
|
'bar'
|
|
169
178
|
```
|
|
170
179
|
|
|
171
|
-
|
|
180
|
+
Alternatively, `envstack.getenv` uses the default environment stack `stack` and can be
|
|
181
|
+
a drop-in replacement for `os.getenv`
|
|
172
182
|
|
|
173
183
|
```python
|
|
174
|
-
>>>
|
|
175
|
-
|
|
184
|
+
>>> import envstack
|
|
185
|
+
>>> envstack.getenv("HELLO")
|
|
186
|
+
'world'
|
|
176
187
|
```
|
|
177
188
|
|
|
178
189
|
## Running Commands
|
|
179
190
|
|
|
180
|
-
To run any command line executable inside of an environment stack, where
|
|
191
|
+
To run any command line executable inside of an environment stack, where `[COMMAND]`
|
|
181
192
|
is the command to run:
|
|
182
193
|
|
|
183
194
|
```bash
|
|
184
|
-
$ envstack
|
|
195
|
+
$ envstack [STACK] -- [COMMAND]
|
|
185
196
|
```
|
|
186
197
|
|
|
187
198
|
For example, running python in the default stack (reading from the default `stack.env` file):
|
|
@@ -5,11 +5,9 @@ Stacked environment variable management system. The lightweight, easy to use
|
|
|
5
5
|
"rez" alternative for production pipelines.
|
|
6
6
|
|
|
7
7
|
Environment variables are declared in namespaced .env files using yaml syntax.
|
|
8
|
-
The default stack
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
> **Note:** envstack works best combined with [siteconf](https://github.com/rsgalloway/siteconf).
|
|
8
|
+
The default stack declares env variables in `stack.env` files. You can create any
|
|
9
|
+
new stack by creating new `.env` files, e.g. to create a new `thing` stack just
|
|
10
|
+
create `thing.env` files in any given context.
|
|
13
11
|
|
|
14
12
|
## Installation
|
|
15
13
|
|
|
@@ -19,47 +17,66 @@ The easiest way to install:
|
|
|
19
17
|
$ pip install envstack
|
|
20
18
|
```
|
|
21
19
|
|
|
22
|
-
|
|
20
|
+
Alternatively,
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
$ git clone https://github.com/rsgalloway/envstack
|
|
24
|
+
$ cd envstack
|
|
25
|
+
$ python setup.py install
|
|
26
|
+
```
|
|
23
27
|
|
|
24
|
-
|
|
25
|
-
[
|
|
26
|
-
to your current working directory, the root of your project or $DEFAULT_ENV_DIR if defined (defaults: /etc/envstack on posix platforms and C:/ProgramData/envstack on Windows).
|
|
28
|
+
The install process will automatically attempt to install the default `stack.env` file to the
|
|
29
|
+
default env file directory defined `$DEFAULT_ENV_DIR`. **Note:** The [siteconf](https://github.com/rsgalloway/siteconf) sitecustomize.py module may override `$DEFAULT_ENV_DIR`.
|
|
27
30
|
|
|
31
|
+
If installing from source, you can use [distman](https://github.com/rsgalloway/distman) to
|
|
32
|
+
install envstack and the default `stack.env` file using the provided `dist.json` file:
|
|
28
33
|
|
|
29
|
-
```
|
|
30
|
-
$
|
|
34
|
+
```bash
|
|
35
|
+
$ distman
|
|
31
36
|
```
|
|
32
37
|
|
|
38
|
+
## Quickstart
|
|
39
|
+
|
|
33
40
|
The `stack` namespace is the default environment stack. Running the `envstack` command
|
|
34
|
-
should show you the
|
|
41
|
+
should show you the default environment stack:
|
|
35
42
|
|
|
36
43
|
```bash
|
|
37
44
|
$ envstack
|
|
38
|
-
ENV
|
|
39
|
-
HELLO
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
ROOT '/mnt/tools/lib/python3.11'
|
|
45
|
+
ENV=prod
|
|
46
|
+
HELLO=world
|
|
47
|
+
LOG_LEVEL=INFO
|
|
48
|
+
DEFAULT_ENV_DIR=${DEPLOY_ROOT}/env
|
|
49
|
+
DEPLOY_ROOT=${ROOT}/${ENV}
|
|
50
|
+
ROOT=${HOME}/.local/envstack
|
|
45
51
|
```
|
|
46
52
|
|
|
47
|
-
Modify the environment stack by
|
|
48
|
-
`stack.env` files up
|
|
53
|
+
Modify the environment stack by editing `stack.env` or by creating new contextual
|
|
54
|
+
`stack.env` files up on the filesystem.
|
|
49
55
|
|
|
50
56
|
You can execute any command inside the default stacked environment like this:
|
|
51
57
|
|
|
52
58
|
```bash
|
|
53
|
-
$ envstack --
|
|
59
|
+
$ envstack -- [COMMAND]
|
|
54
60
|
```
|
|
55
61
|
|
|
56
|
-
For example:
|
|
62
|
+
For example, use the `echo` command to see the resolved value of `$HELLO` (note: we
|
|
63
|
+
have to escape it first to it's not pre-expanded in the shell):
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
$ envstack -- echo \$HELLO
|
|
67
|
+
world
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Any command can be run in an envstack environment by preceeding the command
|
|
71
|
+
with `--`:
|
|
57
72
|
|
|
58
73
|
```bash
|
|
59
74
|
$ envstack -- python -c "import os; print(os.environ['HELLO'])"
|
|
60
75
|
world
|
|
61
76
|
```
|
|
62
77
|
|
|
78
|
+
## Creating Stacks
|
|
79
|
+
|
|
63
80
|
To create a new environment stack, create a new namespaced .env file.
|
|
64
81
|
For example `thing.env` (the stack namespace is "thing"):
|
|
65
82
|
|
|
@@ -75,16 +92,6 @@ $ envstack thing
|
|
|
75
92
|
FOO 'bar'
|
|
76
93
|
```
|
|
77
94
|
|
|
78
|
-
Environment stacks are hierarchical, so values for `$FOO` defined in .env files lower
|
|
79
|
-
in the filesystem (lower in scope) override those defined higher up (higher in scope):
|
|
80
|
-
|
|
81
|
-
```
|
|
82
|
-
/show/thing.env
|
|
83
|
-
/show/seq/thing.env
|
|
84
|
-
/show/seq/shot/thing.env
|
|
85
|
-
/show/seq/shot/task/thing.env
|
|
86
|
-
```
|
|
87
|
-
|
|
88
95
|
Variables can reference other variables defined elsewhere (but cannot be circular):
|
|
89
96
|
|
|
90
97
|
```yaml
|
|
@@ -106,71 +113,76 @@ Environment files can include other namespaced environments (all stacks inherit
|
|
|
106
113
|
include: ['other']
|
|
107
114
|
```
|
|
108
115
|
|
|
109
|
-
##
|
|
116
|
+
## Context
|
|
110
117
|
|
|
111
|
-
|
|
118
|
+
Environment stacks are hierarchical, so values for `$FOO` defined in .env files lower
|
|
119
|
+
in the filesystem (lower in scope) override those defined higher up (higher in scope):
|
|
112
120
|
|
|
113
|
-
```
|
|
114
|
-
$
|
|
121
|
+
```
|
|
122
|
+
${DEFAULT_ENV_DIR}
|
|
123
|
+
/stack.env
|
|
124
|
+
/show/stack.env
|
|
125
|
+
/show/seq/stack.env
|
|
126
|
+
/show/seq/shot/stack.env
|
|
127
|
+
/show/seq/shot/task/stack.env
|
|
115
128
|
```
|
|
116
129
|
|
|
117
|
-
|
|
130
|
+
If you are working in the task directory, those envstack $VARs will override the
|
|
131
|
+
$VARs defined in the shot, seq, show and root directories.
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
## Usage
|
|
135
|
+
|
|
136
|
+
To see the default environment for any given stack:
|
|
118
137
|
|
|
119
138
|
```bash
|
|
120
|
-
$ envstack
|
|
139
|
+
$ envstack [STACK]
|
|
121
140
|
```
|
|
122
141
|
|
|
123
|
-
To resolve
|
|
142
|
+
To resolve one or more environment vars for a given stack:
|
|
124
143
|
|
|
125
144
|
```bash
|
|
126
|
-
$ envstack
|
|
145
|
+
$ envstack [STACK] -r [VAR [VAR ...]]
|
|
127
146
|
```
|
|
128
147
|
|
|
129
|
-
To trace where
|
|
148
|
+
To trace where one or more environment vars is being set:
|
|
130
149
|
|
|
131
150
|
```bash
|
|
132
|
-
$ envstack
|
|
151
|
+
$ envstack [STACK] -t [VAR [VAR ...]]
|
|
133
152
|
```
|
|
134
153
|
|
|
135
|
-
To
|
|
154
|
+
To get the list of source files for a given stack:
|
|
136
155
|
|
|
137
156
|
```bash
|
|
138
|
-
$ envstack
|
|
157
|
+
$ envstack [STACK] --sources
|
|
139
158
|
```
|
|
140
159
|
|
|
141
160
|
## Python API
|
|
142
161
|
|
|
143
|
-
|
|
144
|
-
a drop-in replacement for `os.getenv`
|
|
145
|
-
|
|
146
|
-
```python
|
|
147
|
-
>>> import envstack
|
|
148
|
-
>>> envstack.getenv("HELLO")
|
|
149
|
-
'world'
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
To use a different stack, use the `init` function:
|
|
162
|
+
To init the environment stack, use the `init` function:
|
|
153
163
|
|
|
154
164
|
```python
|
|
155
165
|
>>> envstack.init("thing")
|
|
156
|
-
>>>
|
|
166
|
+
>>> os.getenv("FOO")
|
|
157
167
|
'bar'
|
|
158
168
|
```
|
|
159
169
|
|
|
160
|
-
|
|
170
|
+
Alternatively, `envstack.getenv` uses the default environment stack `stack` and can be
|
|
171
|
+
a drop-in replacement for `os.getenv`
|
|
161
172
|
|
|
162
173
|
```python
|
|
163
|
-
>>>
|
|
164
|
-
|
|
174
|
+
>>> import envstack
|
|
175
|
+
>>> envstack.getenv("HELLO")
|
|
176
|
+
'world'
|
|
165
177
|
```
|
|
166
178
|
|
|
167
179
|
## Running Commands
|
|
168
180
|
|
|
169
|
-
To run any command line executable inside of an environment stack, where
|
|
181
|
+
To run any command line executable inside of an environment stack, where `[COMMAND]`
|
|
170
182
|
is the command to run:
|
|
171
183
|
|
|
172
184
|
```bash
|
|
173
|
-
$ envstack
|
|
185
|
+
$ envstack [STACK] -- [COMMAND]
|
|
174
186
|
```
|
|
175
187
|
|
|
176
188
|
For example, running python in the default stack (reading from the default `stack.env` file):
|
|
@@ -34,6 +34,7 @@ Stacked environment variable management system.
|
|
|
34
34
|
"""
|
|
35
35
|
|
|
36
36
|
__prog__ = "envstack"
|
|
37
|
-
__version__ = "0.
|
|
37
|
+
__version__ = "0.5.0"
|
|
38
38
|
|
|
39
|
-
from envstack.env import
|
|
39
|
+
from envstack.env import Env
|
|
40
|
+
from envstack.env import getenv, init, load_file
|
|
@@ -30,12 +30,10 @@
|
|
|
30
30
|
#
|
|
31
31
|
|
|
32
32
|
__doc__ = """
|
|
33
|
-
|
|
33
|
+
Command line interface for envstack: stacked environment variable management.
|
|
34
34
|
"""
|
|
35
35
|
|
|
36
36
|
import argparse
|
|
37
|
-
import os
|
|
38
|
-
import pprint
|
|
39
37
|
import sys
|
|
40
38
|
import traceback
|
|
41
39
|
|
|
@@ -85,24 +83,26 @@ def parse_args():
|
|
|
85
83
|
"--platform",
|
|
86
84
|
default=config.PLATFORM,
|
|
87
85
|
metavar="PLATFORM",
|
|
88
|
-
help="
|
|
86
|
+
help="platform to resolve variables for (linux, darwin, windows)",
|
|
89
87
|
)
|
|
90
88
|
parser.add_argument(
|
|
91
89
|
"-r",
|
|
92
90
|
"--resolve",
|
|
91
|
+
nargs="*",
|
|
93
92
|
metavar="VAR",
|
|
94
|
-
help="resolve
|
|
95
|
-
)
|
|
96
|
-
parser.add_argument(
|
|
97
|
-
"--sources",
|
|
98
|
-
action="store_true",
|
|
99
|
-
help="list the sources for a stack",
|
|
93
|
+
help="resolve environment variables",
|
|
100
94
|
)
|
|
101
95
|
parser.add_argument(
|
|
102
96
|
"-t",
|
|
103
97
|
"--trace",
|
|
98
|
+
nargs="*",
|
|
104
99
|
metavar="VAR",
|
|
105
|
-
help="trace where
|
|
100
|
+
help="trace where environment variables are being set",
|
|
101
|
+
)
|
|
102
|
+
parser.add_argument(
|
|
103
|
+
"--sources",
|
|
104
|
+
action="store_true",
|
|
105
|
+
help="list the sources for a stack",
|
|
106
106
|
)
|
|
107
107
|
|
|
108
108
|
args = parser.parse_args(args_before_dash)
|
|
@@ -115,15 +115,20 @@ def main():
|
|
|
115
115
|
args, command = parse_args()
|
|
116
116
|
|
|
117
117
|
try:
|
|
118
|
-
if args.resolve:
|
|
119
|
-
|
|
120
|
-
args.
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
118
|
+
if args.resolve is not None:
|
|
119
|
+
if len(args.resolve) == 0:
|
|
120
|
+
args.resolve = load_environ(args.namespace).keys()
|
|
121
|
+
env = load_environ(args.namespace, platform=args.platform)
|
|
122
|
+
for resolve in args.resolve:
|
|
123
|
+
var = env.get(resolve)
|
|
124
|
+
val = expandvars(var, env, recursive=True)
|
|
125
|
+
print(f"{resolve}={val}")
|
|
126
|
+
elif args.trace is not None:
|
|
127
|
+
if len(args.trace) == 0:
|
|
128
|
+
args.trace = load_environ(args.namespace).keys()
|
|
129
|
+
for trace in args.trace:
|
|
130
|
+
path = trace_var(args.namespace, trace)
|
|
131
|
+
print("{0}: {1}".format(trace, path))
|
|
127
132
|
elif args.sources:
|
|
128
133
|
sources = build_sources(args.namespace)
|
|
129
134
|
for source in sources:
|
|
@@ -135,7 +140,7 @@ def main():
|
|
|
135
140
|
else:
|
|
136
141
|
env = load_environ(args.namespace, platform=args.platform, includes=True)
|
|
137
142
|
for k, v in env.items():
|
|
138
|
-
print(f"{k}
|
|
143
|
+
print(f"{k}={v}")
|
|
139
144
|
|
|
140
145
|
except KeyboardInterrupt:
|
|
141
146
|
print("Stopping...")
|
|
@@ -59,20 +59,30 @@ def detect_shell():
|
|
|
59
59
|
|
|
60
60
|
DEBUG = os.getenv("DEBUG")
|
|
61
61
|
DEFAULT_NAMESPACE = os.getenv("DEFAULT_ENV_STACK", "stack")
|
|
62
|
-
|
|
62
|
+
ENV = os.getenv("ENV", "prod")
|
|
63
|
+
HOME = os.getenv("HOME")
|
|
64
|
+
LOG_LEVEL = os.environ.get("LOG_LEVEL", "INFO")
|
|
63
65
|
ON_POSIX = "posix" in sys.builtin_module_names
|
|
64
66
|
PLATFORM = platform.system().lower()
|
|
65
67
|
PYTHON_VERSION = sys.version_info[0]
|
|
66
68
|
SHELL = detect_shell()
|
|
67
69
|
USERNAME = os.getenv("USERNAME", os.getenv("USER"))
|
|
68
70
|
|
|
69
|
-
#
|
|
70
|
-
|
|
71
|
+
# set some default environment variables
|
|
72
|
+
DEFAULT_ENV = {
|
|
73
|
+
"ENV": ENV,
|
|
74
|
+
"HOME": HOME,
|
|
75
|
+
"PLATFORM": PLATFORM,
|
|
76
|
+
"USER": USERNAME,
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
# default location of envstack files
|
|
80
|
+
# NOTE: the siteconf sitecustomize.py module may override this
|
|
71
81
|
DEFAULT_ENV_DIR = os.getenv(
|
|
72
82
|
"DEFAULT_ENV_DIR",
|
|
73
83
|
{
|
|
74
|
-
"darwin": "/
|
|
75
|
-
"linux": "/
|
|
76
|
-
"windows": "C
|
|
77
|
-
}.get(PLATFORM),
|
|
84
|
+
"darwin": "{HOME}/Library/Application Support/envstack",
|
|
85
|
+
"linux": "{HOME}/.local/envstack",
|
|
86
|
+
"windows": "C:\\ProgramData\\envstack",
|
|
87
|
+
}.get(PLATFORM).format(**DEFAULT_ENV),
|
|
78
88
|
)
|
|
@@ -260,18 +260,22 @@ class Env(dict):
|
|
|
260
260
|
"""Returns raw, unexpanded value of key, or None."""
|
|
261
261
|
return self.get(key, resolved=False).template
|
|
262
262
|
|
|
263
|
-
def items(self):
|
|
264
|
-
"""Returns list of (key, value) pairs, as 2-tuples."""
|
|
265
|
-
return [(k, EnvVar(self[k]).value()) for k in self]
|
|
266
|
-
|
|
267
263
|
def merge(self, env):
|
|
268
|
-
"""Merges another environ into this one
|
|
269
|
-
env[k] will replace self[k].
|
|
264
|
+
"""Merges another environ `env` into this one.
|
|
270
265
|
|
|
271
266
|
:param env: env to merge into this one
|
|
272
267
|
"""
|
|
273
|
-
|
|
274
|
-
|
|
268
|
+
merged = env.copy()
|
|
269
|
+
for key, value in self.items():
|
|
270
|
+
if isinstance(value, str):
|
|
271
|
+
# replace ${KEY} vars with values from env
|
|
272
|
+
value = re.sub(
|
|
273
|
+
r"\${(\w+)}",
|
|
274
|
+
lambda match: env.get(match.group(1), match.group(0)),
|
|
275
|
+
value,
|
|
276
|
+
)
|
|
277
|
+
merged[key] = value
|
|
278
|
+
return merged
|
|
275
279
|
|
|
276
280
|
def set_namespace(self, name):
|
|
277
281
|
"""Stores the namespace for this environment.
|
|
@@ -538,7 +542,7 @@ def init(name=config.DEFAULT_NAMESPACE):
|
|
|
538
542
|
def load_environ(
|
|
539
543
|
name=config.DEFAULT_NAMESPACE,
|
|
540
544
|
sources=None,
|
|
541
|
-
environ=
|
|
545
|
+
environ=os.environ,
|
|
542
546
|
platform=config.PLATFORM,
|
|
543
547
|
scope=None,
|
|
544
548
|
includes=True,
|
|
@@ -577,7 +581,7 @@ def load_environ(
|
|
|
577
581
|
for source in sources:
|
|
578
582
|
env.update(source.load(platform=platform))
|
|
579
583
|
|
|
580
|
-
#
|
|
584
|
+
# merge values from given environment
|
|
581
585
|
if environ:
|
|
582
586
|
env.merge(environ)
|
|
583
587
|
|
|
@@ -650,7 +654,7 @@ def trace_var(name, var, scope=None):
|
|
|
650
654
|
:returns: source path
|
|
651
655
|
"""
|
|
652
656
|
if var in os.environ:
|
|
653
|
-
return "local environment
|
|
657
|
+
return "local environment"
|
|
654
658
|
sources = build_sources(name, scope=scope)
|
|
655
659
|
sources.reverse()
|
|
656
660
|
for source in sources:
|
|
@@ -660,6 +664,7 @@ def trace_var(name, var, scope=None):
|
|
|
660
664
|
return source.path
|
|
661
665
|
|
|
662
666
|
|
|
667
|
+
# default stack environment
|
|
663
668
|
environ = load_environ(environ=os.environ)
|
|
664
669
|
|
|
665
670
|
|
|
@@ -33,7 +33,17 @@ import logging
|
|
|
33
33
|
|
|
34
34
|
from envstack.config import LOG_LEVEL
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
|
|
37
|
+
class Logger(logging.Logger):
|
|
38
|
+
"""Custom logger class."""
|
|
39
|
+
|
|
40
|
+
def setLevel(self, level):
|
|
41
|
+
if isinstance(level, str):
|
|
42
|
+
level = getattr(logging, level.upper(), logging.NOTSET)
|
|
43
|
+
super().setLevel(level)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
log = Logger("envstack")
|
|
37
47
|
log.setLevel(LOG_LEVEL)
|
|
38
48
|
log.addHandler(logging.NullHandler())
|
|
39
49
|
|