|
59 | 59 | #![deny(missing_docs)] |
60 | 60 |
|
61 | 61 | use std::fs::{self, File}; |
62 | | -use std::io::{self, BufRead, BufReader, ErrorKind}; |
| 62 | +use std::io::{self, BufRead, BufReader, ErrorKind, IsTerminal, stdin}; |
63 | 63 | use std::path::PathBuf; |
64 | 64 |
|
65 | 65 | use anyhow::{Context, Error, Result}; |
@@ -301,6 +301,22 @@ fn underlying_io_error_kind(error: &Error) -> Option<io::ErrorKind> { |
301 | 301 | async fn run(opts: &LycheeOptions) -> Result<i32> { |
302 | 302 | let inputs = opts.inputs()?; |
303 | 303 |
|
| 304 | + // Hide the progress bar only when stdin is the sole input and it is |
| 305 | + // interactive (TTY). |
| 306 | + // |
| 307 | + // We restrict this to the sole-input case because with mixed inputs like |
| 308 | + // `lychee - README.md` the file is processed concurrently with stdin, so |
| 309 | + // the order of completion is non-deterministic. Hiding the bar there would |
| 310 | + // be confusing rather than helpful. |
| 311 | + // |
| 312 | + // When stdin is piped (`cat links.txt | lychee -`), `is_terminal()` returns |
| 313 | + // false, so the progress bar is shown normally. |
| 314 | + let is_stdin_input = inputs.len() == 1 |
| 315 | + && inputs |
| 316 | + .iter() |
| 317 | + .any(|input| matches!(input.source, lychee_lib::InputSource::Stdin)) |
| 318 | + && stdin().is_terminal(); |
| 319 | + |
304 | 320 | // TODO: Remove this section after `--base` got removed with 1.0 |
305 | 321 | let base = match (opts.config.base.clone(), opts.config.base_url.clone()) { |
306 | 322 | (None, base_url) => base_url, |
@@ -367,6 +383,7 @@ async fn run(opts: &LycheeOptions) -> Result<i32> { |
367 | 383 | cache, |
368 | 384 | requests, |
369 | 385 | cfg: opts.config.clone(), |
| 386 | + is_stdin_input, |
370 | 387 | }; |
371 | 388 |
|
372 | 389 | let exit_code = if opts.config.dump { |
|
0 commit comments