From 93c11ccbb413d9234175534eba9c259c9ec400ef Mon Sep 17 00:00:00 2001 From: cyphercodes Date: Mon, 1 Jun 2026 19:02:54 +0300 Subject: [PATCH 1/2] Handle long task names in list output --- invoke/program.py | 5 +++-- tests/program.py | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/invoke/program.py b/invoke/program.py index 67b879b6..d49e9411 100644 --- a/invoke/program.py +++ b/invoke/program.py @@ -954,12 +954,13 @@ def print_columns( # Calculate column sizes: don't wrap flag specs, give what's left over # to the descriptions. name_width = max(len(x[0]) for x in tuples) - desc_width = ( + desc_width = max( + 1, pty_size()[0] - name_width - self.leading_indent_width - self.col_padding - - 1 + - 1, ) wrapper = textwrap.TextWrapper(width=desc_width) for name, help_str in tuples: diff --git a/tests/program.py b/tests/program.py index 3b6765cd..03bac3c3 100644 --- a/tests/program.py +++ b/tests/program.py @@ -810,6 +810,21 @@ def docstrings_are_wrapped_to_terminal_width(self): ), ) + def long_task_names_may_exhaust_terminal_width(self): + name = ( + "my-very-long-task-name-that-is-completely-legit-but-make-" + "grep-crash-aaaaaa" + ) + + def body(c): + pass + + program = Program(namespace=Collection(Task(body, name=name))) + with patch("invoke.program.pty_size", return_value=(80, 24)): + stdout, _ = run("--list", program=program) + + assert " {}\n".format(name) in stdout + def empty_collections_say_no_tasks(self): expect( "-c empty -l", err="No tasks found in collection 'empty'!\n" From ae26c336c34dc88b9420eb769550c11d223af04b Mon Sep 17 00:00:00 2001 From: cyphercodes Date: Mon, 1 Jun 2026 20:43:14 +0300 Subject: [PATCH 2/2] test: exclude list helper body from coverage --- tests/program.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/program.py b/tests/program.py index 03bac3c3..a08b2ff0 100644 --- a/tests/program.py +++ b/tests/program.py @@ -817,7 +817,7 @@ def long_task_names_may_exhaust_terminal_width(self): ) def body(c): - pass + pass # pragma: no cover program = Program(namespace=Collection(Task(body, name=name))) with patch("invoke.program.pty_size", return_value=(80, 24)):