From 63c6df152ba646f3e65df9b30441c29821d19568 Mon Sep 17 00:00:00 2001 From: Gregory Date: Wed, 5 Apr 2023 17:32:21 -0700 Subject: [PATCH] fixup --- lib/spack/spack/environment/environment.py | 12 ++++++---- lib/spack/spack/filesystem_view.py | 28 +++++++++++++++++++++- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/lib/spack/spack/environment/environment.py b/lib/spack/spack/environment/environment.py index 9d5eac64ef4..ae6581bbf03 100644 --- a/lib/spack/spack/environment/environment.py +++ b/lib/spack/spack/environment/environment.py @@ -491,7 +491,10 @@ def _current_root(self): # We will not operate on this view object, only query metadata # We don't want to pass a created_path to this view, so that we can read where it says it # was created. - view = self.view(self.root, created_path=False) + if not os.path.exists(self.root): + return None + + view = self.view(created_path=False) orig_path = view.metadata.get("created_path", None) if orig_path: return orig_path @@ -532,9 +535,7 @@ def get_projection_for_spec(self, spec): symlink. """ view = self.view() - view_path = view.get_projection_for_spec(spec) - rel_path = os.path.relpath(view_path, self._current_root) - return os.path.join(self.root, rel_path) + return view.get_projection_for_spec(spec) def view(self, new=None, created_path=True): """ @@ -550,7 +551,8 @@ def view(self, new=None, created_path=True): rooted at that path. Default None. This should only be used to regenerate the view, and cannot be used to access specs. """ - root = new if new else self._current_root + root = new if new else self.root + if not root: # This can only be hit if we write a future bug msg = ( diff --git a/lib/spack/spack/filesystem_view.py b/lib/spack/spack/filesystem_view.py index 0617ab26d06..f1ed17d8ed9 100644 --- a/lib/spack/spack/filesystem_view.py +++ b/lib/spack/spack/filesystem_view.py @@ -288,7 +288,7 @@ def __init__(self, root, layout, **kwargs): self.metadata_path = os.path.join(self._root, _metadata_path) if not self.metadata: - self.projections = self.read_metadata() + self.metadata = self.read_metadata() elif not os.path.exists(self.metadata_path): self.write_metadata() else: @@ -675,6 +675,32 @@ class SimpleFilesystemView(FilesystemView): def __init__(self, root, layout, **kwargs): super(SimpleFilesystemView, self).__init__(root, layout, **kwargs) + self.metadata_path = os.path.join(self._root, _metadata_path) + if not self.metadata: + self.metadata = self.read_metadata() + elif not os.path.exists(self.metadata_path): + self.write_metadata() + else: + if self.metadata != self.read_metadata(): + msg = f"View at {self._root} has metadata file" + msg += " which does not match metadata passed manually." + raise ConflictingMetadataError(msg) + + def write_metadata(self): + if self.metadata: + mkdirp(os.path.dirname(self.metadata_path)) + with open(self.metadata_path, "w") as f: + f.write(s_yaml.dump_config({"metadata": self.metadata})) + + def read_metadata(self): + if os.path.exists(self.metadata_path): + with open(self.metadata_path, "r") as f: + # no schema as this is not user modified + metadata_data = s_yaml.load(f) + return metadata_data["metadata"] + else: + return {} + def _sanity_check_view_projection(self, specs): """A very common issue is that we end up with two specs of the same package, that project to the same prefix. We want to catch that as