Skip to content

Commit fe1ca71

Browse files
committed
unstable-api: Wait for rustfmt/bat to exit.
If we exit before our children, they might write to the terminal after the shell has already written a prompt there, which confused me a lot.
1 parent 57e7cff commit fe1ca71

File tree

1 file changed

+47
-8
lines changed

1 file changed

+47
-8
lines changed

tools/unstable-api/src/main.rs

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{env, path::PathBuf};
22

3-
use anyhow::{Context, Error};
3+
use anyhow::{bail, Context, Error};
44
use structopt::StructOpt;
55

66
mod util;
@@ -27,20 +27,21 @@ fn main() -> Result<(), Error> {
2727
None => find_repo_root()?,
2828
};
2929

30-
#[cfg(unix)]
31-
setup_output_formatting();
30+
let feature = opt.feature;
3231

3332
let libs = vec![
3433
repo_root.clone().join("library/core"),
3534
repo_root.clone().join("library/alloc"),
3635
repo_root.clone().join("library/std"),
3736
];
3837

39-
for crate_root in libs {
40-
visit::pub_unstable(crate_root, &opt.feature)?;
41-
}
38+
with_output_formatting_maybe(move || {
39+
for crate_root in libs {
40+
visit::pub_unstable(crate_root, &feature)?;
41+
}
4242

43-
Ok(())
43+
Ok(())
44+
})
4445
}
4546

4647
fn find_repo_root() -> Result<PathBuf, Error> {
@@ -56,12 +57,46 @@ fn find_repo_root() -> Result<PathBuf, Error> {
5657
Ok(path)
5758
}
5859

60+
#[cfg(not(unix))]
61+
fn with_output_formatting_maybe<F>(f: F) -> Result<(), Error>
62+
where
63+
F: FnOnce() -> Result<(), Error>,
64+
{
65+
f()
66+
}
67+
5968
#[cfg(unix)]
60-
fn setup_output_formatting() {
69+
fn with_output_formatting_maybe<F>(f: F) -> Result<(), Error>
70+
where
71+
F: FnOnce() -> Result<(), Error>,
72+
{
73+
use nix::unistd::close;
74+
use std::io::{stdout, Write};
75+
use std::os::unix::io::AsRawFd;
76+
let child = spawn_output_formatter();
77+
78+
let result = f();
79+
let mut stdout = stdout();
80+
stdout.flush().context("couldn't flush stdout")?;
81+
close(stdout.as_raw_fd()).context("couldn't close stdout")?;
82+
83+
if let Some(mut child) = child {
84+
if !child.wait()?.success() {
85+
bail!("output formatting failed");
86+
}
87+
}
88+
89+
result
90+
}
91+
92+
#[cfg(unix)]
93+
fn spawn_output_formatter() -> Option<std::process::Child> {
6194
use nix::unistd::{isatty, dup2};
6295
use std::os::unix::io::AsRawFd;
6396
use std::process::{Command, Stdio};
6497

98+
let mut final_child = None;
99+
65100
if isatty(1) == Ok(true) {
66101
// Pipe the output through `bat` for nice formatting and paging, if available.
67102
if let Ok(mut bat) = Command::new("bat")
@@ -73,6 +108,7 @@ fn setup_output_formatting() {
73108
{
74109
// Replace our stdout by the pipe into `bat`.
75110
dup2(bat.stdin.take().unwrap().as_raw_fd(), 1).unwrap();
111+
final_child = Some(bat);
76112
}
77113
}
78114

@@ -84,5 +120,8 @@ fn setup_output_formatting() {
84120
{
85121
// Replace our stdout by the pipe into `rustfmt`.
86122
dup2(rustfmt.stdin.take().unwrap().as_raw_fd(), 1).unwrap();
123+
final_child.get_or_insert(rustfmt);
87124
}
125+
126+
final_child
88127
}

0 commit comments

Comments
 (0)