Skip to content

Fall back to simple text output when stdout is not a TTY#1392

Open
knQzx wants to merge 2 commits intoapple:mainfrom
knQzx:fix-pipe-output
Open

Fall back to simple text output when stdout is not a TTY#1392
knQzx wants to merge 2 commits intoapple:mainfrom
knQzx:fix-pipe-output

Conversation

@knQzx
Copy link
Copy Markdown

@knQzx knQzx commented Apr 5, 2026

summary

  • detect when stdout is not a tty and fall back to simple line-by-line status output
  • fixes silent commands when piping to a file

fixes #113

test plan

before (main):

$ container image pull ghcr.io/linuxcontainers/alpine:3.20 2>stderr.txt
$ cat stderr.txt
(empty - progress lost when stderr is not a tty)

after:

$ container image pull ghcr.io/linuxcontainers/alpine:3.20 2>stderr.txt
$ cat stderr.txt
[1/2] Fetching image [0s]
[1/2] Fetching image (7 of 15 blobs) [2s]
[1/2] Fetching image 42% (23 of 50 blobs, 10.0/23.7 MB, 6.9 MB/s) [5s]
[2/2] Unpacking image for platform linux/arm64 [11s]
...

also added TestCLIProgressAuto integration test covering auto/plain/none modes

@jglogan
Copy link
Copy Markdown
Contributor

jglogan commented Apr 5, 2026

@knQzx Thank you for the PR! Could you please add the commands you tested with, and before/after output, to the PR description?

Would it be possible to add an integration test for this?

@knQzx
Copy link
Copy Markdown
Author

knQzx commented Apr 5, 2026

added before/after output to the description and an integration test for this

@knQzx knQzx force-pushed the fix-pipe-output branch from 06daaac to 1f83bf4 Compare April 5, 2026 18:49
@jglogan
Copy link
Copy Markdown
Contributor

jglogan commented Apr 9, 2026

@knQzx It was a long time ago, but I think we made an implementation decision during initial progress bar development that if stderr wasn't a tty, we would suppress progress output, so that you'd only see warnings and errors.

I can think of an idea or two, but why is this change to include progress with the warnings and errors useful for you?

@knQzx
Copy link
Copy Markdown
Author

knQzx commented Apr 9, 2026

@jglogan mainly for ci logs - when a pull runs in a pipeline and stderr goes to a file, it's hard to tell if things are progressing or stuck. what were the ideas you had in mind?

@jglogan
Copy link
Copy Markdown
Contributor

jglogan commented Apr 9, 2026

@knQzx I think it's similar.

The use case I was thinking about originally was, if run container something ... 2> errors.txt I really want to study the errors/warnings, so progress just gets in the way for me.

OTOH, if that command is long running and I want to do tail -f errors.txt, being able to see that a command is making progress / doesn't appear to be stuck is probably exactly why I'm running that tail.

@dkovba Do you remember anything else from when you were developing the progress bar and we were talking about it? Looking at where we are with container now, do you have a preference?

@jglogan
Copy link
Copy Markdown
Contributor

jglogan commented Apr 9, 2026

@knQzx Could you review https://github.com/apple/containerization/blob/main/CONTRIBUTING.md#submitting-issues-and-pull-requests and set up signing for your commits? They need to show up in the PR as Verified, like:

image

Then the CI build can make progress.

@dkovba dkovba changed the title fall back to simple text output when stdout is not a tty Fall back to simple text output when stdout is not a TTY Apr 9, 2026

class TestCLIProgressAuto: CLITest {
@Test func testAutoProgressFallsBackToPlainWhenPiped() throws {
do {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do-catch blocks in tests seem redundant.

/// with `isatty`. If the output is a TTY, `.ansi` is used; otherwise
/// `.plain` is selected so that piped or redirected output still shows
/// simple line-by-line status text.
private func resolvedProgress(terminal: FileHandle = .standardError) -> ProgressType {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The terminal parameter is currently unused. Do we need it? Also, the default value .standardError contradicts the PR title mentioning stdout.

do {
let (_, _, error, status) = try run(arguments: [
"image", "pull",
"--progress", "none",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding the same test for --progress ansi.

@dkovba
Copy link
Copy Markdown
Contributor

dkovba commented Apr 9, 2026

Thank you for the contribution! 👍

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.

Commands like image pull don't output any status if stdout (or stderr) is being piped to a file

3 participants