Decide: should `mado check` read standard input when it is not a terminal?
- 主要语言
- Rust
- 星标
- 407
- 派生
- 12
- 平均合并
- 5 小时 45 分钟
- 30 天内合并 PR
- 30
描述
## Context
`Checker::new` asks for standard input before it looks at anything else
(`src/command/check.rs`):
```rust
let runner = match stdin_input() {
Some(input) => LintRunner::String(...),
None => LintRunner::Parallel(...),
};
```
and `stdin_input` reads to EOF whenever standard input is not a terminal:
```rust
fn stdin_input() -> Option {
let stdin = io::stdin();
if stdin.is_terminal() {
return None;
}
let mut buffer = String::new();
io::stdin().lock().read_to_string(&mut buffer).ok()?;
...
}
```
`is_terminal()` is the only thing asked. Whether the command was given files to
check is not, and a pipe that nobody writes to and nobody closes is not a
terminal.
This is not new in #436 — `main` and 0.3.2 behave the same. It was found while
running `cargo test` from a shell whose standard input was an open pipe: every
`mado check` the tests spawned inherited it and stopped there, and the run had
to be killed.
## Observed behaviour
```console
$ mado check docs < /dev/null # stdin at EOF
Found 6 errors. # docs is linted
$ printf '' | mado check docs # empty pipe
Found 6 errors. # docs is linted
$ printf '#Hello.\n' | mado check docs # pipe with content
(stdin):1:1: MD041 First line in file should be a top level header
Found 2 errors. # docs is NOT linted, and nothing says so
$ mado check docs < <(sleep 30) # pipe held open
# nothing, until the pipe closes
```
So two things sit here:
- **a run that never starts.** `mado check .` with standard input open and
silent waits for EOF that may never come. A CI step, a test harness, an
editor integration or a task runner that leaves a pipe open is enough, and
mado says nothing while it waits.
- **files given and not looked at.** Where standard input carries something,
the paths on the command line are dropped without a word.
## What would have to be decided
- Should standard input be read only where no files were named? `files` carries
`#[arg(default_value = ".")]`, so "nothing given" and "`.` given" arrive the
same; telling them apart means `ArgMatches::value_source` or dropping the
default and answering for it elsewhere.
- Should it be asked for rather than guessed at — `mado check -`, the way many
tools spell it, or a flag?
- Should anything be said where both are given, rather than one of them being
dropped quietly?
- Whatever is decided, standard input is undocumented: neither `mado check
--help` nor the README mentions that it is read at all.
## Related
- #436
贡献指南
评估
这个 Issue 还没有评估数据。