mirror of
https://github.com/encounter/objdiff.git
synced 2025-06-07 15:13:47 +00:00
Re-enable wgpu and wsl features; rework WSL config
Improve build failure log view & add copy buttons
This commit is contained in:
parent
b74a49ed0c
commit
4cdad8a519
4
.github/workflows/build.yaml
vendored
4
.github/workflows/build.yaml
vendored
@ -105,11 +105,11 @@ jobs:
|
|||||||
- platform: macos-latest
|
- platform: macos-latest
|
||||||
target: x86_64-apple-darwin
|
target: x86_64-apple-darwin
|
||||||
name: macos-x86_64
|
name: macos-x86_64
|
||||||
features: wgpu
|
features: default
|
||||||
- platform: macos-latest
|
- platform: macos-latest
|
||||||
target: aarch64-apple-darwin
|
target: aarch64-apple-darwin
|
||||||
name: macos-arm64
|
name: macos-arm64
|
||||||
features: wgpu
|
features: default
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
steps:
|
steps:
|
||||||
|
7
Cargo.lock
generated
7
Cargo.lock
generated
@ -2867,6 +2867,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
|
"shell-escape",
|
||||||
"similar",
|
"similar",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
@ -3719,6 +3720,12 @@ dependencies = [
|
|||||||
"lazy_static",
|
"lazy_static",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shell-escape"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signal-hook-registry"
|
name = "signal-hook-registry"
|
||||||
version = "1.4.1"
|
version = "1.4.1"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "objdiff"
|
name = "objdiff"
|
||||||
version = "0.6.1"
|
version = "0.7.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.70"
|
rust-version = "1.70"
|
||||||
authors = ["Luke Street <luke@street.dev>"]
|
authors = ["Luke Street <luke@street.dev>"]
|
||||||
@ -19,7 +19,7 @@ lto = "thin"
|
|||||||
strip = "debuginfo"
|
strip = "debuginfo"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = ["wgpu", "wsl"]
|
||||||
wgpu = ["eframe/wgpu"]
|
wgpu = ["eframe/wgpu"]
|
||||||
wsl = []
|
wsl = []
|
||||||
|
|
||||||
@ -53,6 +53,7 @@ semver = "1.0.20"
|
|||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1.0.108"
|
serde_json = "1.0.108"
|
||||||
serde_yaml = "0.9.27"
|
serde_yaml = "0.9.27"
|
||||||
|
shell-escape = "0.1.5"
|
||||||
similar = "2.3.0"
|
similar = "2.3.0"
|
||||||
tempfile = "3.8.1"
|
tempfile = "3.8.1"
|
||||||
thiserror = "1.0.50"
|
thiserror = "1.0.50"
|
||||||
|
@ -17,7 +17,20 @@ use crate::{
|
|||||||
|
|
||||||
pub struct BuildStatus {
|
pub struct BuildStatus {
|
||||||
pub success: bool,
|
pub success: bool,
|
||||||
pub log: String,
|
pub cmdline: String,
|
||||||
|
pub stdout: String,
|
||||||
|
pub stderr: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for BuildStatus {
|
||||||
|
fn default() -> Self {
|
||||||
|
BuildStatus {
|
||||||
|
success: true,
|
||||||
|
cmdline: String::new(),
|
||||||
|
stdout: String::new(),
|
||||||
|
stderr: String::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ObjDiffConfig {
|
pub struct ObjDiffConfig {
|
||||||
@ -88,16 +101,24 @@ fn run_make(cwd: &Path, arg: &Path, config: &ObjDiffConfig) -> BuildStatus {
|
|||||||
command.creation_flags(winapi::um::winbase::CREATE_NO_WINDOW);
|
command.creation_flags(winapi::um::winbase::CREATE_NO_WINDOW);
|
||||||
command
|
command
|
||||||
};
|
};
|
||||||
|
let mut cmdline =
|
||||||
|
shell_escape::escape(command.get_program().to_string_lossy()).into_owned();
|
||||||
|
for arg in command.get_args() {
|
||||||
|
cmdline.push(' ');
|
||||||
|
cmdline.push_str(shell_escape::escape(arg.to_string_lossy()).as_ref());
|
||||||
|
}
|
||||||
let output = command.output().context("Failed to execute build")?;
|
let output = command.output().context("Failed to execute build")?;
|
||||||
let stdout = from_utf8(&output.stdout).context("Failed to process stdout")?;
|
let stdout = from_utf8(&output.stdout).context("Failed to process stdout")?;
|
||||||
let stderr = from_utf8(&output.stderr).context("Failed to process stderr")?;
|
let stderr = from_utf8(&output.stderr).context("Failed to process stderr")?;
|
||||||
Ok(BuildStatus {
|
Ok(BuildStatus {
|
||||||
success: output.status.code().unwrap_or(-1) == 0,
|
success: output.status.code().unwrap_or(-1) == 0,
|
||||||
log: format!("{stdout}\n{stderr}"),
|
cmdline,
|
||||||
|
stdout: stdout.to_string(),
|
||||||
|
stderr: stderr.to_string(),
|
||||||
})
|
})
|
||||||
})() {
|
})() {
|
||||||
Ok(status) => status,
|
Ok(status) => status,
|
||||||
Err(e) => BuildStatus { success: false, log: e.to_string() },
|
Err(e) => BuildStatus { success: false, stderr: e.to_string(), ..Default::default() },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +171,7 @@ fn run_build(
|
|||||||
)?;
|
)?;
|
||||||
run_make(project_dir, target_path_rel, &config)
|
run_make(project_dir, target_path_rel, &config)
|
||||||
}
|
}
|
||||||
_ => BuildStatus { success: true, log: String::new() },
|
_ => BuildStatus::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let second_status = match base_path_rel {
|
let second_status = match base_path_rel {
|
||||||
@ -164,7 +185,7 @@ fn run_build(
|
|||||||
)?;
|
)?;
|
||||||
run_make(project_dir, base_path_rel, &config)
|
run_make(project_dir, base_path_rel, &config)
|
||||||
}
|
}
|
||||||
_ => BuildStatus { success: true, log: String::new() },
|
_ => BuildStatus::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let time = OffsetDateTime::now_utc();
|
let time = OffsetDateTime::now_utc();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#[cfg(feature = "wsl")]
|
#[cfg(all(windows, feature = "wsl"))]
|
||||||
use std::string::FromUtf16Error;
|
use std::string::FromUtf16Error;
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
@ -6,7 +6,7 @@ use std::{
|
|||||||
path::{PathBuf, MAIN_SEPARATOR},
|
path::{PathBuf, MAIN_SEPARATOR},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "wsl")]
|
#[cfg(all(windows, feature = "wsl"))]
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use const_format::formatcp;
|
use const_format::formatcp;
|
||||||
use egui::{
|
use egui::{
|
||||||
@ -46,7 +46,7 @@ pub struct ConfigViewState {
|
|||||||
pub object_search: String,
|
pub object_search: String,
|
||||||
pub filter_diffable: bool,
|
pub filter_diffable: bool,
|
||||||
pub filter_incomplete: bool,
|
pub filter_incomplete: bool,
|
||||||
#[cfg(feature = "wsl")]
|
#[cfg(all(windows, feature = "wsl"))]
|
||||||
pub available_wsl_distros: Option<Vec<String>>,
|
pub available_wsl_distros: Option<Vec<String>>,
|
||||||
pub file_dialog_state: FileDialogState,
|
pub file_dialog_state: FileDialogState,
|
||||||
}
|
}
|
||||||
@ -134,7 +134,7 @@ pub const DEFAULT_WATCH_PATTERNS: &[&str] = &[
|
|||||||
"*.inc", "*.py", "*.yml", "*.txt", "*.json",
|
"*.inc", "*.py", "*.yml", "*.txt", "*.json",
|
||||||
];
|
];
|
||||||
|
|
||||||
#[cfg(feature = "wsl")]
|
#[cfg(all(windows, feature = "wsl"))]
|
||||||
fn process_utf16(bytes: &[u8]) -> Result<String, FromUtf16Error> {
|
fn process_utf16(bytes: &[u8]) -> Result<String, FromUtf16Error> {
|
||||||
let u16_bytes: Vec<u16> = bytes
|
let u16_bytes: Vec<u16> = bytes
|
||||||
.chunks_exact(2)
|
.chunks_exact(2)
|
||||||
@ -143,7 +143,7 @@ fn process_utf16(bytes: &[u8]) -> Result<String, FromUtf16Error> {
|
|||||||
String::from_utf16(&u16_bytes)
|
String::from_utf16(&u16_bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "wsl")]
|
#[cfg(all(windows, feature = "wsl"))]
|
||||||
fn wsl_cmd(args: &[&str]) -> Result<String> {
|
fn wsl_cmd(args: &[&str]) -> Result<String> {
|
||||||
use std::{os::windows::process::CommandExt, process::Command};
|
use std::{os::windows::process::CommandExt, process::Command};
|
||||||
let output = Command::new("wsl")
|
let output = Command::new("wsl")
|
||||||
@ -154,7 +154,7 @@ fn wsl_cmd(args: &[&str]) -> Result<String> {
|
|||||||
process_utf16(&output.stdout).context("Failed to process stdout")
|
process_utf16(&output.stdout).context("Failed to process stdout")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "wsl")]
|
#[cfg(all(windows, feature = "wsl"))]
|
||||||
fn fetch_wsl2_distros() -> Vec<String> {
|
fn fetch_wsl2_distros() -> Vec<String> {
|
||||||
wsl_cmd(&["-l", "-q"])
|
wsl_cmd(&["-l", "-q"])
|
||||||
.map(|stdout| {
|
.map(|stdout| {
|
||||||
@ -176,7 +176,6 @@ pub fn config_ui(
|
|||||||
) {
|
) {
|
||||||
let mut config_guard = config.write().unwrap();
|
let mut config_guard = config.write().unwrap();
|
||||||
let AppConfig {
|
let AppConfig {
|
||||||
selected_wsl_distro,
|
|
||||||
target_obj_dir,
|
target_obj_dir,
|
||||||
base_obj_dir,
|
base_obj_dir,
|
||||||
selected_obj,
|
selected_obj,
|
||||||
@ -227,27 +226,6 @@ pub fn config_ui(
|
|||||||
}
|
}
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
||||||
#[cfg(feature = "wsl")]
|
|
||||||
{
|
|
||||||
ui.heading("Build");
|
|
||||||
if state.available_wsl_distros.is_none() {
|
|
||||||
state.available_wsl_distros = Some(fetch_wsl2_distros());
|
|
||||||
}
|
|
||||||
egui::ComboBox::from_label("Run in WSL2")
|
|
||||||
.selected_text(selected_wsl_distro.as_ref().unwrap_or(&"Disabled".to_string()))
|
|
||||||
.show_ui(ui, |ui| {
|
|
||||||
ui.selectable_value(selected_wsl_distro, None, "Disabled");
|
|
||||||
for distro in state.available_wsl_distros.as_ref().unwrap() {
|
|
||||||
ui.selectable_value(selected_wsl_distro, Some(distro.clone()), distro);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
ui.separator();
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "wsl"))]
|
|
||||||
{
|
|
||||||
let _ = selected_wsl_distro;
|
|
||||||
}
|
|
||||||
|
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.heading("Project");
|
ui.heading("Project");
|
||||||
if ui.button(RichText::new("Settings")).clicked() {
|
if ui.button(RichText::new("Settings")).clicked() {
|
||||||
@ -649,6 +627,24 @@ fn split_obj_config_ui(
|
|||||||
config.custom_make = Some(custom_make_str);
|
config.custom_make = Some(custom_make_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(all(windows, feature = "wsl"))]
|
||||||
|
{
|
||||||
|
if state.available_wsl_distros.is_none() {
|
||||||
|
state.available_wsl_distros = Some(fetch_wsl2_distros());
|
||||||
|
}
|
||||||
|
egui::ComboBox::from_label("Run in WSL2")
|
||||||
|
.selected_text(config.selected_wsl_distro.as_ref().unwrap_or(&"Disabled".to_string()))
|
||||||
|
.show_ui(ui, |ui| {
|
||||||
|
ui.selectable_value(&mut config.selected_wsl_distro, None, "Disabled");
|
||||||
|
for distro in state.available_wsl_distros.as_ref().unwrap() {
|
||||||
|
ui.selectable_value(
|
||||||
|
&mut config.selected_wsl_distro,
|
||||||
|
Some(distro.clone()),
|
||||||
|
distro,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
||||||
if let Some(project_dir) = config.project_dir.clone() {
|
if let Some(project_dir) = config.project_dir.clone() {
|
||||||
|
@ -262,11 +262,23 @@ fn symbol_list_ui(
|
|||||||
|
|
||||||
fn build_log_ui(ui: &mut Ui, status: &BuildStatus, appearance: &Appearance) {
|
fn build_log_ui(ui: &mut Ui, status: &BuildStatus, appearance: &Appearance) {
|
||||||
ScrollArea::both().auto_shrink([false, false]).show(ui, |ui| {
|
ScrollArea::both().auto_shrink([false, false]).show(ui, |ui| {
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
if ui.button("Copy command").clicked() {
|
||||||
|
ui.output_mut(|output| output.copied_text = status.cmdline.clone());
|
||||||
|
}
|
||||||
|
if ui.button("Copy log").clicked() {
|
||||||
|
ui.output_mut(|output| {
|
||||||
|
output.copied_text = format!("{}\n{}", status.stdout, status.stderr)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
ui.scope(|ui| {
|
ui.scope(|ui| {
|
||||||
ui.style_mut().override_text_style = Some(egui::TextStyle::Monospace);
|
ui.style_mut().override_text_style = Some(egui::TextStyle::Monospace);
|
||||||
ui.style_mut().wrap = Some(false);
|
ui.style_mut().wrap = Some(false);
|
||||||
|
|
||||||
ui.colored_label(appearance.replace_color, &status.log);
|
ui.label(&status.cmdline);
|
||||||
|
ui.colored_label(appearance.replace_color, &status.stdout);
|
||||||
|
ui.colored_label(appearance.delete_color, &status.stderr);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user