ProgressBar::ask: Accept EOF as a no

This may occur when stderr is a tty but stdin is empty.
E.g.

    $ nix build </dev/null
    error: unexpected EOF reading a line

These stdio handles are how some non-interactive sandboxes behave,
including the Nix build sandbox and Hercules CI Effects.
This commit is contained in:
Robert Hensing 2024-11-06 15:05:32 +01:00
parent f7b1e535a3
commit 3112e59734
3 changed files with 12 additions and 1 deletions

View file

@ -543,7 +543,7 @@ public:
auto state(state_.lock());
if (!state->active) return {};
std::cerr << fmt("\r\e[K%s ", msg);
auto s = trim(readLine(STDIN_FILENO));
auto s = trim(readLine(STDIN_FILENO, true));
if (s.size() != 1) return {};
draw(*state);
return s[0];

View file

@ -27,7 +27,17 @@ cat <<EOF > flake.nix
EOF
# Without --accept-flake-config, the post hook should not run.
# To test variations in stderr tty-ness, we run the command in different ways,
# none of which should block on stdin or accept the `nixConfig`s.
nix build < /dev/null
nix build < /dev/null 2>&1 | cat
# EOF counts as no, even when interactive (throw EOF error before)
if type -p script >/dev/null && script -q -c true /dev/null; then
echo "script is available and GNU-like, so we can ensure a tty"
script -q -c 'nix build < /dev/null' /dev/null
else
echo "script is not available or not GNU-like, so we skip testing with an added tty"
fi
(! [[ -f post-hook-ran ]])
TODO_NixOS
clearStore

View file

@ -60,6 +60,7 @@ mkMesonDerivation (finalAttrs: {
# etc.
busybox-sandbox-shell
# For Overlay FS tests need `mount`, `umount`, and `unshare`.
# For `script` command (ensuring a TTY)
# TODO use `unixtools` to be precise over which executables instead?
util-linux
];