@@ -207,6 +207,16 @@ def _copy_site_includes(self):
207207 destination = os .path .join (env_site_dir , "packages.yaml" )
208208 self ._copy_or_merge_includes ("packages" , packages_yaml_path , packages_compiler_yaml_path , destination )
209209
210+ def get_upstream_realpaths (self , upstream_path ):
211+ spack_yaml_path = os .path .realpath (os .path .join (upstream_path , "../spack.yaml" ))
212+ with open (spack_yaml_path , "r" ) as f :
213+ spack_yaml = syaml .load_config (f )
214+ upstream_paths = [upstream_path ]
215+ if "upstreams" in spack_yaml ["spack" ].keys ():
216+ entries = spack_yaml ["spack" ]["upstreams" ]
217+ for entry in entries .items ():
218+ upstream_paths += self .get_upstream_realpaths (entry [1 ]["install_tree" ])
219+ return upstream_paths
210220
211221 def write (self ):
212222 """Write environment out to a spack.yaml in <env_dir>/<name>.
@@ -280,10 +290,10 @@ def write(self):
280290 "common" : os .path .join (self .env_dir (), "common" ),
281291 "site" : os .path .join (self .env_dir (), "site" ),
282292 }
283- for upstream_path in self . upstreams :
284- upstream_path = upstream_path [ 0 ]
285- # spack doesn't handle "~/" correctly, this fixes it:
286- upstream_path = os . path . expanduser ( upstream_path )
293+ all_upstreams = []
294+ for upstream in self . upstreams :
295+ all_upstreams . extend ( self . get_upstream_realpaths ( upstream [ 0 ]))
296+ for upstream_path in all_upstreams :
287297 if not os .path .basename (os .path .normpath (upstream_path )) == "install" :
288298 logging .warning (
289299 "WARNING: Upstream path '%s' is not an 'install' directory!"
@@ -298,7 +308,7 @@ def write(self):
298308 if path_parts :
299309 name = path_parts ["spack_stack_ver" ] + "-" + path_parts ["env_name" ]
300310 else :
301- name = os .path .basename ( upstream_path )
311+ name = os .path .realpath ( os . path . join ( upstream_path , ".." ) )
302312 upstream = "upstreams:%s:install_tree:'%s'" % (name , upstream_path )
303313 logging .info ("Adding upstream path '%s'" % upstream_path )
304314 spack .config .add (upstream , scope = env_scope )
@@ -319,12 +329,20 @@ def write(self):
319329 f"'{ upstream_path } ' do not match! Verify that you are using the same "
320330 "version of spack-stack, or really, really know what you are doing." )
321331 )
332+ new_envrepo = os .path .join (self .env_dir (), "envrepo" )
333+ for upstream_path in all_upstreams [::- 1 ]:
334+ envrepo_path = os .path .realpath (os .path .join (upstream_path , "../envrepo" ))
335+ if os .path .isdir (envrepo_path ):
336+ shutil .copytree (envrepo_path , new_envrepo , dirs_exist_ok = True )
337+ if os .path .isdir (new_envrepo ):
338+ repo_cfg = "repos:[$env/envrepo]"
339+ spack .config .add (repo_cfg , scope = env_scope )
322340
323341 if self .modifypkg :
324342 logging .info ("Creating custom repo with packages %s" % ", " .join (self .modifypkg ))
325343 env_repo_path = os .path .join (env_dir , "envrepo" )
326344 env_pkgs_path = os .path .join (env_repo_path , "packages" )
327- os .makedirs (env_pkgs_path , exist_ok = False )
345+ os .makedirs (env_pkgs_path , exist_ok = True )
328346 with open (os .path .join (env_repo_path , "repo.yaml" ), "w" ) as f :
329347 f .write ("repo:\n namespace: envrepo" )
330348 repo_paths = spack .config .get ("repos" )
@@ -338,6 +356,7 @@ def write(self):
338356 pkg_path ,
339357 os .path .join (env_pkgs_path , pkg_name ),
340358 ignore = shutil .ignore_patterns ("__pycache__" ),
359+ dirs_exist_ok = True ,
341360 )
342361 pkg_found = True
343362 # Use the first repo where the package exists:
0 commit comments