From 8c50b44bfeb34bda1ea45175d50a69aad3c7ee83 Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Tue, 4 Oct 2022 10:56:46 -0700 Subject: `find`/`list`: display package counts last (#32946) * find/list: display package counts last We have over 6,600 packages now, and `spack list` still displays the number of packages before it lists them all. This is useless for large sets of results (e.g., with no args) as the number has scrolled way off the screen before you can see it. The same is true for `spack find` with large installations. This PR changes `spack find` and `spack list` so that they display the package count last. * add some quick testing Co-authored-by: Danny McClanahan <1305167+cosmicexplorer@users.noreply.github.com> --- lib/spack/spack/cmd/find.py | 24 ++++++++++++++++++++---- lib/spack/spack/cmd/list.py | 4 ++-- lib/spack/spack/test/cmd/find.py | 14 ++++++++++++++ lib/spack/spack/test/cmd/list.py | 12 ++++++++++++ lib/spack/spack/test/conftest.py | 5 +++++ 5 files changed, 53 insertions(+), 6 deletions(-) diff --git a/lib/spack/spack/cmd/find.py b/lib/spack/spack/cmd/find.py index aea5829975..0b974539af 100644 --- a/lib/spack/spack/cmd/find.py +++ b/lib/spack/spack/cmd/find.py @@ -203,7 +203,16 @@ def setup_env(env): return decorator, added, roots, removed -def display_env(env, args, decorator): +def display_env(env, args, decorator, results): + """Display extra find output when running in an environment. + + Find in an environment outputs 2 or 3 sections: + + 1. Root specs + 2. Concretized roots (if asked for with -c) + 3. Installed specs + + """ tty.msg("In environment %s" % env.name) if not env.user_specs: @@ -234,6 +243,12 @@ def display_env(env, args, decorator): cmd.display_specs(env.specs_by_hash.values(), args, decorator=decorator) print() + # Display a header for the installed packages section IF there are installed + # packages. If there aren't any, we'll just end up printing "0 installed packages" + # later. + if results: + tty.msg("Installed packages") + def find(parser, args): if args.bootstrap: @@ -286,10 +301,11 @@ def _find(parser, args): else: if not args.format: if env: - display_env(env, args, decorator) + display_env(env, args, decorator, results) + cmd.display_specs(results, args, decorator=decorator, all_headers=True) + + # print number of installed packages last (as the list may be long) if sys.stdout.isatty() and args.groups: pkg_type = "loaded" if args.loaded else "installed" spack.cmd.print_how_many_pkgs(results, pkg_type) - - cmd.display_specs(results, args, decorator=decorator, all_headers=True) diff --git a/lib/spack/spack/cmd/list.py b/lib/spack/spack/cmd/list.py index 54f8e890f4..6bb5da7196 100644 --- a/lib/spack/spack/cmd/list.py +++ b/lib/spack/spack/cmd/list.py @@ -122,9 +122,9 @@ def filter_by_name(pkgs, args): @formatter def name_only(pkgs, out): indent = 0 - if out.isatty(): - tty.msg("%d packages." % len(pkgs)) colify(pkgs, indent=indent, output=out) + if out.isatty(): + tty.msg("%d packages" % len(pkgs)) def github_url(pkg): diff --git a/lib/spack/spack/test/cmd/find.py b/lib/spack/spack/test/cmd/find.py index 0047f9da23..b313a36446 100644 --- a/lib/spack/spack/test/cmd/find.py +++ b/lib/spack/spack/test/cmd/find.py @@ -7,6 +7,7 @@ import argparse import json import os import sys +from textwrap import dedent import pytest @@ -128,6 +129,19 @@ def test_namespaces_shown_correctly(database): assert "builtin.mock.zmpi" in out +@pytest.mark.db +def test_find_cli_output_format(database, mock_tty_stdout): + out = find("zmpi") + assert out.endswith( + dedent( + """\ + zmpi@1.0 + ==> 1 installed package + """ + ) + ) + + def _check_json_output(spec_list): assert len(spec_list) == 3 assert all(spec["name"] == "mpileaks" for spec in spec_list) diff --git a/lib/spack/spack/test/cmd/list.py b/lib/spack/spack/test/cmd/list.py index 924ef140b3..ed5b2574f0 100644 --- a/lib/spack/spack/test/cmd/list.py +++ b/lib/spack/spack/test/cmd/list.py @@ -3,6 +3,8 @@ # # SPDX-License-Identifier: (Apache-2.0 OR MIT) +from textwrap import dedent + from spack.main import SpackCommand list = SpackCommand("list") @@ -14,6 +16,16 @@ def test_list(): assert "hdf5" in output +def test_list_cli_output_format(mock_tty_stdout): + out = list("mpileaks") + assert out == dedent( + """\ + mpileaks + ==> 1 packages + """ + ) + + def test_list_filter(mock_packages): output = list("py-*") assert "py-extension1" in output diff --git a/lib/spack/spack/test/conftest.py b/lib/spack/spack/test/conftest.py index 80a5ee49de..3ec5b4ad48 100644 --- a/lib/spack/spack/test/conftest.py +++ b/lib/spack/spack/test/conftest.py @@ -1764,3 +1764,8 @@ def mock_spider_configs(mock_config_data, monkeypatch): monkeypatch.setattr(spack.util.web, "spider", _spider) yield + + +@pytest.fixture(scope="function") +def mock_tty_stdout(monkeypatch): + monkeypatch.setattr(sys.stdout, "isatty", lambda: True) -- cgit v1.2.3-70-g09d2