Skip to content

patching.py: hardcoded Console width truncates right columns on narrow terminals #9734

@iav

Description

@iav

Background

lib/tools/patching.py:447–453 renders the patching summary table with
a hardcoded rich.Console(width=COLUMNS-12, ...) and only sets
overflow="fold" on the first column. On narrow terminals (≤120 cols —
laptops, serial consoles, tmux panes) two visible problems compound:

  1. The table fits the requested width, but the right columns
    (Diffstat / files, Author / Subject) lose content to truncation
    because they get the default ellipsis/crop overflow.
  2. Console(width=…) is a startup snapshot of COLUMNS-12. It does
    not adapt to the actual TTY size, nor to non-TTY contexts (piped /
    teed output, daemons, cron, ssh without -t) where COLUMNS is
    not meaningful or absent.

Reproducer:

ARTIFACT_IGNORE_CACHE=yes ./compile.sh build BOARD=odroidm1 BRANCH=current \
  BUILD_MINIMAL=yes BUILD_DESKTOP=no RELEASE=noble | tee build.log

In a 90-col terminal the table renders ~78 chars wide and author/subject
is cut off mid-word.

Behaviour matrix

The script runs in several distinct environments. Current logic doesn't
distinguish TTY vs non-TTY, nor docker vs host, nor "no terminal at all":

GitHub Actions Docker stdout TTY COLUMNS meaningful Desired width Overflow
yes yes no (from --env) 160 (CI logs) fold all
no yes no yes COLUMNS from --env fold all
no yes no no 160 (sane default) fold all
no yes yes actual TTY size fold all
no no yes actual TTY size fold all
no no no yes COLUMNS env fold all
no no no no (cron/daemon/nohup) 160 (sane default) fold all

Common rule across every row: never truncate, always wrap.

shutil.get_terminal_size() is not a sufficient default for non-TTY
rows: it silently returns (80, 24), which is too narrow for log-file
consumption.

Proposed fix

Two independent, orthogonal changes:

  1. Add overflow="fold" to every add_column(...) call. Single-line
    change per column; zero behavioural change for users with a wide
    enough terminal — they just get correct wrapping when they don't.

  2. Make width context-aware. Replace the current line with:

    if os.environ.get("GITHUB_ACTIONS"):
        console_width = 160                                          # CI logs
    elif sys.stdout.isatty():
        console_width = shutil.get_terminal_size().columns - 12      # interactive
    else:
        try:
            env_cols = int(os.environ.get("COLUMNS") or 0)
        except ValueError:
            env_cols = 0
        console_width = (env_cols - 12) if env_cols >= 40 else 160   # piped / cron / daemon

(1) alone removes the user-visible truncation; (2) makes width correct
for the rest of the matrix. They can ship in either order or together.

Question

Before writing the PR — is the explicit fixed width kept on purpose
(some CI log reader depends on it)? If the context-aware logic above
(or just shutil.get_terminal_size() for the TTY case) is acceptable,
the change is small and self-contained.

Happy to take it on if direction is welcomed.

Relation to PR #9631

PR #9631 addresses a
narrower symptom of the same root cause — a
ValueError: invalid literal for int() crash when COLUMNS="" is
forwarded into the Python script. The PR's discussion identifies the
underlying issue as missing ${COLUMNS:-160} defaults at the bash
forwarding points (uboot-patching.sh:29, kernel-patching.sh:34).

The proposal in this issue addresses the same root cause and its
sibling problems in one place. The try/except plus fallback in the
proposed Python block subsumes the COLUMNS="" crash, while the
matrix above also covers the previously-unhandled cases (truncation,
no-TTY environments). #9631 can be closed in favour of this fix, or
its bash-side ${COLUMNS:-160} patch can land first as a minimal
intermediate step — both converge on the same behaviour.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugfixPull request is fixing a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions