Skip to content

Commit 4d99470

Browse files
authored
Fix repository order bug in distribution command (#638)
* Fix bug in distribution command The distribution command was modifying the list of repos in a given spack environment which causes problems when resolving package dependencies. Maintain the original package repository data structure throughout the distro bundling process so that this does not occur. * Fix test * Fix test * Fix create-env test
1 parent 2321934 commit 4d99470

File tree

3 files changed

+32
-25
lines changed

3 files changed

+32
-25
lines changed

manager/manager_cmds/create_env.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,7 @@ def create_env(parser, args):
4646
manifest.add_user_spec(str(s))
4747

4848
if args.local_source:
49-
if spack.spack_version_info[0:3] < (0, 23, 0):
50-
manifest.set_config_value("config", "install_tree", {"root": "$env/opt"})
51-
else:
52-
manifest.set_config_value("config", "install_tree", "$env/opt")
49+
manifest.set_config_value("config", "install_tree", {"root": "$env/opt"})
5350

5451
# handle includes, if it is not set up right then nothing gets created
5552
include_dict = {"machine": args.machine, "dir": theDir, "file": "include.yaml"}

manager/manager_cmds/distribution.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

55
import spack.cmd
66
import spack.config
7+
import spack.environment
78
import spack.extensions
89
import spack.llnl.util.tty as tty
910
import spack.util.path
1011
import spack.util.spack_yaml
11-
from spack import environment
1212
from spack.cmd.mirror import create_mirror_for_all_specs, filter_externals
1313
from spack.llnl.util.filesystem import working_dir
1414
from spack.main import SpackCommand
@@ -143,11 +143,11 @@ def __init__(self, env, root, includes=None, excludes=None, extra_data=None):
143143
self._cached_env = None
144144

145145
def __enter__(self):
146-
self._cached_env = environment.active_environment()
146+
self._cached_env = spack.environment.active_environment()
147147
tty.msg(f"Concretizing env: {self.environment_to_package.name}....")
148148
self.environment_to_package.concretize()
149149
self.environment_to_package.write()
150-
environment.deactivate()
150+
spack.environment.deactivate()
151151
self.init_distro_dir()
152152

153153
return self
@@ -156,13 +156,13 @@ def __exit__(self, exc_type, exc_val, exc_tb):
156156
self.filter_excludes()
157157
self.remove_unwanted_artifacts()
158158
if self._cached_env:
159-
environment.activate(self._cached_env)
159+
spack.environment.activate(self._cached_env)
160160

161161
@property
162162
def env(self):
163163
if self._env is None:
164164
epath = os.path.join(self.path, "environment")
165-
self._env = environment.create_in_dir(epath, keep_relative=True)
165+
self._env = spack.environment.create_in_dir(epath, keep_relative=True)
166166
return self._env
167167

168168
def init_distro_dir(self):
@@ -240,24 +240,25 @@ def configure_extensions(self):
240240
sconfig("add", f"config:extensions:[{extension}]")
241241

242242
def configure_package_repos(self):
243-
repos = set()
244243
with self.environment_to_package:
244+
repos = spack.util.spack_yaml.syaml_dict()
245245
for scope in valid_env_scopes(self.environment_to_package):
246-
for repo in spack.config.get("repos", scope=scope).values():
247-
repos.add(spack.util.path.canonicalize_path(repo))
246+
repos.update(spack.config.get("repos", scope=scope))
248247

249248
tty.msg(f"Packing up package repositories to {self.package_repos}....")
250249
os.makedirs(self.package_repos)
251250

252-
to_write = {}
253-
for repo in repos:
254-
name = os.path.basename(repo)
255-
to_write[name] = os.path.join(os.path.relpath(self.package_repos, self.env.path), name)
256-
shutil.copytree(repo, os.path.join(self.package_repos, name))
251+
for name, repo in repos.items():
252+
repo = spack.util.path.canonicalize_path(repo)
253+
basename = os.path.basename(repo)
254+
repos[name] = os.path.join(
255+
os.path.relpath(self.package_repos, self.env.path), basename
256+
)
257+
shutil.copytree(repo, os.path.join(self.package_repos, basename))
257258

258259
tty.msg(f"Adding repositories to env: {self.env.name}....")
259260
env = get_env_as_dict(self.env)
260-
env["spack"]["repos"] = to_write
261+
env["spack"]["repos"] = repos
261262
self._write(env)
262263

263264
def configure_package_settings(self, filter_externals=False):

tests/test_distribution.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def {base_name}(parser, args):
5252

5353
def create_repo(path):
5454
os.makedirs(path)
55-
data = {"repo": {"namespace": "test"}}
55+
data = {"repo": {"namespace": os.path.basename(path)}}
5656
with open(os.path.join(path, "repo.yaml"), "w") as f:
5757
spack.util.spack_yaml.dump(data, f, default_flow_style=False)
5858
package = os.path.join(path, "packages", "test")
@@ -402,7 +402,6 @@ def test_DistributionPackager_configure_extensions(tmpdir):
402402
with tmpdir.as_cwd():
403403
pkgr.configure_extensions()
404404
mod_content = get_manifest(pkgr.env)
405-
print("content", mod_content)
406405

407406
for extension in expected_extensions:
408407
assert os.path.isdir(os.path.join(pkgr.env.path, extension))
@@ -416,10 +415,17 @@ def test_DistributionPackager_configure_repos(tmpdir):
416415
the environment into the environment being created and adds a relative path to the
417416
copied repositories to the spack.yaml that is being constructed.
418417
"""
419-
package_repo = os.path.join(tmpdir.strpath, "mock-repo")
418+
package_repo = os.path.join(tmpdir.strpath, "mock_repo")
420419
create_repo(package_repo)
421420

422-
extra_data = {"repos": {"mock-repo": package_repo}}
421+
package_repo2 = os.path.join(tmpdir.strpath, "mock_repo2")
422+
create_repo(package_repo2)
423+
424+
data = spack.util.spack_yaml.syaml_dict()
425+
data["mock_repo"] = package_repo
426+
data["mock_repo2"] = package_repo2
427+
428+
extra_data = {"repos": data}
423429
manifest = os.path.join(tmpdir.strpath, "base-env", "spack.yaml")
424430
create_spack_manifest(manifest, extra_data=extra_data)
425431
env = spack.environment.Environment(os.path.dirname(manifest))
@@ -436,8 +442,11 @@ def test_DistributionPackager_configure_repos(tmpdir):
436442
assert os.path.isdir(expected_repo_dir)
437443
assert "repos" in result_config["spack"]
438444

439-
expected_repo = {"mock-repo": f"../{os.path.basename(pkgr.package_repos)}/mock-repo"}
440-
assert expected_repo == result_config["spack"]["repos"]
445+
expected = spack.util.spack_yaml.syaml_dict()
446+
for key, val in data.items():
447+
expected[key] = f"../{os.path.basename(pkgr.package_repos)}/{os.path.basename(val)}"
448+
449+
assert expected == result_config["spack"]["repos"]
441450

442451

443452
def test_DistributionPackager_configure_package_settings(tmpdir):
@@ -449,7 +458,7 @@ def test_DistributionPackager_configure_package_settings(tmpdir):
449458
when `filter_externals` is `True`.
450459
"""
451460
good = {"all": {"prefer": ["generator=Ninja"]}}
452-
bad = {"cmake": {"externals": [{"spec": "[email protected]", "path": "/foo/bar"}]}}
461+
bad = {"cmake": {"externals": [{"spec": "[email protected]", "prefix": "/foo/bar"}]}}
453462

454463
extra_data = {"packages": {}}
455464
extra_data["packages"].update(good)

0 commit comments

Comments
 (0)