Skip to content

inspect inherits your shell's environment, so it shows a screen your test will never see #263

Description

@vyncint

Todayinspect spawns the program under test with the environment of whoever ran it, while the suite it exists to debug almost always spawns with env_clear(). crates/termlens/examples/inspect.rs:111:

let mut t = match Terminal::builder()
    .size(size.0, size.1)
    .timeout(timeout)
    .args(args)
    .spawn(&program)

No .env_clear(), and no flag for one. The README's example, the crate docs, bin!, and every fixture test in this repository use env_clear(), because a hermetic environment is the whole point of a harness.

So the tool whose job is "show me what my app looks like in the grid" shows a grid built under different conditions from the one the test will see. Anything the application reads from the environment can differ: NO_COLOR, COLORTERM, LANG and LC_ALL (which decide whether it draws UTF-8 box characters or ASCII), TERM if the caller exported one, and every application-specific variable a developer happens to have set in their shell.

Why it is worth fixing — the failure this produces is the worst kind for a debugging tool: it disagrees with the thing being debugged, and it disagrees quietly. A developer whose snapshot test fails runs inspect to see what the application actually drew, gets a different screen from the one in the failure, and now has two mysteries. An application that draws a coloured border under the developer's COLORTERM=truecolor and a plain one under the test's cleared environment is exactly the case someone reaches for inspect to understand.

It is also the cheapest possible fix — one builder call and one flag — for a tool that is the crate's shop window: it is what the README points a new user at, and what docs/HANDOFF.md recommends for seeing "any program through termlens's eyes".

Fix — make the default match what a test does, and keep the escape hatch:

  • inspect calls .env_clear() by default, so its screen is the screen a test gets.
  • --inherit-env restores the current behaviour, for the case where the program genuinely needs something from the caller's environment to run at all.
  • --env KEY=VALUE, repeatable, so a single variable can be set without giving up hermeticity — this is what a developer actually wants when chasing "does it look different with NO_COLOR=1?", which is a good enough reason on its own.

Two things to handle while there. Under env_clear() the crate refuses a bare program name, because clearing the environment removes PATH (#222) — so inspect ls would start failing with the error #222 added. Either pass PATH through by default (a documented exception, the way TERM and SHELL already are) or catch that error and add one line telling the user about --inherit-env; say which was chosen and why. And the usage text and the file's //! header both list the flags, so both need the new ones — they are already the single source --help prints, so this is one edit.

Done wheninspect clears the environment by default and its trailer or usage says so; --inherit-env and a repeatable --env KEY=VALUE exist; a bare program name still works or fails with a message naming the flag that fixes it; the doc comment and usage text list every flag; and crates/termlens/tests/inspect.rs covers the cleared default by inspecting a program that prints its own environment.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions