Skip to content

Commit 7f1ecb2

Browse files
authored
Merge pull request #38 from ben0x539/main
unstable-api: Wait for rustfmt/bat to exit.
2 parents 96018ed + 6766d87 commit 7f1ecb2

File tree

1 file changed

+56
-9
lines changed

1 file changed

+56
-9
lines changed

tools/unstable-api/src/main.rs

Lines changed: 56 additions & 9 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,11 +57,28 @@ 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() {
61-
use nix::unistd::{isatty, dup2};
69+
fn with_output_formatting_maybe<F>(f: F) -> Result<(), Error>
70+
where
71+
F: FnOnce() -> Result<(), Error>,
72+
{
73+
use nix::unistd::{isatty, close, dup, dup2};
6274
use std::os::unix::io::AsRawFd;
6375
use std::process::{Command, Stdio};
76+
use std::io::{stdout, Write};
77+
78+
let mut original_stdout = None;
79+
let mut inner_child = None;
80+
81+
stdout().flush().unwrap(); // just in case
6482

6583
if isatty(1) == Ok(true) {
6684
// Pipe the output through `bat` for nice formatting and paging, if available.
@@ -71,8 +89,12 @@ fn setup_output_formatting() {
7189
.stdout(Stdio::inherit())
7290
.spawn()
7391
{
92+
// Hold on to our stdout for later.
93+
original_stdout = Some(dup(1).unwrap());
7494
// Replace our stdout by the pipe into `bat`.
7595
dup2(bat.stdin.take().unwrap().as_raw_fd(), 1).unwrap();
96+
97+
inner_child = Some(bat);
7698
}
7799
}
78100

@@ -82,7 +104,32 @@ fn setup_output_formatting() {
82104
.stdout(Stdio::inherit()) // This pipes into `bat` if it was executed above.
83105
.spawn()
84106
{
107+
// Hold on to our stdout for later, if we didn't already.
108+
original_stdout.get_or_insert_with(|| dup(1).unwrap());
85109
// Replace our stdout by the pipe into `rustfmt`.
86110
dup2(rustfmt.stdin.take().unwrap().as_raw_fd(), 1).unwrap();
111+
112+
inner_child.get_or_insert(rustfmt);
87113
}
114+
115+
let result = f();
116+
117+
if let Some(fd) = original_stdout {
118+
// Overwriting the current stdout with the original stdout
119+
// closes the pipe to the child's stdin, allowing the child to
120+
// exit.
121+
stdout().flush().unwrap(); // just in case
122+
dup2(fd, 1).unwrap();
123+
close(fd).unwrap();
124+
}
125+
126+
if let Some(mut child) = inner_child {
127+
// Wait for inner child to exit to ensure it won't write to
128+
// original stdout after we return.
129+
if !child.wait()?.success() {
130+
bail!("output formatting failed");
131+
}
132+
}
133+
134+
result
88135
}

0 commit comments

Comments
 (0)