summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGreg Becker <becker33@llnl.gov>2024-03-28 08:00:55 -0700
committerGitHub <noreply@github.com>2024-03-28 10:00:55 -0500
commit7e906ced75dead665048a254c0ca2f09205c9d47 (patch)
tree8a8d749e8336adc9e25f557967f812e16f87b9f6 /lib
parent647e89f6bc3e46d2104e43241697f73c7e1c464d (diff)
downloadspack-7e906ced75dead665048a254c0ca2f09205c9d47.tar.gz
spack-7e906ced75dead665048a254c0ca2f09205c9d47.tar.bz2
spack-7e906ced75dead665048a254c0ca2f09205c9d47.tar.xz
spack-7e906ced75dead665048a254c0ca2f09205c9d47.zip
spack find: add options for local/upstream only (#42999)
Users requested an option to filter between local/upstream results in `spack find` output. ``` # default behavior, same as without --install-tree argument $ spack find --install-tree all # show only local results $ spack find --install-tree local # show results from all upstreams $ spack find --install-tree upstream # show results from a particular upstream or the local install_tree $ spack find --install-tree /path/to/install/tree/root ``` --------- Co-authored-by: becker33 <becker33@users.noreply.github.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/cmd/find.py12
-rw-r--r--lib/spack/spack/database.py23
-rw-r--r--lib/spack/spack/test/cmd/find.py2
-rw-r--r--lib/spack/spack/test/database.py28
4 files changed, 58 insertions, 7 deletions
diff --git a/lib/spack/spack/cmd/find.py b/lib/spack/spack/cmd/find.py
index 070ac9bd0e..f8e74f262f 100644
--- a/lib/spack/spack/cmd/find.py
+++ b/lib/spack/spack/cmd/find.py
@@ -140,6 +140,12 @@ def setup_parser(subparser):
subparser.add_argument(
"--only-deprecated", action="store_true", help="show only deprecated packages"
)
+ subparser.add_argument(
+ "--install-tree",
+ action="store",
+ default="all",
+ help="Install trees to query: 'all' (default), 'local', 'upstream', upstream name or path",
+ )
subparser.add_argument("--start-date", help="earliest date of installation [YYYY-MM-DD]")
subparser.add_argument("--end-date", help="latest date of installation [YYYY-MM-DD]")
@@ -168,6 +174,12 @@ def query_arguments(args):
q_args = {"installed": installed, "known": known, "explicit": explicit}
+ install_tree = args.install_tree
+ upstreams = spack.config.get("upstreams", {})
+ if install_tree in upstreams.keys():
+ install_tree = upstreams[install_tree]["install_tree"]
+ q_args["install_tree"] = install_tree
+
# Time window of installation
for attribute in ("start_date", "end_date"):
date = getattr(args, attribute)
diff --git a/lib/spack/spack/database.py b/lib/spack/spack/database.py
index c2f0567d22..e2f9e57e82 100644
--- a/lib/spack/spack/database.py
+++ b/lib/spack/spack/database.py
@@ -1621,15 +1621,32 @@ class Database:
query_local.__doc__ += _QUERY_DOCSTRING
def query(self, *args, **kwargs):
- """Query the Spack database including all upstream databases."""
+ """Query the Spack database including all upstream databases.
+
+ Additional Arguments:
+ install_tree (str): query 'all' (default), 'local', 'upstream', or upstream path
+ """
+ install_tree = kwargs.pop("install_tree", "all")
+ valid_trees = ["all", "upstream", "local", self.root] + [u.root for u in self.upstream_dbs]
+ if install_tree not in valid_trees:
+ msg = "Invalid install_tree argument to Database.query()\n"
+ msg += f"Try one of {', '.join(valid_trees)}"
+ tty.error(msg)
+ return []
+
upstream_results = []
- for upstream_db in self.upstream_dbs:
+ upstreams = self.upstream_dbs
+ if install_tree not in ("all", "upstream"):
+ upstreams = [u for u in self.upstream_dbs if u.root == install_tree]
+ for upstream_db in upstreams:
# queries for upstream DBs need to *not* lock - we may not
# have permissions to do this and the upstream DBs won't know about
# us anyway (so e.g. they should never uninstall specs)
upstream_results.extend(upstream_db._query(*args, **kwargs) or [])
- local_results = set(self.query_local(*args, **kwargs))
+ local_results = []
+ if install_tree in ("all", "local") or self.root == install_tree:
+ local_results = set(self.query_local(*args, **kwargs))
results = list(local_results) + list(x for x in upstream_results if x not in local_results)
diff --git a/lib/spack/spack/test/cmd/find.py b/lib/spack/spack/test/cmd/find.py
index 5d551e6df9..e42a938e38 100644
--- a/lib/spack/spack/test/cmd/find.py
+++ b/lib/spack/spack/test/cmd/find.py
@@ -64,6 +64,7 @@ def test_query_arguments():
implicit=False,
start_date="2018-02-23",
end_date=None,
+ install_tree="all",
)
q_args = query_arguments(args)
@@ -75,6 +76,7 @@ def test_query_arguments():
assert q_args["explicit"] is any
assert "start_date" in q_args
assert "end_date" not in q_args
+ assert q_args["install_tree"] == "all"
# Check that explicit works correctly
args.explicit = True
diff --git a/lib/spack/spack/test/database.py b/lib/spack/spack/test/database.py
index e02f549532..0b611e93e3 100644
--- a/lib/spack/spack/test/database.py
+++ b/lib/spack/spack/test/database.py
@@ -56,11 +56,31 @@ def upstream_and_downstream_db(tmpdir, gen_mock_layout):
yield upstream_write_db, upstream_db, upstream_layout, downstream_db, downstream_layout
+@pytest.mark.parametrize(
+ "install_tree,result",
+ [("all", ["b", "c"]), ("upstream", ["c"]), ("local", ["b"]), ("{u}", ["c"]), ("{d}", ["b"])],
+)
+def test_query_by_install_tree(
+ install_tree, result, upstream_and_downstream_db, mock_packages, monkeypatch, config
+):
+ up_write_db, up_db, up_layout, down_db, down_layout = upstream_and_downstream_db
+
+ # Set the upstream DB to contain "c" and downstream to contain "b")
+ b = spack.spec.Spec("b").concretized()
+ c = spack.spec.Spec("c").concretized()
+ up_write_db.add(c, up_layout)
+ up_db._read()
+ down_db.add(b, down_layout)
+
+ specs = down_db.query(install_tree=install_tree.format(u=up_db.root, d=down_db.root))
+ assert [s.name for s in specs] == result
+
+
def test_spec_installed_upstream(
upstream_and_downstream_db, mock_custom_repository, config, monkeypatch
):
"""Test whether Spec.installed_upstream() works."""
- (upstream_write_db, upstream_db, upstream_layout, downstream_db, downstream_layout) = (
+ upstream_write_db, upstream_db, upstream_layout, downstream_db, downstream_layout = (
upstream_and_downstream_db
)
@@ -86,7 +106,7 @@ def test_spec_installed_upstream(
@pytest.mark.usefixtures("config")
def test_installed_upstream(upstream_and_downstream_db, tmpdir):
- (upstream_write_db, upstream_db, upstream_layout, downstream_db, downstream_layout) = (
+ upstream_write_db, upstream_db, upstream_layout, downstream_db, downstream_layout = (
upstream_and_downstream_db
)
@@ -124,7 +144,7 @@ def test_installed_upstream(upstream_and_downstream_db, tmpdir):
@pytest.mark.usefixtures("config")
def test_removed_upstream_dep(upstream_and_downstream_db, tmpdir):
- (upstream_write_db, upstream_db, upstream_layout, downstream_db, downstream_layout) = (
+ upstream_write_db, upstream_db, upstream_layout, downstream_db, downstream_layout = (
upstream_and_downstream_db
)
@@ -156,7 +176,7 @@ def test_add_to_upstream_after_downstream(upstream_and_downstream_db, tmpdir):
DB. When a package is recorded as installed in both, the results should
refer to the downstream DB.
"""
- (upstream_write_db, upstream_db, upstream_layout, downstream_db, downstream_layout) = (
+ upstream_write_db, upstream_db, upstream_layout, downstream_db, downstream_layout = (
upstream_and_downstream_db
)