Skip to content

Commit eee41fb

Browse files
committed
[hermes] Hermes is responsible for all terminal UI
gherrit-pr-id: Gc48bae5a713c0931a406c162369f4a30ddc1f2b3
1 parent 0062c3c commit eee41fb

File tree

89 files changed

+19506
-17
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+19506
-17
lines changed

tools/Cargo.lock

Lines changed: 29 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tools/hermes/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ syn = { version = "2.0.114", features = ["full", "visit", "extra-traits", "parsi
2323
quote = "1.0"
2424
thiserror = "2.0.18"
2525
walkdir = "2.5.0"
26+
indicatif = { version = "0.18.3", features = ["improved_unicode"] }
27+
console = "0.16.2"
2628

2729
[dev-dependencies]
2830
syn = { version = "2.0.114", features = ["printing", "full", "visit", "extra-traits", "parsing"] }
@@ -35,6 +37,8 @@ datatest-stable = "0.3.3"
3537
serde = { version = "1.0", features = ["derive"] }
3638
toml = "0.8"
3739
which = "6.0"
40+
regex.workspace = true
41+
strip-ansi-escapes = "0.2.1"
3842

3943
[[test]]
4044
name = "integration"

tools/hermes/src/charon.rs

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,34 @@ pub fn run_charon(args: &Args, roots: &Roots, packages: &[HermesArtifact]) -> Re
8282
log::debug!("Command: {:?}", cmd);
8383

8484
cmd.stdout(std::process::Stdio::piped());
85+
cmd.stderr(std::process::Stdio::piped());
8586
let mut child = cmd.spawn().context("Failed to spawn charon")?;
8687

8788
let mut output_error = false;
89+
90+
let safety_buffer = std::sync::Arc::new(std::sync::Mutex::new(Vec::new()));
91+
let safety_buffer_clone = std::sync::Arc::clone(&safety_buffer);
92+
if let Some(stderr) = child.stderr.take() {
93+
std::thread::spawn(move || {
94+
use std::io::{BufRead, BufReader};
95+
let reader = BufReader::new(stderr);
96+
for line in reader.lines() {
97+
if let Ok(line) = line {
98+
if let Ok(mut buf) = safety_buffer_clone.lock() {
99+
buf.push(line);
100+
}
101+
}
102+
}
103+
});
104+
}
105+
106+
let pb = indicatif::ProgressBar::new_spinner();
107+
pb.set_style(
108+
indicatif::ProgressStyle::default_spinner().template("{spinner:.green} {msg}").unwrap(),
109+
);
110+
pb.enable_steady_tick(std::time::Duration::from_millis(100));
111+
pb.set_message("Compiling...");
112+
88113
if let Some(stdout) = child.stdout.take() {
89114
use std::io::{BufRead, BufReader};
90115
let reader = BufReader::new(stdout);
@@ -105,8 +130,13 @@ pub fn run_charon(args: &Args, roots: &Roots, packages: &[HermesArtifact]) -> Re
105130
if let Ok(msg) = serde_json::from_str::<cargo_metadata::Message>(&line) {
106131
use cargo_metadata::Message;
107132
match msg {
133+
Message::CompilerArtifact(a) => {
134+
pb.set_message(format!("Compiling {}", a.target.name));
135+
}
108136
Message::CompilerMessage(msg) => {
109-
mapper.render_miette(&msg.message);
137+
pb.suspend(|| {
138+
mapper.render_miette(&msg.message, |s| eprintln!("{}", s));
139+
});
110140
if matches!(
111141
msg.message.level,
112142
DiagnosticLevel::Error | DiagnosticLevel::Ice
@@ -115,23 +145,34 @@ pub fn run_charon(args: &Args, roots: &Roots, packages: &[HermesArtifact]) -> Re
115145
}
116146
}
117147
Message::TextLine(t) => {
118-
eprintln!("{}", t);
148+
if let Ok(mut buf) = safety_buffer.lock() {
149+
buf.push(t);
150+
}
119151
}
120152
_ => {}
121153
}
122154
} else {
123-
// Print non-JSON lines to stderr
124-
eprintln!("{}", line);
155+
if let Ok(mut buf) = safety_buffer.lock() {
156+
buf.push(line);
157+
}
125158
}
126159
}
127160
}
128161
}
129162

163+
pb.finish_and_clear();
164+
130165
let status = child.wait().context("Failed to wait for charon")?;
131166

132167
if output_error {
133168
bail!("Diagnostic error in charon");
134169
} else if !status.success() {
170+
// "Silent Death" dump
171+
if let Ok(buf) = safety_buffer.lock() {
172+
for line in buf.iter() {
173+
eprintln!("{}", line);
174+
}
175+
}
135176
bail!("Charon failed with status: {}", status);
136177
}
137178
}

tools/hermes/src/diagnostics.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,10 @@ impl DiagnosticMapper {
9090
}
9191
}
9292

93-
pub fn render_miette(&mut self, diag: &Diagnostic) {
93+
pub fn render_miette<F>(&mut self, diag: &Diagnostic, mut printer: F)
94+
where
95+
F: FnMut(String),
96+
{
9497
let mut mapped_paths_and_spans: HashMap<PathBuf, Vec<&DiagnosticSpan>> = HashMap::new();
9598

9699
// 1) Group spans by mapped path
@@ -160,7 +163,7 @@ impl DiagnosticMapper {
160163
if !all_errors.is_empty() {
161164
let mut main_err = all_errors.remove(0);
162165
main_err.related = all_errors;
163-
eprintln!("{:?}", Report::new(main_err));
166+
printer(format!("{:?}", Report::new(main_err)));
164167
return;
165168
}
166169
}
@@ -172,6 +175,6 @@ impl DiagnosticMapper {
172175
DiagnosticLevel::Warning => "[External Warning]",
173176
_ => "[External Info]",
174177
};
175-
eprintln!("{} {}", prefix, diag.message);
178+
printer(format!("{} {}", prefix, diag.message));
176179
}
177180
}
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
Line 1 from charon
21
× interleaved error
32
╭─[[PROJECT_ROOT]/src/lib.rs:1:1]
43
1 │ pub fn foo() {}
@@ -7,5 +6,4 @@ Line 1 from charon
76
2 │
87
╰────
98

10-
Line 2 from charon
119
Error: Diagnostic error in charon
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
failure
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.*
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[dependencies]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Invalid JSON Data
2+
{"reason": "compiler-artifact", "target": {"name": "test_pkg", "kind": ["lib"]}}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[package]
2+
name = "test_pkg"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]

0 commit comments

Comments
 (0)