diff options
-rw-r--r-- | lib/spack/spack/cmd/config.py | 52 | ||||
-rw-r--r-- | lib/spack/spack/config.py | 4 | ||||
-rw-r--r-- | lib/spack/spack/test/cmd/config.py | 29 | ||||
-rw-r--r-- | share/spack/gitlab/cloud_pipelines/.gitlab-ci.yml | 7 |
4 files changed, 50 insertions, 42 deletions
diff --git a/lib/spack/spack/cmd/config.py b/lib/spack/spack/cmd/config.py index e7d459ff77..e7b859adb7 100644 --- a/lib/spack/spack/cmd/config.py +++ b/lib/spack/spack/cmd/config.py @@ -5,6 +5,7 @@ import collections import os import shutil +import sys from typing import List import llnl.util.filesystem as fs @@ -48,6 +49,7 @@ def setup_parser(subparser): blame_parser.add_argument( "section", help="configuration section to print\n\noptions: %(choices)s", + nargs="?", metavar="section", choices=spack.config.SECTION_SCHEMAS, ) @@ -131,32 +133,50 @@ def _get_scope_and_section(args): return scope, section +def print_configuration(args, *, blame: bool) -> None: + if args.scope and args.section is None: + tty.die(f"the argument --scope={args.scope} requires specifying a section.") + + if args.section is not None: + spack.config.CONFIG.print_section(args.section, blame=blame, scope=args.scope) + return + + print_flattened_configuration(blame=blame) + + +def print_flattened_configuration(*, blame: bool) -> None: + """Prints to stdout a flattened version of the configuration. + + Args: + blame: if True, shows file provenance for each entry in the configuration. + """ + env = ev.active_environment() + if env is not None: + pristine = env.manifest.pristine_yaml_content + flattened = pristine.copy() + flattened[spack.schema.env.TOP_LEVEL_KEY] = pristine[spack.schema.env.TOP_LEVEL_KEY].copy() + else: + flattened = syaml.syaml_dict() + flattened[spack.schema.env.TOP_LEVEL_KEY] = syaml.syaml_dict() + + for config_section in spack.config.SECTION_SCHEMAS: + current = spack.config.get(config_section) + flattened[spack.schema.env.TOP_LEVEL_KEY][config_section] = current + syaml.dump_config(flattened, stream=sys.stdout, default_flow_style=False, blame=blame) + + def config_get(args): """Dump merged YAML configuration for a specific section. With no arguments and an active environment, print the contents of the environment's manifest file (spack.yaml). """ - scope, section = _get_scope_and_section(args) - - if section is not None: - spack.config.CONFIG.print_section(section) - - elif scope and scope.startswith("env:"): - config_file = spack.config.CONFIG.get_config_filename(scope, section) - if os.path.exists(config_file): - with open(config_file) as f: - print(f.read()) - else: - tty.die("environment has no %s file" % ev.manifest_name) - - else: - tty.die("`spack config get` requires a section argument or an active environment.") + print_configuration(args, blame=False) def config_blame(args): """Print out line-by-line blame of merged YAML.""" - spack.config.CONFIG.print_section(args.section, blame=True) + print_configuration(args, blame=True) def config_edit(args): diff --git a/lib/spack/spack/config.py b/lib/spack/spack/config.py index eff978718c..b661f4dc48 100644 --- a/lib/spack/spack/config.py +++ b/lib/spack/spack/config.py @@ -699,11 +699,11 @@ class Configuration: """Iterate over scopes in this configuration.""" yield from self.scopes.values() - def print_section(self, section: str, blame: bool = False) -> None: + def print_section(self, section: str, blame: bool = False, *, scope=None) -> None: """Print a configuration to stdout.""" try: data = syaml.syaml_dict() - data[section] = self.get_config(section) + data[section] = self.get_config(section, scope=scope) syaml.dump_config(data, stream=sys.stdout, default_flow_style=False, blame=blame) except (syaml.SpackYAMLError, OSError) as e: raise ConfigError(f"cannot read '{section}' configuration") from e diff --git a/lib/spack/spack/test/cmd/config.py b/lib/spack/spack/test/cmd/config.py index 7247ce9753..bec9db3881 100644 --- a/lib/spack/spack/test/cmd/config.py +++ b/lib/spack/spack/test/cmd/config.py @@ -91,15 +91,10 @@ def test_config_edit(mutable_config, working_env): def test_config_get_gets_spack_yaml(mutable_mock_env_path): - config("get", fail_on_error=False) - assert config.returncode == 1 - with ev.create("test") as env: assert "mpileaks" not in config("get") - env.add("mpileaks") env.write() - assert "mpileaks" in config("get") @@ -122,11 +117,6 @@ def test_config_edit_fails_correctly_with_no_env(mutable_mock_env_path): assert "requires a section argument or an active environment" in output -def test_config_get_fails_correctly_with_no_env(mutable_mock_env_path): - output = config("get", fail_on_error=False) - assert "requires a section argument or an active environment" in output - - def test_config_list(): output = config("list") assert "compilers" in output @@ -470,7 +460,6 @@ def test_config_add_to_env(mutable_empty_config, mutable_mock_env_path): expected = """ config: dirty: true - """ assert expected in output @@ -497,29 +486,21 @@ spack: # comment config("add", "config:dirty:true") output = config("get") - expected = manifest - expected += """ config: - dirty: true - -""" - assert output == expected + assert "# comment" in output + assert "dirty: true" in output def test_config_remove_from_env(mutable_empty_config, mutable_mock_env_path): env("create", "test") - with ev.read("test"): config("add", "config:dirty:true") + output = config("get") + assert "dirty: true" in output with ev.read("test"): config("rm", "config:dirty") output = config("get") - - expected = ev.default_manifest_yaml() - expected += """ config: {} - -""" - assert output == expected + assert "dirty: true" not in output def test_config_update_config(config_yaml_v015): diff --git a/share/spack/gitlab/cloud_pipelines/.gitlab-ci.yml b/share/spack/gitlab/cloud_pipelines/.gitlab-ci.yml index e1d7561300..0c770ee872 100644 --- a/share/spack/gitlab/cloud_pipelines/.gitlab-ci.yml +++ b/share/spack/gitlab/cloud_pipelines/.gitlab-ci.yml @@ -150,6 +150,13 @@ default: - spack python -c "import os,sys; print(os.path.expandvars(sys.stdin.read()))" < "${SPACK_CI_CONFIG_ROOT}/${PIPELINE_MIRROR_TEMPLATE}" > "${SPACK_CI_CONFIG_ROOT}/mirrors.yaml" - spack config add -f "${SPACK_CI_CONFIG_ROOT}/mirrors.yaml" + - mkdir -p "${CI_PROJECT_DIR}/jobs_scratch_dir" + - spack + --config-scope "${SPACK_CI_CONFIG_ROOT}" + --config-scope "${SPACK_CI_CONFIG_ROOT}/${SPACK_TARGET_PLATFORM}" + --config-scope "${SPACK_CI_CONFIG_ROOT}/${SPACK_TARGET_PLATFORM}/${SPACK_TARGET_ARCH}" + ${CI_STACK_CONFIG_SCOPES} + config blame > "${CI_PROJECT_DIR}/jobs_scratch_dir/spack.yaml.blame" - spack -v --color=always --config-scope "${SPACK_CI_CONFIG_ROOT}" --config-scope "${SPACK_CI_CONFIG_ROOT}/${SPACK_TARGET_PLATFORM}" |