From 22594952ce4d41da4ff79619aa5761ea47f42964 Mon Sep 17 00:00:00 2001 From: Johan Walles Date: Sun, 29 Oct 2023 09:52:17 +0100 Subject: [PATCH] Handle no-search-hits properly Before this change, if there were no search hits, we just listed all running processes. With this change in place, we print an informative message to stderr when this happens. Fixes #117. --- px/px_tree.py | 18 +++++++++++++++--- tests/px_tree_test.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/px/px_tree.py b/px/px_tree.py index 1113c99..21811cd 100644 --- a/px/px_tree.py +++ b/px/px_tree.py @@ -1,16 +1,26 @@ from . import px_process from . import px_terminal +import sys + from typing import Set, List, Optional, Iterable def tree(search: str) -> None: """Print a process tree""" - for line in _generate_tree(px_process.get_all(), search): + print_me = _generate_tree(px_process.get_all(), search) + if not print_me: + print(f"No processes found matching <{search}>", file=sys.stderr) + return + + for line in print_me: print(line) def _generate_tree(processes: List[px_process.PxProcess], search: str) -> List[str]: + if not processes: + return [] + # Only print subtrees needed for showing all search hits and their children. # # We do that by starting at the search hits and walking up the tree from all @@ -24,6 +34,7 @@ def _generate_tree(processes: List[px_process.PxProcess], search: str) -> List[s _mark_children(process, show_pids) + # Walk up the tree from this process, marking each process for display if process and process.parent: process = process.parent while process: @@ -34,8 +45,9 @@ def _generate_tree(processes: List[px_process.PxProcess], search: str) -> List[s break process = process.parent - if not processes: - return [] + # Search found nothing + if not show_pids: + return [] lines = [] coalescer = Coalescer(0) diff --git a/tests/px_tree_test.py b/tests/px_tree_test.py index f25a3bf..8fabe2e 100644 --- a/tests/px_tree_test.py +++ b/tests/px_tree_test.py @@ -47,6 +47,37 @@ def test_search(): ) == ["root(1)", f" {px_terminal.bold('find-me')}(2)"] +def test_no_search(): + assert px_tree._generate_tree( + resolve( + [ + testutils.create_process(pid=1, ppid=0, commandline="root"), + testutils.create_process(pid=2, ppid=1, commandline="find-me"), + testutils.create_process(pid=3, ppid=1, commandline="uninteresting"), + ] + ), + "", + ) == ["root(1)", " find-me(2)", " uninteresting(3)"] + + +def test_search_no_matches(): + assert ( + px_tree._generate_tree( + resolve( + [ + testutils.create_process(pid=1, ppid=0, commandline="root"), + testutils.create_process(pid=2, ppid=1, commandline="find-me"), + testutils.create_process( + pid=3, ppid=1, commandline="uninteresting" + ), + ] + ), + "not-there", + ) + == [] + ) + + def test_coalesce_no_search(): assert px_tree._generate_tree( resolve(