Skip to content
Snippets Groups Projects
Unverified Commit 31f660bd authored by Massimiliano Culpo's avatar Massimiliano Culpo Committed by GitHub
Browse files

Improve output of the external find command (#18017)

This commit adds output to the "spack external find"
command to inform users of the result of the operation.

It also fixes a bug introduced in #17804 due to the fact
that a function was not updated to conform to the new
packages.yaml format (_get_predefined_externals).
parent c0342e41
No related branches found
No related tags found
No related merge requests found
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
import llnl.util.tty.colify as colify import llnl.util.tty.colify as colify
import six import six
import spack import spack
import spack.cmd
import spack.error import spack.error
import spack.util.environment import spack.util.environment
import spack.util.spack_yaml as syaml import spack.util.spack_yaml as syaml
...@@ -146,7 +147,17 @@ def external_find(args): ...@@ -146,7 +147,17 @@ def external_find(args):
packages_to_check = spack.repo.path.all_packages() packages_to_check = spack.repo.path.all_packages()
pkg_to_entries = _get_external_packages(packages_to_check) pkg_to_entries = _get_external_packages(packages_to_check)
_update_pkg_config(pkg_to_entries, args.not_buildable) new_entries, write_scope = _update_pkg_config(
pkg_to_entries, args.not_buildable
)
if new_entries:
path = spack.config.config.get_config_filename(write_scope, 'packages')
msg = ('The following specs have been detected on this system '
'and added to {0}')
tty.msg(msg.format(path))
spack.cmd.display_specs(new_entries)
else:
tty.msg('No new external packages detected')
def _group_by_prefix(paths): def _group_by_prefix(paths):
...@@ -188,23 +199,24 @@ def _get_predefined_externals(): ...@@ -188,23 +199,24 @@ def _get_predefined_externals():
pkg_config = spack.config.get('packages') pkg_config = spack.config.get('packages')
already_defined_specs = set() already_defined_specs = set()
for pkg_name, per_pkg_cfg in pkg_config.items(): for pkg_name, per_pkg_cfg in pkg_config.items():
paths = per_pkg_cfg.get('paths', {}) for item in per_pkg_cfg.get('externals', []):
already_defined_specs.update(spack.spec.Spec(k) for k in paths) already_defined_specs.add(spack.spec.Spec(item['spec']))
modules = per_pkg_cfg.get('modules', {})
already_defined_specs.update(spack.spec.Spec(k) for k in modules)
return already_defined_specs return already_defined_specs
def _update_pkg_config(pkg_to_entries, not_buildable): def _update_pkg_config(pkg_to_entries, not_buildable):
predefined_external_specs = _get_predefined_externals() predefined_external_specs = _get_predefined_externals()
pkg_to_cfg = {} pkg_to_cfg, all_new_specs = {}, []
for pkg_name, ext_pkg_entries in pkg_to_entries.items(): for pkg_name, ext_pkg_entries in pkg_to_entries.items():
new_entries = list( new_entries = list(
e for e in ext_pkg_entries e for e in ext_pkg_entries
if (e.spec not in predefined_external_specs)) if (e.spec not in predefined_external_specs))
pkg_config = _generate_pkg_config(new_entries) pkg_config = _generate_pkg_config(new_entries)
all_new_specs.extend([
spack.spec.Spec(x['spec']) for x in pkg_config.get('externals', [])
])
if not_buildable: if not_buildable:
pkg_config['buildable'] = False pkg_config['buildable'] = False
pkg_to_cfg[pkg_name] = pkg_config pkg_to_cfg[pkg_name] = pkg_config
...@@ -215,6 +227,8 @@ def _update_pkg_config(pkg_to_entries, not_buildable): ...@@ -215,6 +227,8 @@ def _update_pkg_config(pkg_to_entries, not_buildable):
spack.config.merge_yaml(pkgs_cfg, pkg_to_cfg) spack.config.merge_yaml(pkgs_cfg, pkg_to_cfg)
spack.config.set('packages', pkgs_cfg, scope=cfg_scope) spack.config.set('packages', pkgs_cfg, scope=cfg_scope)
return all_new_specs, cfg_scope
def _get_external_packages(packages_to_check, system_path_to_exe=None): def _get_external_packages(packages_to_check, system_path_to_exe=None):
if not system_path_to_exe: if not system_path_to_exe:
......
...@@ -222,3 +222,21 @@ def _determine_variants(cls, exes, version_str): ...@@ -222,3 +222,21 @@ def _determine_variants(cls, exes, version_str):
externals = packages_yaml['gcc']['externals'] externals = packages_yaml['gcc']['externals']
assert len(externals) == 1 assert len(externals) == 1
assert externals[0]['prefix'] == '/opt/gcc/bin' assert externals[0]['prefix'] == '/opt/gcc/bin'
def test_new_entries_are_reported_correctly(
mock_executable, mutable_config, monkeypatch
):
# Prepare an environment to detect a fake gcc
gcc_exe = mock_executable('gcc', output="echo 4.2.1")
prefix = os.path.dirname(gcc_exe)
monkeypatch.setenv('PATH', prefix)
# The first run will find and add the external gcc
output = external('find', 'gcc')
assert 'The following specs have been' in output
# The second run should report that no new external
# has been found
output = external('find', 'gcc')
assert 'No new external packages detected' in output
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment