Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 43 additions & 5 deletions objdiff-cli/src/cmd/diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,12 @@ pub struct Args {
}

pub fn run(args: Args) -> Result<()> {
let (target_path, base_path, project_config, unit_options, symbol_mappings) =
let (project_dir, target_path, base_path, project_config, unit_options, symbol_mappings) =
match (&args.target, &args.base, &args.project, &args.unit) {
(Some(_), Some(_), None, None)
| (Some(_), None, None, None)
| (None, Some(_), None, None) => {
(args.target.clone(), args.base.clone(), None, None, BTreeMap::new())
(None, args.target.clone(), args.base.clone(), None, None, BTreeMap::new())
}
(None, None, p, u) => {
let project = match p {
Expand Down Expand Up @@ -168,7 +168,14 @@ pub fn run(args: Args) -> Result<()> {
let target_path = object.target_path.clone();
let base_path = object.base_path.clone();
let symbol_mappings = object.symbol_mappings.clone();
(target_path, base_path, Some(project_config), unit_options, symbol_mappings)
(
Some(project),
target_path,
base_path,
Some(project_config),
unit_options,
symbol_mappings,
)
}
_ => bail!("Either target and base or project and unit must be specified"),
};
Expand All @@ -184,7 +191,15 @@ pub fn run(args: Args) -> Result<()> {
&symbol_mappings,
)
} else {
run_interactive(args, target_path, base_path, project_config, unit_options, symbol_mappings)
run_interactive(
args,
project_dir,
target_path,
base_path,
project_config,
unit_options,
symbol_mappings,
)
}
}

Expand Down Expand Up @@ -345,6 +360,28 @@ impl AppState {
fn check_jobs(&mut self) -> Result<bool> {
let mut redraw = false;
self.jobs.collect_results();
// Surface job errors (e.g. a failed build) instead of silently showing nothing.
for job in self.jobs.iter_mut() {
let Some((title, error)) = job
.context
.status
.write()
.ok()
.and_then(|mut s| s.error.take().map(|e| (s.title.clone(), e)))
else {
continue;
};
let status = BuildStatus {
success: false,
stdout: format!("Job \"{title}\" failed"),
stderr: format!("{error:#}"),
..Default::default()
};
self.left_status = Some(status.clone());
self.right_status = Some(status);
redraw = true;
}
self.jobs.clear_finished();
for result in mem::take(&mut self.jobs.results) {
match result {
JobResult::None => unreachable!("Unexpected JobResult::None"),
Expand Down Expand Up @@ -378,6 +415,7 @@ impl Wake for TermWaker {

fn run_interactive(
args: Args,
project_dir: Option<Utf8PlatformPathBuf>,
target_path: Option<Utf8PlatformPathBuf>,
base_path: Option<Utf8PlatformPathBuf>,
project_config: Option<ProjectConfig>,
Expand All @@ -396,7 +434,7 @@ fn run_interactive(
let mut state = AppState {
jobs: Default::default(),
waker: Default::default(),
project_dir: args.project.clone(),
project_dir,
project_config,
target_path,
base_path,
Expand Down
1 change: 1 addition & 0 deletions objdiff-core/src/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::process::Command;

use typed_path::{Utf8PlatformPathBuf, Utf8UnixPath};

#[derive(Clone)]
pub struct BuildStatus {
pub success: bool,
pub cmdline: String,
Expand Down
22 changes: 14 additions & 8 deletions objdiff-core/src/jobs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,16 +203,22 @@ fn start_job(
error: None,
}));
let context = JobContext { status: status.clone(), waker: waker.clone() };
let context_inner = JobContext { status: status.clone(), waker };
let context_inner = JobContext { status: status.clone(), waker: waker.clone() };
let (tx, rx) = std::sync::mpsc::channel();
let handle = std::thread::spawn(move || match run(context_inner, rx) {
Ok(state) => state,
Err(e) => {
if let Ok(mut w) = status.write() {
w.error = Some(e);
let handle = std::thread::spawn(move || {
let result = match run(context_inner, rx) {
Ok(state) => state,
Err(e) => {
if let Ok(mut w) = status.write() {
w.error = Some(e);
}
JobResult::None
}
JobResult::None
}
};
// Always wake on completion, so the frontend notices jobs that finished
// (or failed) without reporting any progress.
waker.wake();
result
});
let id = JOB_ID.fetch_add(1, Ordering::Relaxed);
JobState { id, kind, handle: Some(handle), context, cancel: tx }
Expand Down
Loading