Skip to content

fix: Packages without root, Rio under sudo, logo aspect - #189

Merged
l1a merged 1 commit into
mainfrom
fix/nonroot-packages-and-logo-scaling
Aug 12, 2026
Merged

fix: Packages without root, Rio under sudo, logo aspect#189
l1a merged 1 commit into
mainfrom
fix/nonroot-packages-and-logo-scaling

Conversation

@l1a

@l1a l1a commented Aug 12, 2026

Copy link
Copy Markdown
Owner

Three user-reported defects, all surfaced by diffing a sudo retch --full run
against a plain one on corrino (i7-1360P, Fedora 44, Rio), plus the documentation
that makes the remaining differences legible.

1. Packages appeared only under sudo (bugfix)

detect_packages opened /var/lib/rpm/rpmdb.sqlite with rusqlite::Connection::open
— i.e. read-write. The rpmdb is root:root 0644 inside a root-owned directory, so
SQLite cannot create the journal sidecars it wants and every query fails with
attempt to write a readonly database.

Note query, not open(): the existing eprintln! guarded only the open, so the
failure was completely silent and the field just disappeared. Plain mode=ro does not
help for the same reason — it still needs to touch the directory.

Fixed with open_with_flags(rpm_db_uri(path), SQLITE_OPEN_READ_ONLY | SQLITE_OPEN_URI | SQLITE_OPEN_NO_MUTEX) over a file:…?immutable=1 URI, which lets SQLite skip locking
and sidecars entirely. The query error is now surfaced instead of swallowed.

2. Rio lost graphics support under sudo (bugfix)

supports_kitty/supports_iterm2/supports_sixel identified Rio only by
TERM_PROGRAM, which is not in sudo's default env_keep. So sudo retch silently fell
all the way through to Chafa while the same command as the user used the Kitty protocol
— which is exactly why the two pasted runs looked like they had different logos.

New is_rio_terminal() also accepts TERM=rio/xterm-rio, which sudo does preserve.

3. The Kitty logo was stretched ~3× vertically (bugfix)

print_graphical_logo emitted a hardcoded c=26,r=10, and Kitty forces an image
into the c×r rectangle — it does not preserve aspect when both are given. Five assets
are wide horizontal lockups (fedora.png is 384×108, i.e. 3.56:1; also arch/nixos/
ubuntu/tux), so they were squashed into a roughly 1:1 box.

Compounding it, display.rs separately assumed a fixed 40-column width for layout
while graphical_logo_height_lines derived the row count a third way — three
inconsistent answers for one footprint.

Fixed with a single pure fit_logo_cells(...) -> LogoFit (aspect-preserving, in pixels
so non-square cells are handled) now used by all three protocol emitters and by
plan_layout.

Computing c and r correctly is not sufficient. Cells are indivisible, so the
rounded rectangle is never exactly the image's aspect. Measured in a PTY at real
geometry (169×47 cells, 22×51 px):

placement aspect error
old c=26,r=10 ~220% (3× vertical stretch)
computed c and r 9%
c=45 only, Kitty derives the rest 0.0%

LogoFit::width_limited records which dimension the image touches first and
kitty_placement_spec emits just that one. The layout's div_ceil reservation (6 rows
for a 5.46-row draw) still covers it — the safe direction.

4. Chafa logo box widened 28 → 45 columns

Row cap unchanged at 10. Chafa fits within the box preserving aspect, so a narrow box
caps a wide image's height long before the row cap does: at 28 columns the Fedora logo
collapsed to 4 rows of symbols and was unreadable; at 45 it renders 7.

The side-by-side threshold is unaffected — the text column floors at 45 and
45 + 45 = 90 ≤ 95, so a full-width logo still sits beside the text at the 95-column
cutoff. Pinned by a new plan_layout test at both 95 and 169 columns.

Assets deliberately not changed: cropping the wide lockups to their square icon
halves would render larger still, but that is a content decision and was declined in
favour of the layout-only fix.

