envstack 0.2.6__tar.gz → 0.4.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: envstack
3
- Version: 0.2.6
3
+ Version: 0.4.0
4
4
  Summary: Stacked environment variable management system.
5
5
  Home-page: http://github.com/rsgalloway/envstack
6
6
  Author: Ryan Galloway
@@ -20,10 +20,9 @@ The default stack is `stack` and variables are declared in `stack.env`
20
20
  files. You can create any new stack by creating new `.env` files, e.g. creating
21
21
  a new `test` stack just create `test.env` files.
22
22
 
23
- Envstack works best combined with [siteconf](https://github.com/rsgalloway/siteconf).
23
+ > **Note:** envstack works best combined with [siteconf](https://github.com/rsgalloway/siteconf).
24
24
 
25
- Installation
26
- ------------
25
+ ## Installation
27
26
 
28
27
  The easiest way to install:
29
28
 
@@ -35,9 +34,15 @@ $ pip install envstack
35
34
 
36
35
  Copy the default stack file
37
36
  [`stack.env`](https://github.com/rsgalloway/envstack/blob/master/stack.env)
38
- to your current working directory, or the root of your project. This is the default
39
- environment stack. Running the `envstack` command should show you the resolved
40
- environment for your platform:
37
+ to your current working directory, the root of your project or `/etc/envstack` (the default location for envstack files, or `C:/ProgramData/envstack` on Windows).
38
+
39
+
40
+ ```bach
41
+ cp stack.env /etc/envstack
42
+ ```
43
+
44
+ The `stack` namespace is the default environment stack. Running the `envstack` command
45
+ should show you the resolved environment for your platform:
41
46
 
42
47
  ```bash
43
48
  $ envstack
@@ -56,7 +61,7 @@ Modify the environment stack by updating `stack.env` or by creating new contextu
56
61
  You can execute any command inside the default stacked environment like this:
57
62
 
58
63
  ```bash
59
- $ enstack -- <command>
64
+ $ envstack -- <command>
60
65
  ```
61
66
 
62
67
  For example:
@@ -106,7 +111,8 @@ linux:
106
111
  HELLO: world
107
112
  ```
108
113
 
109
- Environment files can include other namespaced environments:
114
+ Environment files can include other namespaced environments (all stacks inherit the default stack.env automatically).
115
+
110
116
  ```yaml
111
117
  include: ['other']
112
118
  ```
@@ -143,14 +149,39 @@ To see an environment stack on another platform:
143
149
  $ envstack <stack> -p <platform>
144
150
  ```
145
151
 
146
- Running Commands
147
- ----------------
152
+ ## Python API
153
+
154
+ By default, `envstack.getenv` uses the resolved default env stack `stack` and can be
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:
164
+
165
+ ```python
166
+ >>> envstack.init("thing")
167
+ >>> envstack.getenv("FOO")
168
+ 'bar'
169
+ ```
170
+
171
+ The `init` function also updates the current environment for code that is not using envstack:
172
+
173
+ ```python
174
+ >>> os.getenv("FOO")
175
+ 'bar'
176
+ ```
177
+
178
+ ## Running Commands
148
179
 
149
180
  To run any command line executable inside of an environment stack, where `<command>`
150
181
  is the command to run:
151
182
 
152
183
  ```bash
153
- $ enstack <stack> -- <command>
184
+ $ envstack <stack> -- <command>
154
185
  ```
155
186
 
156
187
  For example, running python in the default stack (reading from the default `stack.env` file):
@@ -166,3 +197,26 @@ Same command but using the "thing" stack"
166
197
  $ envstack thing -- python -c "import os; print(os.environ['FOO'])"
167
198
  bar
168
199
  ```
200
+
201
+ To source the environment in your current shell, source the output of --export (and create
202
+ an alias for convenience):
203
+
204
+ ```bash
205
+ $ source <(envstack --export)
206
+ $ alias esinit='source <(envstack $ARG --export)'
207
+ ```
208
+
209
+ In Windows command prompt:
210
+
211
+ ```cmd
212
+ for /f "usebackq" %i in (`envstack --export`) do %i
213
+ ```
214
+
215
+ ## Config
216
+
217
+ Default config settings are in the config.py module. The following environment variables are supported:
218
+
219
+ | Variable | Description |
220
+ |---------------------|-------------|
221
+ | $DEFAULT_ENV_DIR | the folder containing the default env stack files |
222
+ | $DEFAULT_ENV_STACK | the name of the default env stack namespace (default "stack") |
@@ -9,10 +9,9 @@ The default stack is `stack` and variables are declared in `stack.env`
9
9
  files. You can create any new stack by creating new `.env` files, e.g. creating
10
10
  a new `test` stack just create `test.env` files.
11
11
 
12
- Envstack works best combined with [siteconf](https://github.com/rsgalloway/siteconf).
12
+ > **Note:** envstack works best combined with [siteconf](https://github.com/rsgalloway/siteconf).
13
13
 
14
- Installation
15
- ------------
14
+ ## Installation
16
15
 
17
16
  The easiest way to install:
18
17
 
@@ -24,9 +23,15 @@ $ pip install envstack
24
23
 
25
24
  Copy the default stack file
26
25
  [`stack.env`](https://github.com/rsgalloway/envstack/blob/master/stack.env)
27
- to your current working directory, or the root of your project. This is the default
28
- environment stack. Running the `envstack` command should show you the resolved
29
- environment for your platform:
26
+ to your current working directory, the root of your project or `/etc/envstack` (the default location for envstack files, or `C:/ProgramData/envstack` on Windows).
27
+
28
+
29
+ ```bach
30
+ cp stack.env /etc/envstack
31
+ ```
32
+
33
+ The `stack` namespace is the default environment stack. Running the `envstack` command
34
+ should show you the resolved environment for your platform:
30
35
 
31
36
  ```bash
32
37
  $ envstack
@@ -45,7 +50,7 @@ Modify the environment stack by updating `stack.env` or by creating new contextu
45
50
  You can execute any command inside the default stacked environment like this:
46
51
 
47
52
  ```bash
48
- $ enstack -- <command>
53
+ $ envstack -- <command>
49
54
  ```
50
55
 
51
56
  For example:
@@ -95,7 +100,8 @@ linux:
95
100
  HELLO: world
96
101
  ```
97
102
 
98
- Environment files can include other namespaced environments:
103
+ Environment files can include other namespaced environments (all stacks inherit the default stack.env automatically).
104
+
99
105
  ```yaml
100
106
  include: ['other']
101
107
  ```
@@ -132,14 +138,39 @@ To see an environment stack on another platform:
132
138
  $ envstack <stack> -p <platform>
133
139
  ```
134
140
 
135
- Running Commands
136
- ----------------
141
+ ## Python API
142
+
143
+ By default, `envstack.getenv` uses the resolved default env stack `stack` and can be
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:
153
+
154
+ ```python
155
+ >>> envstack.init("thing")
156
+ >>> envstack.getenv("FOO")
157
+ 'bar'
158
+ ```
159
+
160
+ The `init` function also updates the current environment for code that is not using envstack:
161
+
162
+ ```python
163
+ >>> os.getenv("FOO")
164
+ 'bar'
165
+ ```
166
+
167
+ ## Running Commands
137
168
 
138
169
  To run any command line executable inside of an environment stack, where `<command>`
139
170
  is the command to run:
140
171
 
141
172
  ```bash
142
- $ enstack <stack> -- <command>
173
+ $ envstack <stack> -- <command>
143
174
  ```
144
175
 
145
176
  For example, running python in the default stack (reading from the default `stack.env` file):
@@ -155,3 +186,26 @@ Same command but using the "thing" stack"
155
186
  $ envstack thing -- python -c "import os; print(os.environ['FOO'])"
156
187
  bar
157
188
  ```
189
+
190
+ To source the environment in your current shell, source the output of --export (and create
191
+ an alias for convenience):
192
+
193
+ ```bash
194
+ $ source <(envstack --export)
195
+ $ alias esinit='source <(envstack $ARG --export)'
196
+ ```
197
+
198
+ In Windows command prompt:
199
+
200
+ ```cmd
201
+ for /f "usebackq" %i in (`envstack --export`) do %i
202
+ ```
203
+
204
+ ## Config
205
+
206
+ Default config settings are in the config.py module. The following environment variables are supported:
207
+
208
+ | Variable | Description |
209
+ |---------------------|-------------|
210
+ | $DEFAULT_ENV_DIR | the folder containing the default env stack files |
211
+ | $DEFAULT_ENV_STACK | the name of the default env stack namespace (default "stack") |
@@ -34,4 +34,6 @@ Stacked environment variable management system.
34
34
  """
35
35
 
36
36
  __prog__ = "envstack"
37
- __version__ = "0.2.6"
37
+ __version__ = "0.4.0"
38
+
39
+ from envstack.env import getenv, init
@@ -40,7 +40,7 @@ import sys
40
40
  import traceback
41
41
 
42
42
  from envstack import __version__, config
43
- from envstack.env import build_sources, expandvars, load_environ, trace_var
43
+ from envstack.env import build_sources, expandvars, export, load_environ, trace_var
44
44
  from envstack.wrapper import run_command
45
45
 
46
46
 
@@ -75,6 +75,11 @@ def parse_args():
75
75
  default=config.DEFAULT_NAMESPACE,
76
76
  help="the environment stack to use (default '%s')" % config.DEFAULT_NAMESPACE,
77
77
  )
78
+ parser.add_argument(
79
+ "--export",
80
+ action="store_true",
81
+ help="generate export commands for the current shell",
82
+ )
78
83
  parser.add_argument(
79
84
  "-p",
80
85
  "--platform",
@@ -123,6 +128,8 @@ def main():
123
128
  sources = build_sources(args.namespace)
124
129
  for source in sources:
125
130
  print(source)
131
+ elif args.export:
132
+ print(export(args.namespace, config.SHELL))
126
133
  elif command:
127
134
  return run_command(args.namespace, command)
128
135
  else:
@@ -37,20 +37,41 @@ import os
37
37
  import platform
38
38
  import sys
39
39
 
40
+
41
+ def detect_shell():
42
+ """Detect the current shell."""
43
+ if PLATFORM == "windows":
44
+ comspec = os.environ.get("ComSpec")
45
+ if comspec:
46
+ if "cmd.exe" in comspec:
47
+ return "cmd"
48
+ elif "powershell.exe" in comspec:
49
+ return "pwsh"
50
+ else:
51
+ return "unknown"
52
+ else:
53
+ shell = os.environ.get("SHELL")
54
+ if shell:
55
+ return shell.split("/")[-1]
56
+ else:
57
+ return "unknown"
58
+
59
+
40
60
  DEBUG = os.getenv("DEBUG")
41
- DEFAULT_NAMESPACE = "stack"
61
+ DEFAULT_NAMESPACE = os.getenv("DEFAULT_ENV_STACK", "stack")
42
62
  LOG_LEVEL = int(os.environ.get("LOG_LEVEL", 20))
43
63
  ON_POSIX = "posix" in sys.builtin_module_names
44
64
  PLATFORM = platform.system().lower()
45
65
  PYTHON_VERSION = sys.version_info[0]
66
+ SHELL = detect_shell()
46
67
  USERNAME = os.getenv("USERNAME", os.getenv("USER"))
47
68
 
48
- # default location of the global environment directory by platform
69
+ # default location of the global env stacks
49
70
  DEFAULT_ENV_DIR = os.getenv(
50
71
  "DEFAULT_ENV_DIR",
51
72
  {
52
- "darwin": f"/etc/{DEFAULT_NAMESPACE}",
53
- "linux": f"/etc/{DEFAULT_NAMESPACE}",
54
- "windows": f"C:/ProgramData/{DEFAULT_NAMESPACE}",
73
+ "darwin": "/etc/envstack",
74
+ "linux": "/etc/envstack",
75
+ "windows": "C:/ProgramData/envstack",
55
76
  }.get(PLATFORM),
56
77
  )
@@ -356,31 +356,44 @@ def clear_file_cache():
356
356
  load_file_cache = {}
357
357
 
358
358
 
359
- def safe_eval(value):
360
- """Returns template value preserving original class.
361
- Useful for preserving nested values in wrappers.
362
- """
359
+ def decode_value(value):
360
+ """Returns a decoded value that's been encoded by a wrapper.
363
361
 
364
- from envstack.wrapper import decode_value
362
+ Decoding encoded environments can be tricky. For example, it must account for path
363
+ templates that include curly braces, e.g. path templates string like this must be
364
+ preserved:
365
365
 
366
- try:
367
- from ast import literal_eval
366
+ '/path/with/{variable}'
368
367
 
369
- eval_func = literal_eval
370
- except ImportError:
371
- # warning: security issue
372
- eval_func = eval
373
-
374
- if type(value) == str:
375
- try:
376
- return eval_func(value)
377
- except Exception:
378
- try:
379
- return eval_func(decode_value(value))
380
- except Exception:
381
- return value
382
-
383
- return value
368
+ :param value: wrapper encoded env value
369
+ :returns: decoded value
370
+ """
371
+ # TODO: find a better way to encode/decode wrapper envs
372
+ return (
373
+ str(value)
374
+ .replace("'[", "[")
375
+ .replace("]'", "]")
376
+ .replace('"[', "[")
377
+ .replace(']"', "]")
378
+ .replace('"{"', "{'")
379
+ .replace('"}"', "'}")
380
+ .replace("'{'", "{'")
381
+ .replace("'}'", "'}")
382
+ )
383
+
384
+
385
+ def encode(env, resolved=True):
386
+ """Returns environment as a dict with str encoded key/values for passing to
387
+ wrapper subprocesses.
388
+
389
+ :param env: `Env` instance or os.environ.
390
+ :param resolved: fully resolve values (default=True).
391
+ :returns: dict with bytestring key/values.
392
+ """
393
+ c = lambda v: str(v)
394
+ if resolved:
395
+ return dict((c(k), c(expandvars(v, env))) for k, v in env.items())
396
+ return dict((c(k), c(v)) for k, v in env.items())
384
397
 
385
398
 
386
399
  def build_sources(
@@ -481,6 +494,47 @@ def expandvars(var, env=None, recursive=False):
481
494
  return EnvVar(var).expand(env, recursive=recursive)
482
495
 
483
496
 
497
+ def export(name, shell="bash", resolve=False, scope=None):
498
+ """Returns environment commands that can be sourced.
499
+
500
+ $ source <(envstack --export)
501
+
502
+ List of shell names: bash, tcsh, cmd, pwsh
503
+ (see output of config.detect_shell()).
504
+
505
+ :param name: stack namespace
506
+ :param shell: name of shell (default: bash)
507
+ :param resolve: resolve values (default: True)
508
+ :param scope: environment scope (default: cwd)
509
+ :returns: shell commands as string
510
+ """
511
+ env = load_environ(name, scope=scope)
512
+ expList = list()
513
+ for k, v in env.items():
514
+ if resolve:
515
+ v = expandvars(v, env, recursive=False)
516
+ if shell == "bash":
517
+ expList.append('export {0}="{1}"'.format(k, v))
518
+ elif shell == "tcsh":
519
+ expList.append('setenv {0}:"{1}"'.format(k, v))
520
+ elif shell == "cmd":
521
+ expList.append('set {0}="{1}"'.format(k, v))
522
+ elif shell == "pwsh":
523
+ expList.append('$env:{0}="{1}"'.format(k, v))
524
+ expList.sort()
525
+ exp = "\n".join(expList)
526
+ return exp
527
+
528
+
529
+ def init(name=config.DEFAULT_NAMESPACE):
530
+ """Initializes the environment for a given namespace.
531
+
532
+ :param name: namespace (basename of env files).
533
+ """
534
+ env = load_environ(name)
535
+ os.environ.update(encode(env))
536
+
537
+
484
538
  def load_environ(
485
539
  name=config.DEFAULT_NAMESPACE,
486
540
  sources=None,
@@ -562,6 +616,31 @@ def load_file(path):
562
616
  return data
563
617
 
564
618
 
619
+ def safe_eval(value):
620
+ """Returns template value preserving original class.
621
+ Useful for preserving nested values in wrappers.
622
+ """
623
+
624
+ try:
625
+ from ast import literal_eval
626
+
627
+ eval_func = literal_eval
628
+ except ImportError:
629
+ # warning: security issue
630
+ eval_func = eval
631
+
632
+ if type(value) == str:
633
+ try:
634
+ return eval_func(value)
635
+ except Exception:
636
+ try:
637
+ return eval_func(decode_value(value))
638
+ except Exception:
639
+ return value
640
+
641
+ return value
642
+
643
+
565
644
  def trace_var(name, var, scope=None):
566
645
  """Traces where a var is getting set for a given name.
567
646
 
@@ -38,47 +38,7 @@ import subprocess
38
38
  import traceback
39
39
 
40
40
  from envstack import logger
41
- from envstack.env import expandvars, load_environ
42
-
43
-
44
- def decode_value(value):
45
- """Returns a decoded value that's been encoded by a wrapper.
46
-
47
- Decoding encoded environments can be tricky. For example, it must account for path
48
- templates that include curly braces, e.g. path templates string like this must be
49
- preserved:
50
-
51
- '/path/with/{variable}'
52
-
53
- :param value: wrapper encoded env value
54
- :returns: decoded value
55
- """
56
- # TODO: find a better way to encode/decode wrapper envs
57
- return (
58
- str(value)
59
- .replace("'[", "[")
60
- .replace("]'", "]")
61
- .replace('"[', "[")
62
- .replace(']"', "]")
63
- .replace('"{"', "{'")
64
- .replace('"}"', "'}")
65
- .replace("'{'", "{'")
66
- .replace("'}'", "'}")
67
- )
68
-
69
-
70
- def encode(env, resolved=True):
71
- """Returns environment as a dict with str encoded key/values for passing to
72
- wrapper subprocesses.
73
-
74
- :param env: `Env` instance or os.environ.
75
- :param resolved: fully resolve values (default=True).
76
- :returns: dict with bytestring key/values.
77
- """
78
- c = lambda v: str(v)
79
- if resolved:
80
- return dict((c(k), c(expandvars(v, env))) for k, v in env.items())
81
- return dict((c(k), c(v)) for k, v in env.items())
41
+ from envstack.env import encode, expandvars, load_environ
82
42
 
83
43
 
84
44
  def to_args(cmd):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: envstack
3
- Version: 0.2.6
3
+ Version: 0.4.0
4
4
  Summary: Stacked environment variable management system.
5
5
  Home-page: http://github.com/rsgalloway/envstack
6
6
  Author: Ryan Galloway
@@ -20,10 +20,9 @@ The default stack is `stack` and variables are declared in `stack.env`
20
20
  files. You can create any new stack by creating new `.env` files, e.g. creating
21
21
  a new `test` stack just create `test.env` files.
22
22
 
23
- Envstack works best combined with [siteconf](https://github.com/rsgalloway/siteconf).
23
+ > **Note:** envstack works best combined with [siteconf](https://github.com/rsgalloway/siteconf).
24
24
 
25
- Installation
26
- ------------
25
+ ## Installation
27
26
 
28
27
  The easiest way to install:
29
28
 
@@ -35,9 +34,15 @@ $ pip install envstack
35
34
 
36
35
  Copy the default stack file
37
36
  [`stack.env`](https://github.com/rsgalloway/envstack/blob/master/stack.env)
38
- to your current working directory, or the root of your project. This is the default
39
- environment stack. Running the `envstack` command should show you the resolved
40
- environment for your platform:
37
+ to your current working directory, the root of your project or `/etc/envstack` (the default location for envstack files, or `C:/ProgramData/envstack` on Windows).
38
+
39
+
40
+ ```bach
41
+ cp stack.env /etc/envstack
42
+ ```
43
+
44
+ The `stack` namespace is the default environment stack. Running the `envstack` command
45
+ should show you the resolved environment for your platform:
41
46
 
42
47
  ```bash
43
48
  $ envstack
@@ -56,7 +61,7 @@ Modify the environment stack by updating `stack.env` or by creating new contextu
56
61
  You can execute any command inside the default stacked environment like this:
57
62
 
58
63
  ```bash
59
- $ enstack -- <command>
64
+ $ envstack -- <command>
60
65
  ```
61
66
 
62
67
  For example:
@@ -106,7 +111,8 @@ linux:
106
111
  HELLO: world
107
112
  ```
108
113
 
109
- Environment files can include other namespaced environments:
114
+ Environment files can include other namespaced environments (all stacks inherit the default stack.env automatically).
115
+
110
116
  ```yaml
111
117
  include: ['other']
112
118
  ```
@@ -143,14 +149,39 @@ To see an environment stack on another platform:
143
149
  $ envstack <stack> -p <platform>
144
150
  ```
145
151
 
146
- Running Commands
147
- ----------------
152
+ ## Python API
153
+
154
+ By default, `envstack.getenv` uses the resolved default env stack `stack` and can be
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:
164
+
165
+ ```python
166
+ >>> envstack.init("thing")
167
+ >>> envstack.getenv("FOO")
168
+ 'bar'
169
+ ```
170
+
171
+ The `init` function also updates the current environment for code that is not using envstack:
172
+
173
+ ```python
174
+ >>> os.getenv("FOO")
175
+ 'bar'
176
+ ```
177
+
178
+ ## Running Commands
148
179
 
149
180
  To run any command line executable inside of an environment stack, where `<command>`
150
181
  is the command to run:
151
182
 
152
183
  ```bash
153
- $ enstack <stack> -- <command>
184
+ $ envstack <stack> -- <command>
154
185
  ```
155
186
 
156
187
  For example, running python in the default stack (reading from the default `stack.env` file):
@@ -166,3 +197,26 @@ Same command but using the "thing" stack"
166
197
  $ envstack thing -- python -c "import os; print(os.environ['FOO'])"
167
198
  bar
168
199
  ```
200
+
201
+ To source the environment in your current shell, source the output of --export (and create
202
+ an alias for convenience):
203
+
204
+ ```bash
205
+ $ source <(envstack --export)
206
+ $ alias esinit='source <(envstack $ARG --export)'
207
+ ```
208
+
209
+ In Windows command prompt:
210
+
211
+ ```cmd
212
+ for /f "usebackq" %i in (`envstack --export`) do %i
213
+ ```
214
+
215
+ ## Config
216
+
217
+ Default config settings are in the config.py module. The following environment variables are supported:
218
+
219
+ | Variable | Description |
220
+ |---------------------|-------------|
221
+ | $DEFAULT_ENV_DIR | the folder containing the default env stack files |
222
+ | $DEFAULT_ENV_STACK | the name of the default env stack namespace (default "stack") |
@@ -43,27 +43,35 @@ with open(os.path.join(here, "README.md")) as f:
43
43
  class PostInstallCommand(install):
44
44
  """Custom post-installation for copying stack.env."""
45
45
 
46
- def run(self):
47
- install.run(self)
48
- home_dir = os.getenv("HOME") or os.getenv("USERPROFILE")
46
+ def install_default_stack(self):
47
+ """Copy the default stack.env file to the default location."""
48
+ from envstack.config import DEFAULT_ENV_DIR
49
49
 
50
- if not home_dir:
51
- print("Error: unable to determine home directory.")
52
- return
50
+ if not os.path.isdir(DEFAULT_ENV_DIR):
51
+ os.makedirs(DEFAULT_ENV_DIR)
53
52
 
54
53
  source = os.path.join(os.path.dirname(__file__), "stack.env")
55
- destination = os.path.join(home_dir, "stack.env")
54
+ destination = os.path.join(DEFAULT_ENV_DIR, "stack.env")
56
55
 
57
56
  if os.path.exists(source):
57
+ print(f"Copying {source} to {destination}")
58
58
  shutil.copy(source, destination)
59
- print(f"Copied {source} to {destination}")
60
59
  else:
61
- print(f"{source} not found")
60
+ print(f"{source} not found)")
61
+
62
+ def run(self):
63
+ """Run the default install and copy the default stack.env file."""
64
+ install.run(self)
65
+
66
+ try:
67
+ self.install_default_stack()
68
+ except Exception as e:
69
+ print(f"Error copying stack.env: {e}")
62
70
 
63
71
 
64
72
  setup(
65
73
  name="envstack",
66
- version="0.2.6",
74
+ version="0.4.0",
67
75
  description="Stacked environment variable management system.",
68
76
  long_description=long_description,
69
77
  long_description_content_type="text/markdown",
File without changes
File without changes
File without changes