summaryrefslogtreecommitdiff
path: root/lib/spack/spack/cmd/mark.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/spack/spack/cmd/mark.py')
-rw-r--r--lib/spack/spack/cmd/mark.py122
1 files changed, 122 insertions, 0 deletions
diff --git a/lib/spack/spack/cmd/mark.py b/lib/spack/spack/cmd/mark.py
new file mode 100644
index 0000000000..85a22b9741
--- /dev/null
+++ b/lib/spack/spack/cmd/mark.py
@@ -0,0 +1,122 @@
+# Copyright 2013-2020 Lawrence Livermore National Security, LLC and other
+# Spack Project Developers. See the top-level COPYRIGHT file for details.
+#
+# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+
+from __future__ import print_function
+
+import sys
+
+import spack.cmd
+import spack.error
+import spack.package
+import spack.cmd.common.arguments as arguments
+import spack.repo
+import spack.store
+from spack.database import InstallStatuses
+
+from llnl.util import tty
+
+description = "mark packages as explicitly or implicitly installed"
+section = "admin"
+level = "long"
+
+error_message = """You can either:
+ a) use a more specific spec, or
+ b) use `spack mark --all` to mark ALL matching specs.
+"""
+
+# Arguments for display_specs when we find ambiguity
+display_args = {
+ 'long': True,
+ 'show_flags': False,
+ 'variants': False,
+ 'indent': 4,
+}
+
+
+def setup_parser(subparser):
+ arguments.add_common_arguments(
+ subparser, ['installed_specs'])
+ subparser.add_argument(
+ '-a', '--all', action='store_true', dest='all',
+ help="Mark ALL installed packages that match each "
+ "supplied spec. If you `mark --all libelf`,"
+ " ALL versions of `libelf` are marked. If no spec is "
+ "supplied, all installed packages will be marked.")
+ exim = subparser.add_mutually_exclusive_group(required=True)
+ exim.add_argument(
+ '-e', '--explicit', action='store_true', dest='explicit',
+ help="Mark packages as explicitly installed.")
+ exim.add_argument(
+ '-i', '--implicit', action='store_true', dest='implicit',
+ help="Mark packages as implicitly installed.")
+
+
+def find_matching_specs(specs, allow_multiple_matches=False):
+ """Returns a list of specs matching the not necessarily
+ concretized specs given from cli
+
+ Args:
+ specs (list): list of specs to be matched against installed packages
+ allow_multiple_matches (bool): if True multiple matches are admitted
+
+ Return:
+ list of specs
+ """
+ # List of specs that match expressions given via command line
+ specs_from_cli = []
+ has_errors = False
+
+ for spec in specs:
+ install_query = [InstallStatuses.INSTALLED]
+ matching = spack.store.db.query_local(spec, installed=install_query)
+ # For each spec provided, make sure it refers to only one package.
+ # Fail and ask user to be unambiguous if it doesn't
+ if not allow_multiple_matches and len(matching) > 1:
+ tty.error('{0} matches multiple packages:'.format(spec))
+ sys.stderr.write('\n')
+ spack.cmd.display_specs(matching, output=sys.stderr,
+ **display_args)
+ sys.stderr.write('\n')
+ sys.stderr.flush()
+ has_errors = True
+
+ # No installed package matches the query
+ if len(matching) == 0 and spec is not any:
+ tty.die('{0} does not match any installed packages.'.format(spec))
+
+ specs_from_cli.extend(matching)
+
+ if has_errors:
+ tty.die(error_message)
+
+ return specs_from_cli
+
+
+def do_mark(specs, explicit):
+ """Marks all the specs in a list.
+
+ Args:
+ specs (list): list of specs to be marked
+ explicit (bool): whether to mark specs as explicitly installed
+ """
+ for spec in specs:
+ spack.store.db.update_explicit(spec, explicit)
+
+
+def mark_specs(args, specs):
+ mark_list = find_matching_specs(specs, args.all)
+
+ # Mark everything on the list
+ do_mark(mark_list, args.explicit)
+
+
+def mark(parser, args):
+ if not args.specs and not args.all:
+ tty.die('mark requires at least one package argument.',
+ ' Use `spack mark --all` to mark ALL packages.')
+
+ # [any] here handles the --all case by forcing all specs to be returned
+ specs = spack.cmd.parse_specs(args.specs) if args.specs else [any]
+ mark_specs(args, specs)