Skip to content

Commit ffb6043

Browse files
committed
Merge remote-tracking branch 'origin/main' into main
2 parents d1ea3eb + 4af6e4c commit ffb6043

File tree

7 files changed

+69
-20
lines changed

7 files changed

+69
-20
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
### next
2+
- propose to toggle backtraces when suggestion is found in cargo's output
3+
14
<a name="v1.1.8"></a>
25
### v1.1.8 - 2021/07/31
36
- move to more recent versions of some crates - Fix #51

src/app.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub fn run(w: &mut W, mission: Mission) -> Result<()> {
2424
mission.add_watchs(&mut watcher)?;
2525

2626
let executor = Executor::new(&mission)?;
27-
executor.start()?; // first computation
27+
executor.start(state.new_task())?; // first computation
2828

2929
let event_source = EventSource::new()?;
3030
let user_events = event_source.receiver();
@@ -59,6 +59,16 @@ pub fn run(w: &mut W, mission: Mission) -> Result<()> {
5959
state.toggle_wrap_mode();
6060
state.draw(w)?;
6161
}
62+
(Char('t'), KeyModifiers::NONE) => {
63+
debug!("user toggles backtraces");
64+
state.toggle_backtrace();
65+
if let Err(e) = executor.start(state.new_task()) {
66+
debug!("error sending task: {}", e);
67+
} else {
68+
state.computation_starts();
69+
}
70+
state.draw(w)?;
71+
}
6272
(Home, _) => { state.scroll(w, ScrollCommand::Top)?; }
6373
(End, _) => { state.scroll(w, ScrollCommand::Bottom)?; }
6474
(Up, _) => { state.scroll(w, ScrollCommand::Lines(-1))?; }
@@ -88,7 +98,7 @@ pub fn run(w: &mut W, mission: Mission) -> Result<()> {
8898
}
8999
recv(watch_receiver) -> _ => {
90100
debug!("got a watcher event");
91-
if let Err(e) = executor.start() {
101+
if let Err(e) = executor.start(state.new_task()) {
92102
debug!("error sending task: {}", e);
93103
} else {
94104
state.computation_starts();

src/executor.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,39 @@ use {
1515
/// Channel sizes are designed to avoid useless computations.
1616
pub struct Executor {
1717
pub line_receiver: Receiver<CommandExecInfo>,
18-
task_sender: Sender<()>,
18+
task_sender: Sender<Task>,
1919
stop_sender: Sender<()>, // signal for stopping the thread
2020
thread: thread::JoinHandle<()>,
2121
}
2222

23+
#[derive(Debug, Clone, Copy, PartialEq, Default)]
24+
pub struct Task {
25+
pub backtrace: bool,
26+
}
27+
2328
impl Executor {
2429
/// launch the commands, sends the lines of its stderr on the
2530
/// line channel.
2631
/// If `with_stdout` captures and send also its stdout.
2732
pub fn new(mission: &Mission) -> Result<Self> {
2833
let mut command = mission.get_command();
2934
let with_stdout = mission.need_stdout();
30-
let (task_sender, task_receiver) = bounded(1);
35+
let (task_sender, task_receiver) = bounded::<Task>(1);
3136
let (stop_sender, stop_receiver) = bounded(0);
3237
let (line_sender, line_receiver) = unbounded();
38+
command
39+
.stderr(Stdio::piped())
40+
.stdout(if with_stdout { Stdio::piped() } else { Stdio::null() });
3341
let thread = thread::spawn(move || {
3442
loop {
3543
select! {
36-
recv(task_receiver) -> _ => {
37-
debug!("starting task");
38-
command
39-
.stderr(Stdio::piped())
40-
.stdout(if with_stdout { Stdio::piped() } else { Stdio::null() });
44+
recv(task_receiver) -> task => {
45+
let task = task.unwrap();
46+
debug!("starting task {:?}", task);
47+
command.env(
48+
"RUST_BACKTRACE",
49+
if task.backtrace { "1" } else { "0" },
50+
);
4151
let child = command.spawn();
4252
let mut child = match child {
4353
Ok(child) => child,
@@ -163,8 +173,8 @@ impl Executor {
163173
})
164174
}
165175
/// notify the executor a computation is necessary
166-
pub fn start(&self) -> Result<()> {
167-
self.task_sender.try_send(())?;
176+
pub fn start(&self, task: Task) -> Result<()> {
177+
self.task_sender.try_send(task)?;
168178
Ok(())
169179
}
170180
pub fn die(self) -> Result<()> {

src/line_analysis.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ impl From<&CommandOutputLine> for LineAnalysis {
3030
} else if regex_is_match!("^failures:$", content) {
3131
// this isn't very discriminant...
3232
LineType::Title(Kind::Sum)
33+
} else if regex_is_match!("^note: run with `RUST_BACKTRACE=", content) {
34+
LineType::BacktraceSuggestion
3335
} else {
3436
LineType::Normal
3537
}

src/line_type.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ pub enum LineType {
3030
/// the line saying if a test was passed
3131
TestResult(bool),
3232

33+
/// a suggestion to try with backtrace
34+
BacktraceSuggestion,
35+
3336
/// any other line
3437
Normal,
3538
}

src/report.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use {
1010
pub struct Report {
1111
pub lines: Vec<Line>,
1212
pub stats: Stats,
13+
pub suggest_backtrace: bool,
1314
}
1415

1516
impl Report {
@@ -33,6 +34,7 @@ impl Report {
3334
let mut passed_tests = 0;
3435
let mut cur_err_kind = None; // the current kind among stderr lines
3536
let mut is_in_out_fail = false;
37+
let mut suggest_backtrace = false;
3638
for cmd_line in cmd_lines {
3739
debug!("cmd_line={:?}", &cmd_line);
3840
let line_analysis = LineAnalysis::from(cmd_line);
@@ -95,6 +97,9 @@ impl Report {
9597
cur_err_kind = None;
9698
is_in_out_fail = false;
9799
}
100+
(LineType::BacktraceSuggestion, _) => {
101+
suggest_backtrace = true;
102+
}
98103
_ => {
99104
// TODO add normal if not broken with blank line
100105
warn!("unexpected line: {:#?}", &line);
@@ -133,6 +138,6 @@ impl Report {
133138
// have been read but not added (at start or end)
134139
let mut stats = Stats::from(&lines);
135140
stats.passed_tests = passed_tests;
136-
Ok(Report { lines, stats })
141+
Ok(Report { lines, stats, suggest_backtrace })
137142
}
138143
}

src/state.rs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ pub struct AppState {
3232
computing: bool,
3333
/// whether the user wants wrapped lines
3434
pub wrap: bool,
35+
/// whether the user wants backtraces
36+
pub backtrace: bool,
3537
/// whether we should display only titles and locations
3638
summary: bool,
3739
reverse: bool,
@@ -62,6 +64,7 @@ impl AppState {
6264
computing: true,
6365
summary: mission.settings.summary,
6466
wrap: mission.settings.wrap,
67+
backtrace: false,
6568
reverse: mission.settings.reverse,
6669
status_skin,
6770
scroll: 0,
@@ -79,6 +82,11 @@ impl AppState {
7982
self.scroll_to_bottom();
8083
}
8184
}
85+
pub fn new_task(&self) -> Task {
86+
Task {
87+
backtrace: self.backtrace,
88+
}
89+
}
8290
pub fn take_lines(&mut self) -> Option<Vec<CommandOutputLine>> {
8391
self.lines.take()
8492
}
@@ -188,6 +196,9 @@ impl AppState {
188196
self.summary ^= true;
189197
self.try_scroll_to_last_top_item();
190198
}
199+
pub fn toggle_backtrace(&mut self) {
200+
self.backtrace ^= true;
201+
}
191202
pub fn toggle_wrap_mode(&mut self) {
192203
self.wrap ^= true;
193204
if self.wrapped_report.is_some() {
@@ -222,20 +233,25 @@ impl AppState {
222233
self.draw(w)
223234
}
224235
fn draw_status(&self, w: &mut W, y: u16) -> Result<()> {
225-
let status = if matches!(self.cmd_result, CommandResult::Report(_)) {
226-
if self.wrap {
227-
"hit *q* to quit, *s* to toggle summary mode, *w* to not wrap lines"
236+
let mut parts = vec!["hit *q* to quit"];
237+
if let CommandResult::Report(report) = &self.cmd_result {
238+
if report.suggest_backtrace {
239+
parts.push("*t* to toggle backtraces");
228240
} else {
229-
"hit *q* to quit, *s* to toggle summary mode, *w* to wrap lines"
241+
parts.push("*s* to toggle summary mode");
242+
if self.wrap {
243+
parts.push("*w* to not wrap lines");
244+
} else {
245+
parts.push("*w* to wrap lines");
246+
}
230247
}
231-
} else {
232-
"hit *q* to quit"
233-
};
248+
}
249+
let status = parts.join(", ");
234250
if self.height > 1 {
235251
goto(w, y)?;
236252
self.status_skin.write_composite_fill(
237253
w,
238-
Composite::from_inline(status),
254+
Composite::from_inline(&status),
239255
self.width.into(),
240256
Alignment::Left,
241257
)?;

0 commit comments

Comments
 (0)