summaryrefslogtreecommitdiff
path: root/lib/spack/spack/cmd/config.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/spack/spack/cmd/config.py')
-rw-r--r--lib/spack/spack/cmd/config.py285
1 files changed, 144 insertions, 141 deletions
diff --git a/lib/spack/spack/cmd/config.py b/lib/spack/spack/cmd/config.py
index c6eca2fd8a..f36dffd40a 100644
--- a/lib/spack/spack/cmd/config.py
+++ b/lib/spack/spack/cmd/config.py
@@ -32,89 +32,92 @@ def setup_parser(subparser):
# User can only choose one
subparser.add_argument(
- '--scope', choices=scopes, metavar=scopes_metavar,
- help="configuration scope to read/modify")
+ "--scope",
+ choices=scopes,
+ metavar=scopes_metavar,
+ help="configuration scope to read/modify",
+ )
- sp = subparser.add_subparsers(metavar='SUBCOMMAND', dest='config_command')
+ sp = subparser.add_subparsers(metavar="SUBCOMMAND", dest="config_command")
- get_parser = sp.add_parser('get', help='print configuration values')
- get_parser.add_argument('section',
- help="configuration section to print. "
- "options: %(choices)s",
- nargs='?',
- metavar='section',
- choices=spack.config.section_schemas)
+ get_parser = sp.add_parser("get", help="print configuration values")
+ get_parser.add_argument(
+ "section",
+ help="configuration section to print. " "options: %(choices)s",
+ nargs="?",
+ metavar="section",
+ choices=spack.config.section_schemas,
+ )
blame_parser = sp.add_parser(
- 'blame', help='print configuration annotated with source file:line')
- blame_parser.add_argument('section',
- help="configuration section to print. "
- "options: %(choices)s",
- metavar='section',
- choices=spack.config.section_schemas)
-
- edit_parser = sp.add_parser('edit', help='edit configuration file')
- edit_parser.add_argument('section',
- help="configuration section to edit. "
- "options: %(choices)s",
- metavar='section',
- nargs='?',
- choices=spack.config.section_schemas)
+ "blame", help="print configuration annotated with source file:line"
+ )
+ blame_parser.add_argument(
+ "section",
+ help="configuration section to print. " "options: %(choices)s",
+ metavar="section",
+ choices=spack.config.section_schemas,
+ )
+
+ edit_parser = sp.add_parser("edit", help="edit configuration file")
+ edit_parser.add_argument(
+ "section",
+ help="configuration section to edit. " "options: %(choices)s",
+ metavar="section",
+ nargs="?",
+ choices=spack.config.section_schemas,
+ )
edit_parser.add_argument(
- '--print-file', action='store_true',
- help="print the file name that would be edited")
+ "--print-file", action="store_true", help="print the file name that would be edited"
+ )
- sp.add_parser('list', help='list configuration sections')
+ sp.add_parser("list", help="list configuration sections")
- add_parser = sp.add_parser('add', help='add configuration parameters')
- add_parser.add_argument(
- 'path', nargs='?',
- help="colon-separated path to config that should be added,"
- " e.g. 'config:default:true'")
+ add_parser = sp.add_parser("add", help="add configuration parameters")
add_parser.add_argument(
- '-f', '--file',
- help="file from which to set all config values"
+ "path",
+ nargs="?",
+ help="colon-separated path to config that should be added," " e.g. 'config:default:true'",
)
+ add_parser.add_argument("-f", "--file", help="file from which to set all config values")
prefer_upstream_parser = sp.add_parser(
- 'prefer-upstream',
- help='set package preferences from upstream')
+ "prefer-upstream", help="set package preferences from upstream"
+ )
prefer_upstream_parser.add_argument(
- '--local', action='store_true', default=False,
- help="Set packages preferences based on local installs, rather "
- "than upstream."
+ "--local",
+ action="store_true",
+ default=False,
+ help="Set packages preferences based on local installs, rather " "than upstream.",
)
- remove_parser = sp.add_parser('remove', aliases=['rm'],
- help='remove configuration parameters')
+ remove_parser = sp.add_parser("remove", aliases=["rm"], help="remove configuration parameters")
remove_parser.add_argument(
- 'path',
+ "path",
help="colon-separated path to config that should be removed,"
- " e.g. 'config:default:true'")
+ " e.g. 'config:default:true'",
+ )
# Make the add parser available later
setup_parser.add_parser = add_parser
- update = sp.add_parser(
- 'update', help='update configuration files to the latest format'
- )
- spack.cmd.common.arguments.add_common_arguments(update, ['yes_to_all'])
- update.add_argument('section', help='section to update')
+ update = sp.add_parser("update", help="update configuration files to the latest format")
+ spack.cmd.common.arguments.add_common_arguments(update, ["yes_to_all"])
+ update.add_argument("section", help="section to update")
revert = sp.add_parser(
- 'revert',
- help='revert configuration files to their state before update'
+ "revert", help="revert configuration files to their state before update"
)
- spack.cmd.common.arguments.add_common_arguments(revert, ['yes_to_all'])
- revert.add_argument('section', help='section to update')
+ spack.cmd.common.arguments.add_common_arguments(revert, ["yes_to_all"])
+ revert.add_argument("section", help="section to update")
def _get_scope_and_section(args):
"""Extract config scope and section from arguments."""
scope = args.scope
- section = getattr(args, 'section', None)
- path = getattr(args, 'path', None)
+ section = getattr(args, "section", None)
+ path = getattr(args, "path", None)
# w/no args and an active environment, point to env manifest
if not section:
@@ -128,7 +131,7 @@ def _get_scope_and_section(args):
# special handling for commands that take value instead of section
if path:
- section = path[:path.find(':')] if ':' in path else path
+ section = path[: path.find(":")] if ":" in path else path
if not scope:
scope = spack.config.default_modify_scope(section)
@@ -146,17 +149,16 @@ def config_get(args):
if section is not None:
spack.config.config.print_section(section)
- elif scope and scope.startswith('env:'):
+ 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)
+ tty.die("environment has no %s file" % ev.manifest_name)
else:
- tty.die('`spack config get` requires a section argument '
- 'or an active environment.')
+ tty.die("`spack config get` requires a section argument " "or an active environment.")
def config_blame(args):
@@ -179,8 +181,7 @@ def config_edit(args):
# If we aren't editing a spack.yaml file, get config path from scope.
scope, section = _get_scope_and_section(args)
if not scope and not section:
- tty.die('`spack config edit` requires a section argument '
- 'or an active environment.')
+ tty.die("`spack config edit` requires a section argument " "or an active environment.")
config_file = spack.config.config.get_config_filename(scope, section)
if args.print_file:
@@ -194,7 +195,7 @@ def config_list(args):
Used primarily for shell tab completion scripts.
"""
- print(' '.join(list(spack.config.section_schemas)))
+ print(" ".join(list(spack.config.section_schemas)))
def config_add(args):
@@ -221,11 +222,11 @@ def config_remove(args):
This is a stateful operation that edits the config files."""
scope, _ = _get_scope_and_section(args)
- path, _, value = args.path.rpartition(':')
+ path, _, value = args.path.rpartition(":")
existing = spack.config.get(path, scope=scope)
if not isinstance(existing, (list, dict)):
- path, _, value = path.rpartition(':')
+ path, _, value = path.rpartition(":")
existing = spack.config.get(path, scope=scope)
value = syaml.load(value)
@@ -238,7 +239,7 @@ def config_remove(args):
existing.pop(value, None)
else:
# This should be impossible to reach
- raise spack.config.ConfigError('Config has nested non-dict values')
+ raise spack.config.ConfigError("Config has nested non-dict values")
spack.config.set(path, existing, scope)
@@ -256,31 +257,33 @@ def config_update(args):
cannot_overwrite, skip_system_scope = [], False
for scope in updates:
- cfg_file = spack.config.config.get_config_filename(
- scope.name, args.section
- )
+ cfg_file = spack.config.config.get_config_filename(scope.name, args.section)
scope_dir = scope.path
can_be_updated = _can_update_config_file(scope_dir, cfg_file)
if not can_be_updated:
- if scope.name == 'system':
+ if scope.name == "system":
skip_system_scope = True
- msg = ('Not enough permissions to write to "system" scope. '
- 'Skipping update at that location [cfg={0}]')
+ msg = (
+ 'Not enough permissions to write to "system" scope. '
+ "Skipping update at that location [cfg={0}]"
+ )
tty.warn(msg.format(cfg_file))
continue
cannot_overwrite.append((scope, cfg_file))
if cannot_overwrite:
- msg = 'Detected permission issues with the following scopes:\n\n'
+ msg = "Detected permission issues with the following scopes:\n\n"
for scope, cfg_file in cannot_overwrite:
- msg += '\t[scope={0}, cfg={1}]\n'.format(scope.name, cfg_file)
- msg += ('\nEither ensure that you have sufficient permissions to '
- 'modify these files or do not include these scopes in the '
- 'update.')
+ msg += "\t[scope={0}, cfg={1}]\n".format(scope.name, cfg_file)
+ msg += (
+ "\nEither ensure that you have sufficient permissions to "
+ "modify these files or do not include these scopes in the "
+ "update."
+ )
tty.die(msg)
if skip_system_scope:
- updates = [x for x in updates if x.name != 'system']
+ updates = [x for x in updates if x.name != "system"]
# Report if there are no updates to be done
if not updates:
@@ -290,40 +293,38 @@ def config_update(args):
proceed = True
if not args.yes_to_all:
- msg = ('The following configuration files are going to be updated to'
- ' the latest schema format:\n\n')
+ msg = (
+ "The following configuration files are going to be updated to"
+ " the latest schema format:\n\n"
+ )
for scope in updates:
- cfg_file = spack.config.config.get_config_filename(
- scope.name, args.section
- )
- msg += '\t[scope={0}, file={1}]\n'.format(scope.name, cfg_file)
- msg += ('\nIf the configuration files are updated, versions of Spack '
- 'that are older than this version may not be able to read '
- 'them. Spack stores backups of the updated files which can '
- 'be retrieved with "spack config revert"')
+ cfg_file = spack.config.config.get_config_filename(scope.name, args.section)
+ msg += "\t[scope={0}, file={1}]\n".format(scope.name, cfg_file)
+ msg += (
+ "\nIf the configuration files are updated, versions of Spack "
+ "that are older than this version may not be able to read "
+ "them. Spack stores backups of the updated files which can "
+ 'be retrieved with "spack config revert"'
+ )
tty.msg(msg)
- proceed = tty.get_yes_or_no('Do you want to proceed?', default=False)
+ proceed = tty.get_yes_or_no("Do you want to proceed?", default=False)
if not proceed:
- tty.die('Operation aborted.')
+ tty.die("Operation aborted.")
# Get a function to update the format
update_fn = spack.config.ensure_latest_format_fn(args.section)
for scope in updates:
- cfg_file = spack.config.config.get_config_filename(
- scope.name, args.section
- )
+ cfg_file = spack.config.config.get_config_filename(scope.name, args.section)
with open(cfg_file) as f:
data = syaml.load_config(f) or {}
data = data.pop(args.section, {})
update_fn(data)
# Make a backup copy and rewrite the file
- bkp_file = cfg_file + '.bkp'
+ bkp_file = cfg_file + ".bkp"
shutil.copy(cfg_file, bkp_file)
- spack.config.config.update_config(
- args.section, data, scope=scope.name, force=True
- )
+ spack.config.config.update_config(args.section, data, scope=scope.name, force=True)
msg = 'File "{0}" updated [backup={1}]'
tty.msg(msg.format(cfg_file, bkp_file))
@@ -336,16 +337,14 @@ def _can_revert_update(scope_dir, cfg_file, bkp_file):
def config_revert(args):
- scopes = [args.scope] if args.scope else [
- x.name for x in spack.config.config.file_scopes
- ]
+ scopes = [args.scope] if args.scope else [x.name for x in spack.config.config.file_scopes]
# Search for backup files in the configuration scopes
- Entry = collections.namedtuple('Entry', ['scope', 'cfg', 'bkp'])
+ Entry = collections.namedtuple("Entry", ["scope", "cfg", "bkp"])
to_be_restored, cannot_overwrite = [], []
for scope in scopes:
cfg_file = spack.config.config.get_config_filename(scope, args.section)
- bkp_file = cfg_file + '.bkp'
+ bkp_file = cfg_file + ".bkp"
# If the backup files doesn't exist move to the next scope
if not os.path.exists(bkp_file):
@@ -364,25 +363,26 @@ def config_revert(args):
# Report errors if we can't revert a configuration
if cannot_overwrite:
- msg = 'Detected permission issues with the following scopes:\n\n'
+ msg = "Detected permission issues with the following scopes:\n\n"
for e in cannot_overwrite:
- msg += '\t[scope={0.scope}, cfg={0.cfg}, bkp={0.bkp}]\n'.format(e)
- msg += ('\nEither ensure to have the right permissions before retrying'
- ' or be more specific on the scope to revert.')
+ msg += "\t[scope={0.scope}, cfg={0.cfg}, bkp={0.bkp}]\n".format(e)
+ msg += (
+ "\nEither ensure to have the right permissions before retrying"
+ " or be more specific on the scope to revert."
+ )
tty.die(msg)
proceed = True
if not args.yes_to_all:
- msg = ('The following scopes will be restored from the corresponding'
- ' backup files:\n')
+ msg = "The following scopes will be restored from the corresponding" " backup files:\n"
for entry in to_be_restored:
- msg += '\t[scope={0.scope}, bkp={0.bkp}]\n'.format(entry)
- msg += 'This operation cannot be undone.'
+ msg += "\t[scope={0.scope}, bkp={0.bkp}]\n".format(entry)
+ msg += "This operation cannot be undone."
tty.msg(msg)
- proceed = tty.get_yes_or_no('Do you want to proceed?', default=False)
+ proceed = tty.get_yes_or_no("Do you want to proceed?", default=False)
if not proceed:
- tty.die('Operation aborted.')
+ tty.die("Operation aborted.")
for _, cfg_file, bkp_file in to_be_restored:
shutil.copy(bkp_file, cfg_file)
@@ -397,7 +397,7 @@ def config_prefer_upstream(args):
scope = args.scope
if scope is None:
- scope = spack.config.default_modify_scope('packages')
+ scope = spack.config.default_modify_scope("packages")
all_specs = set(spack.store.db.query(installed=True))
local_specs = set(spack.store.db.query_local(installed=True))
@@ -408,58 +408,61 @@ def config_prefer_upstream(args):
pkgs = {}
for spec in pref_specs:
# Collect all the upstream compilers and versions for this package.
- pkg = pkgs.get(spec.name, {
- 'version': [],
- 'compiler': [],
- })
+ pkg = pkgs.get(
+ spec.name,
+ {
+ "version": [],
+ "compiler": [],
+ },
+ )
pkgs[spec.name] = pkg
# We have no existing variant if this is our first added version.
- existing_variants = pkg.get('variants',
- None if not pkg['version'] else '')
+ existing_variants = pkg.get("variants", None if not pkg["version"] else "")
version = spec.version.string
- if version not in pkg['version']:
- pkg['version'].append(version)
+ if version not in pkg["version"]:
+ pkg["version"].append(version)
compiler = str(spec.compiler)
- if compiler not in pkg['compiler']:
- pkg['compiler'].append(compiler)
+ if compiler not in pkg["compiler"]:
+ pkg["compiler"].append(compiler)
# Get and list all the variants that differ from the default.
variants = []
for var_name, variant in spec.variants.items():
- if (var_name in ['patches']
- or var_name not in spec.package.variants):
+ if var_name in ["patches"] or var_name not in spec.package.variants:
continue
variant_desc, _ = spec.package.variants[var_name]
if variant.value != variant_desc.default:
variants.append(str(variant))
variants.sort()
- variants = ' '.join(variants)
+ variants = " ".join(variants)
if spec.name not in conflicting_variants:
# Only specify the variants if there's a single variant
# set across all versions/compilers.
if existing_variants is not None and existing_variants != variants:
conflicting_variants.add(spec.name)
- pkg.pop('variants', None)
+ pkg.pop("variants", None)
elif variants:
- pkg['variants'] = variants
+ pkg["variants"] = variants
if conflicting_variants:
tty.warn(
"The following packages have multiple conflicting upstream "
"specs. You may have to specify, by "
"concretized hash, which spec you want when building "
- "packages that depend on them:\n - {0}"
- .format("\n - ".join(sorted(conflicting_variants))))
+ "packages that depend on them:\n - {0}".format(
+ "\n - ".join(sorted(conflicting_variants))
+ )
+ )
# Simply write the config to the specified file.
- existing = spack.config.get('packages', scope=scope)
+ existing = spack.config.get("packages", scope=scope)
new = spack.config.merge_yaml(existing, pkgs)
- spack.config.set('packages', new, scope)
+ spack.config.set("packages", new, scope)
config_file = spack.config.config.get_config_filename(scope, section)
tty.msg("Updated config at {0}".format(config_file))
@@ -467,15 +470,15 @@ def config_prefer_upstream(args):
def config(parser, args):
action = {
- 'get': config_get,
- 'blame': config_blame,
- 'edit': config_edit,
- 'list': config_list,
- 'add': config_add,
- 'rm': config_remove,
- 'remove': config_remove,
- 'update': config_update,
- 'revert': config_revert,
- 'prefer-upstream': config_prefer_upstream,
+ "get": config_get,
+ "blame": config_blame,
+ "edit": config_edit,
+ "list": config_list,
+ "add": config_add,
+ "rm": config_remove,
+ "remove": config_remove,
+ "update": config_update,
+ "revert": config_revert,
+ "prefer-upstream": config_prefer_upstream,
}
action[args.config_command](args)