5. Documentation

New NOTES §6b documents the privilege-dependent fields in both directions — root-only
phys-mem and btrfs snapshot counts, user-only editor/desktop/wm — mirrored in
README.md and a new PRIVILEGES section in docs/retch.1.md.

Test-isolation defect fixed in passing

Same class as #155 / v0.6.2: once supports_iterm2 began reading TERM,
test_supports_iterm2_heuristics (which guarded only TERM_PROGRAM) let the host's
TERM leak in, so its negative assertions failed on a Rio box while passing on CI. It
now guards and clears TERM too.

Test plan

  • just check — fmt + clippy --workspace + clippy --features graphics, all clean
  • cargo test --workspace — 69 cli + 117 sysinfo + 15 integration, green with and without --features graphics
  • just man — regenerates idempotently, footer retch 0.6.18, 0 doubled font runs
  • just pr — full gate green (audit shows only the pre-existing allowed paste RUSTSEC-2024-0436)
  • retch --fields packages as an unprivileged user → Packages: 2509, identical to the sudo run
  • retch --fields phys-mem unprivileged → still absent (genuinely root-only, now documented)
  • PTY probe with TERM_PROGRAM unset and TERM=xterm-rio (the sudo case) → Kitty escape emitted, c=45, 0.0% aspect error
  • chafa --size 45x10 on fedora.png → 7 content rows (was 4 at 28x10)

Manual verification for a reviewer: run retch --full in Rio/kitty and confirm the
logo sits beside the text, undistorted. Then run it in a terminal identified only by
TERM_PROGRAM (e.g. WezTerm) to confirm no regression in the non-Rio paths.

Versions

retch-sysinfo0.1.53 (library behaviour change); retch-cli0.6.18. Patch bump.

Wiki updated ahead of this PR (4025d35..7fc584f): Troubleshooting.md gains a
"What sudo retch actually changes" section; Configuration-and-Theming.md notes that
packages no longer needs root.

Three defects found by diffing `sudo retch --full` against a plain run.

Packages appeared only under sudo. The RPM SQLite database was opened
read-write; it is root-owned inside a root-owned directory, so SQLite
could not create its journal sidecars and every *query* failed with
"attempt to write a readonly database" — not the open(), which is why
the existing warning never fired and the field vanished silently. Now
opened read-only over a `file:...?immutable=1` URI, and the query error
is reported instead of swallowed.

Rio lost all graphics support under sudo: it was identified only by
TERM_PROGRAM, which env_reset drops. `is_rio_terminal` now also accepts
TERM=rio/xterm-rio, which sudo preserves.

The Kitty logo was stretched ~3x vertically. `c=26,r=10` was hardcoded
and Kitty forces an image into that rectangle, while display.rs assumed
a fixed 40-column width and derived the row count a third way. A single
pure `fit_logo_cells` now feeds all three protocol emitters and
plan_layout. Passing both correct values still left a 9% stretch from
cell quantisation, so the Kitty spec carries only the limiting dimension
and lets Kitty derive the other — measured 0.0% aspect error in a PTY.

The chafa box widens 28 -> 45 columns (row cap unchanged at 10) so wide
lockup assets stay legible: the Fedora logo goes from 4 rows to 7. The
side-by-side threshold is unaffected (45 + 45 <= 95), pinned by a test.

Also fixes a test-isolation defect the change exposed: once
supports_iterm2 read TERM, the host's TERM leaked into a test that
guarded only TERM_PROGRAM, failing on a Rio box and passing on CI.

Documents the privilege trade-off in both directions (root-only
phys-mem and btrfs snapshot counts; user-only editor/desktop/wm) in a
new NOTES section, README, and a man-page PRIVILEGES section.

Assisted-By: Claude Opus 5
@l1a
l1a merged commit 1d0dc36 into main Aug 12, 2026
18 checks passed
@l1a
l1a deleted the fix/nonroot-packages-and-logo-scaling branch August 12, 2026 00:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant