Address review: Linux data-dir caches, bash invocation, pre-webview clear
Three review findings, all verified: 1. wry keys the WebKitGTK base-cache dir to the app DATA dir (same as base-data), so on Linux the stale frontend cache also lives under ~/.local/share/ai.unsloth.studio. Clear the cache-typed subdirs there (WebKitCache, CacheStorage, serviceworkers) while keeping localstorage, indexeddb, and cookies. Tests extended to 23 assertions. 2. run_all.sh invoked the new test with sh, but the extracted setup.sh function uses bash arrays; dash aborts with a syntax error before any assertion. Invoke with bash. 3. The in-app desktop update runs start_backend_update before downloadAndInstall/relaunch, so setup.ps1/setup.sh clear caches while the live WebView still holds them and silently fail. Clear the caches from the Rust side in main() before the Builder runs: the config window (and the WebView lock) exists by the time setup hooks fire, so this is the one point where the profile is guaranteed unlocked. Same cache-only path lists per OS; cargo check passes.
This commit is contained in:
parent
1eb3ac26e7
commit
cbb1508513
4 changed files with 101 additions and 15 deletions
|
|
@ -492,7 +492,18 @@ _clear_webview_caches() {
|
|||
)
|
||||
;;
|
||||
Linux)
|
||||
_wvc_paths=("${XDG_CACHE_HOME:-$HOME/.cache}/$_wvc_bid")
|
||||
# wry keys the WebKitGTK base-cache dir to the app DATA dir (same
|
||||
# as base-data), so cache subdirs also live under
|
||||
# ~/.local/share/<bid>. Clear only the cache-typed subdirs there;
|
||||
# sibling localstorage/, indexeddb/, and cookies stay.
|
||||
_wvc_data="${XDG_DATA_HOME:-$HOME/.local/share}/$_wvc_bid"
|
||||
_wvc_paths=(
|
||||
"${XDG_CACHE_HOME:-$HOME/.cache}/$_wvc_bid"
|
||||
"$_wvc_data/WebKitCache"
|
||||
"$_wvc_data/CacheStorage"
|
||||
"$_wvc_data/serviceworkers"
|
||||
"$_wvc_data/ServiceWorkers"
|
||||
)
|
||||
;;
|
||||
*) return 0 ;;
|
||||
esac
|
||||
|
|
|
|||
|
|
@ -161,6 +161,64 @@ fn setup_tray(app: &tauri::App) -> Result<(), Box<dyn std::error::Error>> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
// Clear WebView caches before the webview initializes. An in-app update runs
|
||||
// setup.sh/setup.ps1 while the old WebView still holds these files (its clear
|
||||
// silently fails), so without this a relaunch can serve the previous frontend
|
||||
// from cache. Cache-only paths; LocalStorage, IndexedDB, cookies, and app
|
||||
// data are kept. Mirrors setup.sh _clear_webview_caches / setup.ps1.
|
||||
fn clear_webview_caches(bundle_id: &str) {
|
||||
use std::path::PathBuf;
|
||||
let mut paths: Vec<PathBuf> = Vec::new();
|
||||
#[cfg(target_os = "windows")]
|
||||
if let Ok(local) = std::env::var("LOCALAPPDATA") {
|
||||
if !local.is_empty() {
|
||||
let profile = PathBuf::from(local)
|
||||
.join(bundle_id)
|
||||
.join("EBWebView")
|
||||
.join("Default");
|
||||
for sub in ["Cache", "Code Cache", "GPUCache", "Service Worker"] {
|
||||
paths.push(profile.join(sub));
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
if let Ok(home) = std::env::var("HOME") {
|
||||
if !home.is_empty() {
|
||||
let home = PathBuf::from(home);
|
||||
paths.push(home.join("Library/Caches").join(bundle_id));
|
||||
let data = home.join("Library/WebKit").join(bundle_id).join("WebsiteData");
|
||||
for sub in ["CacheStorage", "ServiceWorkers", "DiskCache"] {
|
||||
paths.push(data.join(sub));
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(target_os = "linux")]
|
||||
if let Ok(home) = std::env::var("HOME") {
|
||||
if !home.is_empty() {
|
||||
let home = PathBuf::from(home);
|
||||
let cache = std::env::var("XDG_CACHE_HOME")
|
||||
.ok()
|
||||
.filter(|v| !v.is_empty())
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|| home.join(".cache"));
|
||||
paths.push(cache.join(bundle_id));
|
||||
// wry keys the WebKitGTK base-cache dir to the app data dir.
|
||||
let data = std::env::var("XDG_DATA_HOME")
|
||||
.ok()
|
||||
.filter(|v| !v.is_empty())
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|| home.join(".local/share"))
|
||||
.join(bundle_id);
|
||||
for sub in ["WebKitCache", "CacheStorage", "serviceworkers", "ServiceWorkers"] {
|
||||
paths.push(data.join(sub));
|
||||
}
|
||||
}
|
||||
}
|
||||
for p in paths {
|
||||
let _ = fs::remove_dir_all(&p);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Fix PATH for GUI apps (macOS .app bundles, Linux AppImage, Windows)
|
||||
// GUI apps don't inherit shell dotfile PATH — this spawns the user's
|
||||
|
|
@ -171,6 +229,11 @@ fn main() {
|
|||
info!("Unsloth Studio desktop app starting");
|
||||
windows_job::initialize();
|
||||
|
||||
// Must run before the Builder: the config-defined window (and its
|
||||
// WebView, which locks these files) exists by the time setup hooks run.
|
||||
let context = tauri::generate_context!();
|
||||
clear_webview_caches(&context.config().identifier);
|
||||
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_single_instance::init(|app, _args, _cwd| {
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
|
|
@ -247,7 +310,7 @@ fn main() {
|
|||
api.prevent_close();
|
||||
}
|
||||
})
|
||||
.build(tauri::generate_context!())
|
||||
.build(context)
|
||||
.expect("error while building tauri application")
|
||||
.run(|app, event| {
|
||||
if let tauri::RunEvent::Exit = event {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ sh "$TESTS_DIR/sh/test_nvcc_meets_llama_minimum.sh"
|
|||
sh "$TESTS_DIR/sh/test_resolve_cuda_archs.sh"
|
||||
sh "$TESTS_DIR/sh/test_strixhalo_wsl_reroute.sh"
|
||||
sh "$TESTS_DIR/sh/test_uninstall_shared_icon.sh"
|
||||
sh "$TESTS_DIR/sh/test_setup_webview_cache_clear.sh"
|
||||
# bash, not sh: the extracted setup.sh function uses bash arrays (dash chokes).
|
||||
bash "$TESTS_DIR/sh/test_setup_webview_cache_clear.sh"
|
||||
sh "$TESTS_DIR/sh/test_torch_flavor.sh"
|
||||
sh "$TESTS_DIR/sh/test_redact_install_output.sh"
|
||||
sh "$TESTS_DIR/sh/test_install_uv_override_space.sh"
|
||||
|
|
|
|||
|
|
@ -53,23 +53,34 @@ assert_present "macOS: IndexedDB kept" "$H/Library/WebKit/$BID
|
|||
assert_present "macOS: Application Support kept" "$H/Library/Application Support/$BID"
|
||||
assert_present "macOS: unrelated app cache kept" "$H/Library/Caches/com.other.app"
|
||||
|
||||
# ── 2. Linux: cache dir removed, data/config kept ──
|
||||
# ── 2. Linux: cache paths removed (XDG cache dir AND the cache subdirs wry
|
||||
# keys to the app data dir), user-facing storage kept ──
|
||||
H=$(mktemp -d -p "$_TMP_ROOT")
|
||||
mkdir -p "$H/.cache/$BID" "$H/.local/share/$BID" "$H/.config/$BID" "$H/.cache/other.app"
|
||||
D="$H/.local/share/$BID"
|
||||
mkdir -p "$H/.cache/$BID" "$D/WebKitCache" "$D/CacheStorage" "$D/serviceworkers" \
|
||||
"$D/localstorage" "$D/indexeddb" "$H/.config/$BID" "$H/.cache/other.app"
|
||||
: > "$D/cookies.sqlite"
|
||||
uname() { echo Linux; }
|
||||
HOME="$H" XDG_CACHE_HOME="" _clear_webview_caches
|
||||
assert_gone "linux: ~/.cache/$BID removed" "$H/.cache/$BID"
|
||||
assert_present "linux: ~/.local/share/$BID kept" "$H/.local/share/$BID"
|
||||
assert_present "linux: ~/.config/$BID kept" "$H/.config/$BID"
|
||||
assert_present "linux: unrelated app cache kept" "$H/.cache/other.app"
|
||||
HOME="$H" XDG_CACHE_HOME="" XDG_DATA_HOME="" _clear_webview_caches
|
||||
assert_gone "linux: ~/.cache/$BID removed" "$H/.cache/$BID"
|
||||
assert_gone "linux: data-dir WebKitCache removed" "$D/WebKitCache"
|
||||
assert_gone "linux: data-dir CacheStorage removed" "$D/CacheStorage"
|
||||
assert_gone "linux: data-dir serviceworkers removed" "$D/serviceworkers"
|
||||
assert_present "linux: localstorage kept" "$D/localstorage"
|
||||
assert_present "linux: indexeddb kept" "$D/indexeddb"
|
||||
assert_present "linux: cookies kept" "$D/cookies.sqlite"
|
||||
assert_present "linux: ~/.config/$BID kept" "$H/.config/$BID"
|
||||
assert_present "linux: unrelated app cache kept" "$H/.cache/other.app"
|
||||
|
||||
# ── 3. Linux: XDG_CACHE_HOME override honored ──
|
||||
# ── 3. Linux: XDG_CACHE_HOME / XDG_DATA_HOME overrides honored ──
|
||||
H=$(mktemp -d -p "$_TMP_ROOT")
|
||||
XDG=$(mktemp -d -p "$_TMP_ROOT")
|
||||
mkdir -p "$XDG/$BID" "$H/.cache/$BID"
|
||||
HOME="$H" XDG_CACHE_HOME="$XDG" _clear_webview_caches
|
||||
assert_gone "linux: XDG_CACHE_HOME/$BID removed" "$XDG/$BID"
|
||||
assert_present "linux: ~/.cache/$BID kept under override" "$H/.cache/$BID"
|
||||
mkdir -p "$XDG/cache/$BID" "$XDG/data/$BID/WebKitCache" "$XDG/data/$BID/localstorage" "$H/.cache/$BID"
|
||||
HOME="$H" XDG_CACHE_HOME="$XDG/cache" XDG_DATA_HOME="$XDG/data" _clear_webview_caches
|
||||
assert_gone "linux: XDG_CACHE_HOME/$BID removed" "$XDG/cache/$BID"
|
||||
assert_gone "linux: XDG_DATA_HOME WebKitCache removed" "$XDG/data/$BID/WebKitCache"
|
||||
assert_present "linux: XDG_DATA_HOME localstorage kept" "$XDG/data/$BID/localstorage"
|
||||
assert_present "linux: ~/.cache/$BID kept under override" "$H/.cache/$BID"
|
||||
|
||||
# ── 4. Nothing to clear is a clean no-op ──
|
||||
H=$(mktemp -d -p "$_TMP_ROOT")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue