mirror of
https://github.com/encounter/objdiff.git
synced 2025-12-09 13:37:55 +00:00
Version 0.2.0
- Update checker & auto-updater - Configure font sizes and diff colors - Data diffing bug fixes & improvements - Bug fix for low match percent - Improvements to Jobs UI (cancel, dismiss errors) - "Demangle" tool Closes #6, #13, #17, #19
This commit is contained in:
@@ -38,7 +38,7 @@ fn run_build(
|
||||
}
|
||||
|
||||
pub fn queue_bindiff(config: Arc<RwLock<AppConfig>>) -> JobState {
|
||||
queue_job(Job::BinDiff, move |status, cancel| {
|
||||
queue_job("Binary diff", Job::BinDiff, move |status, cancel| {
|
||||
run_build(status, cancel, config).map(JobResult::BinDiff)
|
||||
})
|
||||
}
|
||||
|
||||
33
src/jobs/check_update.rs
Normal file
33
src/jobs/check_update.rs
Normal file
@@ -0,0 +1,33 @@
|
||||
use std::sync::mpsc::Receiver;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use self_update::{cargo_crate_version, update::Release};
|
||||
|
||||
use crate::{
|
||||
jobs::{queue_job, update_status, Job, JobResult, JobState, Status},
|
||||
update::{build_updater, BIN_NAME},
|
||||
};
|
||||
|
||||
pub struct CheckUpdateResult {
|
||||
pub update_available: bool,
|
||||
pub latest_release: Release,
|
||||
pub found_binary: bool,
|
||||
}
|
||||
|
||||
fn run_check_update(status: &Status, cancel: Receiver<()>) -> Result<Box<CheckUpdateResult>> {
|
||||
update_status(status, "Fetching latest release".to_string(), 0, 1, &cancel)?;
|
||||
let updater = build_updater().context("Failed to create release updater")?;
|
||||
let latest_release = updater.get_latest_release()?;
|
||||
let update_available =
|
||||
self_update::version::bump_is_greater(cargo_crate_version!(), &latest_release.version)?;
|
||||
let found_binary = latest_release.assets.iter().any(|a| a.name == BIN_NAME);
|
||||
|
||||
update_status(status, "Complete".to_string(), 1, 1, &cancel)?;
|
||||
Ok(Box::new(CheckUpdateResult { update_available, latest_release, found_binary }))
|
||||
}
|
||||
|
||||
pub fn queue_check_update() -> JobState {
|
||||
queue_job("Check for updates", Job::CheckUpdate, move |status, cancel| {
|
||||
run_check_update(status, cancel).map(JobResult::CheckUpdate)
|
||||
})
|
||||
}
|
||||
@@ -9,15 +9,22 @@ use std::{
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::jobs::{bindiff::BinDiffResult, objdiff::ObjDiffResult};
|
||||
use crate::jobs::{
|
||||
bindiff::BinDiffResult, check_update::CheckUpdateResult, objdiff::ObjDiffResult,
|
||||
update::UpdateResult,
|
||||
};
|
||||
|
||||
pub mod bindiff;
|
||||
pub mod check_update;
|
||||
pub mod objdiff;
|
||||
pub mod update;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
|
||||
pub enum Job {
|
||||
ObjDiff,
|
||||
BinDiff,
|
||||
CheckUpdate,
|
||||
Update,
|
||||
}
|
||||
pub static JOB_ID: AtomicUsize = AtomicUsize::new(0);
|
||||
pub struct JobState {
|
||||
@@ -40,6 +47,8 @@ pub enum JobResult {
|
||||
None,
|
||||
ObjDiff(Box<ObjDiffResult>),
|
||||
BinDiff(Box<BinDiffResult>),
|
||||
CheckUpdate(Box<CheckUpdateResult>),
|
||||
Update(Box<UpdateResult>),
|
||||
}
|
||||
|
||||
fn should_cancel(rx: &Receiver<()>) -> bool {
|
||||
@@ -52,14 +61,15 @@ fn should_cancel(rx: &Receiver<()>) -> bool {
|
||||
type Status = Arc<RwLock<JobStatus>>;
|
||||
|
||||
fn queue_job(
|
||||
title: &str,
|
||||
job_type: Job,
|
||||
run: impl FnOnce(&Status, Receiver<()>) -> Result<JobResult> + Send + 'static,
|
||||
) -> JobState {
|
||||
let status = Arc::new(RwLock::new(JobStatus {
|
||||
title: String::new(),
|
||||
title: title.to_string(),
|
||||
progress_percent: 0.0,
|
||||
progress_items: None,
|
||||
status: "".to_string(),
|
||||
status: String::new(),
|
||||
error: None,
|
||||
}));
|
||||
let status_clone = status.clone();
|
||||
|
||||
@@ -19,6 +19,7 @@ pub struct BuildStatus {
|
||||
pub success: bool,
|
||||
pub log: String,
|
||||
}
|
||||
|
||||
pub struct ObjDiffResult {
|
||||
pub first_status: BuildStatus,
|
||||
pub second_status: BuildStatus,
|
||||
@@ -29,7 +30,7 @@ pub struct ObjDiffResult {
|
||||
|
||||
fn run_make(cwd: &Path, arg: &Path, config: &AppConfig) -> BuildStatus {
|
||||
match (|| -> Result<BuildStatus> {
|
||||
let make = if config.custom_make.is_empty() { "make" } else { &config.custom_make };
|
||||
let make = config.custom_make.as_deref().unwrap_or("make");
|
||||
#[cfg(not(windows))]
|
||||
let mut command = {
|
||||
let mut command = Command::new(make);
|
||||
@@ -136,7 +137,7 @@ fn run_build(
|
||||
}
|
||||
|
||||
pub fn queue_build(config: Arc<RwLock<AppConfig>>, diff_config: DiffConfig) -> JobState {
|
||||
queue_job(Job::ObjDiff, move |status, cancel| {
|
||||
queue_job("Object diff", Job::ObjDiff, move |status, cancel| {
|
||||
run_build(status, cancel, config, diff_config).map(JobResult::ObjDiff)
|
||||
})
|
||||
}
|
||||
|
||||
61
src/jobs/update.rs
Normal file
61
src/jobs/update.rs
Normal file
@@ -0,0 +1,61 @@
|
||||
use std::{
|
||||
env::{current_dir, current_exe},
|
||||
fs,
|
||||
fs::File,
|
||||
path::PathBuf,
|
||||
sync::mpsc::Receiver,
|
||||
};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use const_format::formatcp;
|
||||
|
||||
use crate::{
|
||||
jobs::{queue_job, update_status, Job, JobResult, JobState, Status},
|
||||
update::{build_updater, BIN_NAME},
|
||||
};
|
||||
|
||||
pub struct UpdateResult {
|
||||
pub exe_path: PathBuf,
|
||||
}
|
||||
|
||||
fn run_update(status: &Status, cancel: Receiver<()>) -> Result<Box<UpdateResult>> {
|
||||
update_status(status, "Fetching latest release".to_string(), 0, 3, &cancel)?;
|
||||
let updater = build_updater().context("Failed to create release updater")?;
|
||||
let latest_release = updater.get_latest_release()?;
|
||||
let asset = latest_release
|
||||
.assets
|
||||
.iter()
|
||||
.find(|a| a.name == BIN_NAME)
|
||||
.ok_or(anyhow::Error::msg(formatcp!("No release asset for {}", BIN_NAME)))?;
|
||||
|
||||
update_status(status, "Downloading release".to_string(), 1, 3, &cancel)?;
|
||||
let tmp_dir = tempfile::Builder::new().prefix("update").tempdir_in(current_dir()?)?;
|
||||
let tmp_path = tmp_dir.path().join(&asset.name);
|
||||
let tmp_file = File::create(&tmp_path)?;
|
||||
self_update::Download::from_url(&asset.download_url)
|
||||
.set_header(reqwest::header::ACCEPT, "application/octet-stream".parse()?)
|
||||
.download_to(&tmp_file)?;
|
||||
|
||||
update_status(status, "Extracting release".to_string(), 2, 3, &cancel)?;
|
||||
let tmp_file = tmp_dir.path().join("replacement_tmp");
|
||||
let target_file = current_exe()?;
|
||||
self_update::Move::from_source(&tmp_path)
|
||||
.replace_using_temp(&tmp_file)
|
||||
.to_dest(&target_file)?;
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
let mut perms = fs::metadata(&target_file)?.permissions();
|
||||
perms.set_mode(0755);
|
||||
fs::set_permissions(&target_file, perms)?;
|
||||
}
|
||||
|
||||
update_status(status, "Complete".to_string(), 3, 3, &cancel)?;
|
||||
Ok(Box::from(UpdateResult { exe_path: target_file }))
|
||||
}
|
||||
|
||||
pub fn queue_update() -> JobState {
|
||||
queue_job("Update app", Job::Update, move |status, cancel| {
|
||||
run_update(status, cancel).map(JobResult::Update)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user