@@ -114,7 +114,7 @@ def length(self):
114114 """Returns the char length of the path"""
115115 return len (self .path )
116116
117- def load (self , platform = config .PLATFORM ):
117+ def load (self , platform : str = config .PLATFORM ):
118118 """Reads .env from .path, and returns an Env class object"""
119119 if self .path and not self .data :
120120 self .data = load_file (self .path )
@@ -305,17 +305,12 @@ def bake(self, filename: str = None, depth: int = 0, encrypt: bool = False):
305305 >>> env.bake("baked.env")
306306
307307 :param filename: path to save the baked environment.
308- :param depth: depth of source files to incldue (default: all ).
309- :param encrypt: encrypt the values.
308+ :param depth: depth of source files to include (optional ).
309+ :param encrypt: encrypt the values (optional) .
310310 :returns: baked environment.
311311 """
312- # get the sources for the given environment
313312 sources = self .sources
314-
315- # look for encryption keys in the environment
316- os .environ .update (get_keys_from_env (self ))
317-
318- # create a baked source
313+ os .environ .update (get_keys_from_env (self )) # for encryption
319314 baked = Source (filename )
320315
321316 def get_node_class (value ):
@@ -327,35 +322,63 @@ def get_node_class(value):
327322 return EncryptedNode
328323 return value .__class__
329324
330- # merge the sources into the outfile
325+ # track included files and seen keys
326+ includes = []
327+ seen_keys = set ()
328+
329+ for source in sources [:depth ]:
330+ for key , value in source .data .items ():
331+ if isinstance (value , dict ):
332+ for k , v in value .items ():
333+ if k in self :
334+ v = self [k ]
335+ node_class = get_node_class (v )
336+ seen_keys .add (k )
337+ else :
338+ seen_keys .add (key )
339+
340+ current_depth = 0
331341 for source in sources [- depth :]:
332342 for key , value in source .data .items ():
343+ if key == "include" and current_depth <= depth :
344+ includes = value
345+ continue
333346 if isinstance (value , dict ):
334347 for k , v in value .items ():
348+ if k in self and key == "all" : # override only in "all"
349+ v = self [k ]
335350 node_class = get_node_class (v )
336351 baked .data .setdefault (key , {})[k ] = node_class (v )
352+ seen_keys .add (k )
337353 else :
338- node_class = get_node_class (value )
339- baked .data [key ] = node_class (value )
354+ baked .data [key ] = get_node_class (value )(value )
355+ seen_keys .add (key )
356+ current_depth += 1
357+
358+ # add/override with values from the current environment
359+ for key , value in self .items ():
360+ if key == "STACK" or key in seen_keys :
361+ continue
362+ baked .data ["all" ][key ] = get_node_class (value )(value )
340363
341364 # clear includes if environment stack is fully baked
342- if depth <= 0 :
365+ if depth <= 0 or depth >= len ( sources ) :
343366 baked .data ["include" ] = []
367+ else :
368+ baked .data ["include" ] = includes
344369
345- # write the baked environment to the file
370+ # create the baked environment from the baked source
371+ baked_env = Env ()
372+ baked_env .load_source (baked )
346373 if filename :
347374 try :
348375 baked .write ()
349376 except Exception as err :
350377 raise WriteError (f"Failed to write { filename } " , err )
351378
352- # create the baked environment from the baked source
353- baked_env = Env ()
354- baked_env .load_source (baked )
355-
356379 return baked_env
357380
358- def write (self , filename : str = None ):
381+ def write (self , filename : str , depth : int = 0 , encrypt : bool = False ):
359382 """Writes the environment to an env file.
360383
361384 >>> env = Env({"FOO": "${BAR}", "BAR": "bar"})
@@ -367,11 +390,13 @@ def write(self, filename: str = None):
367390 >>> env.write("encrypted.env")
368391
369392 :param filename: path to save the baked environment.
393+ :param depth: depth of source files to include (optional).
394+ :param encrypt: encrypt the values (optional).
370395 :returns: Source object.
371396 """
372397 # the environment was loaded from one or more sources
373398 if self .sources :
374- baked = self .bake (filename )
399+ baked = self .bake (filename , depth = depth , encrypt = encrypt )
375400 return baked .sources [0 ]
376401
377402 # the environment was created from scratch
@@ -634,19 +659,21 @@ def export(
634659 name : str = config .DEFAULT_NAMESPACE ,
635660 shell : str = config .SHELL ,
636661 scope : str = None ,
662+ encrypt : bool = False ,
637663):
638664 """Returns shell commands that can be sourced to set environment stack
639665 environment variables.
640666
641667 Supported shells: bash, sh, tcsh, cmd, pwsh (see config.detect_shell()).
642668
643669 :param name: stack namespace.
644- :param shell: name of shell (default: current shell).
645- :param scope: environment scope (default: cwd).
670+ :param shell: name of shell (optional).
671+ :param scope: environment scope (optional).
672+ :param encrypt: encrypt the values (optional).
646673 :returns: shell commands as string.
647674 """
648- resolved_env = resolve_environ ( load_environ (name , scope = scope ) )
649- return export_env_to_shell (resolved_env , shell )
675+ env = load_environ (name , scope = scope , encrypt = encrypt )
676+ return export_env_to_shell (env , shell )
650677
651678
652679def save ():
@@ -747,8 +774,8 @@ def bake_environ(
747774 $ envstack [STACK] -o <filename>
748775
749776 :param name: stack namespace.
750- :param scope: environment scope (default: cwd ).
751- :param depth: depth of source files to incldue (default: all ).
777+ :param scope: environment scope (optional ).
778+ :param depth: depth of source files to include (optional ).
752779 :param filename: path to save the baked environment.
753780 :param encrypt: encrypt the values.
754781 :returns: baked environment.
0 commit comments