From e2293c758f11bcf98db6fbec1442b8b1c49a4f00 Mon Sep 17 00:00:00 2001 From: fbrechin <101643138+fbrechin@users.noreply.github.com> Date: Tue, 4 Mar 2025 17:52:28 +0000 Subject: [PATCH] Adding ability for repo paths from a manifest file to be expanded when creating an environment. (#49084) * Adding ability for repo paths from a manifest file to be expanded when creating an environment. A unit test was added to check that an environment variable will be expanded. Also, a bug was fixed in the expansion of develop paths where if an environment variable was in the path that then produced an absolute path the path would not be extended. * Fixing new unit test for env repo var substitution * Adding ability for repo paths from a manifest file to be expanded when creating an environment. A unit test was added to check that an environment variable will be expanded. Also, a bug was fixed in the expansion of develop paths where if an environment variable was in the path that then produced an absolute path the path would not be extended. * Messed up resolving last rebase --- lib/spack/spack/environment/environment.py | 33 +++++++++++++++++++-- lib/spack/spack/test/cmd/repo.py | 34 ++++++++++++++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/lib/spack/spack/environment/environment.py b/lib/spack/spack/environment/environment.py index d8b662f69af..f0e0ef8b2f3 100644 --- a/lib/spack/spack/environment/environment.py +++ b/lib/spack/spack/environment/environment.py @@ -389,6 +389,7 @@ def create_in_dir( # dev paths in this environment to refer to their original # locations. _rewrite_relative_dev_paths_on_relocation(env, init_file_dir) + _rewrite_relative_repos_paths_on_relocation(env, init_file_dir) return env @@ -405,8 +406,8 @@ def _rewrite_relative_dev_paths_on_relocation(env, init_file_dir): dev_path = substitute_path_variables(entry["path"]) expanded_path = spack.util.path.canonicalize_path(dev_path, default_wd=init_file_dir) - # Skip if the expanded path is the same (e.g. when absolute) - if dev_path == expanded_path: + # Skip if the substituted and expanded path is the same (e.g. when absolute) + if entry["path"] == expanded_path: continue tty.debug("Expanding develop path for {0} to {1}".format(name, expanded_path)) @@ -421,6 +422,34 @@ def _rewrite_relative_dev_paths_on_relocation(env, init_file_dir): env._re_read() +def _rewrite_relative_repos_paths_on_relocation(env, init_file_dir): + """When initializing the environment from a manifest file and we plan + to store the environment in a different directory, we have to rewrite + relative repo paths to absolute ones and expand environment variables.""" + with env: + repos_specs = spack.config.get("repos", default={}, scope=env.scope_name) + if not repos_specs: + return + for i, entry in enumerate(repos_specs): + repo_path = substitute_path_variables(entry) + expanded_path = spack.util.path.canonicalize_path(repo_path, default_wd=init_file_dir) + + # Skip if the substituted and expanded path is the same (e.g. when absolute) + if entry == expanded_path: + continue + + tty.debug("Expanding repo path for {0} to {1}".format(entry, expanded_path)) + + repos_specs[i] = expanded_path + + spack.config.set("repos", repos_specs, scope=env.scope_name) + + env.repos_specs = None + # If we changed the environment's spack.yaml scope, that will not be reflected + # in the manifest that we read + env._re_read() + + def environment_dir_from_name(name: str, exists_ok: bool = True) -> str: """Returns the directory associated with a named environment. diff --git a/lib/spack/spack/test/cmd/repo.py b/lib/spack/spack/test/cmd/repo.py index 3cb35ef09e4..86bb09bc81f 100644 --- a/lib/spack/spack/test/cmd/repo.py +++ b/lib/spack/spack/test/cmd/repo.py @@ -5,9 +5,13 @@ import pytest +import spack.config +import spack.environment as ev import spack.main +from spack.main import SpackCommand repo = spack.main.SpackCommand("repo") +env = SpackCommand("env") def test_help_option(): @@ -33,3 +37,33 @@ def test_create_add_list_remove(mutable_config, tmpdir): repo("remove", "--scope=site", str(tmpdir)) output = repo("list", "--scope=site", output=str) assert "mockrepo" not in output + + +def test_env_repo_path_vars_substitution( + tmpdir, install_mockery, mutable_mock_env_path, monkeypatch +): + """Test Spack correctly substitues repo paths with environment variables when creating an + environment from a manifest file.""" + + monkeypatch.setenv("CUSTOM_REPO_PATH", ".") + + # setup environment from spack.yaml + envdir = tmpdir.mkdir("env") + with envdir.as_cwd(): + with open("spack.yaml", "w", encoding="utf-8") as f: + f.write( + """\ +spack: + specs: [] + + repos: + - $CUSTOM_REPO_PATH +""" + ) + # creating env from manifest file + env("create", "test", "./spack.yaml") + # check that repo path was correctly substituted with the environment variable + current_dir = os.getcwd() + with ev.read("test") as newenv: + repos_specs = spack.config.get("repos", default={}, scope=newenv.scope_name) + assert current_dir in repos_specs