mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-11-06 00:32:13 +08:00
fix(macos): keep DNS state outside app bundle (#7544)
* fix(macos): keep DNS state outside app bundle * fix(macos): restore legacy DNS state --------- Co-authored-by: Arcanum <260421450+ArcanePivot@users.noreply.github.com> Co-authored-by: wonfen <eiwonfen@gmail.com>
This commit is contained in:
co-authored by
Arcanum
wonfen
parent
ef179fcf61
commit
7d8f98e183
@@ -1,4 +1,22 @@
|
||||
use clash_verge_logging::{Type, logging};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
const DNS_STATE_FILE: &str = ".original_dns.txt";
|
||||
|
||||
fn dns_state_dir() -> anyhow::Result<PathBuf> {
|
||||
// The DNS scripts persist .original_dns.txt relative to their working directory.
|
||||
let dir = crate::utils::dirs::app_home_dir()?;
|
||||
std::fs::create_dir_all(&dir)?;
|
||||
Ok(dir)
|
||||
}
|
||||
|
||||
fn restore_dns_state_dir(resource_dir: &Path, state_dir: PathBuf) -> PathBuf {
|
||||
if resource_dir.join(DNS_STATE_FILE).exists() {
|
||||
resource_dir.to_path_buf()
|
||||
} else {
|
||||
state_dir
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn set_public_dns(dns_server: String) {
|
||||
use crate::{core::handle, utils::dirs};
|
||||
@@ -19,11 +37,18 @@ pub async fn set_public_dns(dns_server: String) {
|
||||
return;
|
||||
}
|
||||
let script = script.to_string_lossy().into_owned();
|
||||
let state_dir = match dns_state_dir() {
|
||||
Ok(dir) => dir,
|
||||
Err(e) => {
|
||||
logging!(error, Type::Config, "Failed to get DNS state directory: {}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
match app_handle
|
||||
.shell()
|
||||
.command("bash")
|
||||
.args([script, dns_server])
|
||||
.current_dir(resource_dir)
|
||||
.current_dir(state_dir)
|
||||
.status()
|
||||
.await
|
||||
{
|
||||
@@ -60,11 +85,19 @@ pub async fn restore_public_dns() {
|
||||
return;
|
||||
}
|
||||
let script = script.to_string_lossy().into_owned();
|
||||
let state_dir = match dns_state_dir() {
|
||||
Ok(dir) => dir,
|
||||
Err(e) => {
|
||||
logging!(error, Type::Config, "Failed to get DNS state directory: {}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let state_dir = restore_dns_state_dir(&resource_dir, state_dir);
|
||||
match app_handle
|
||||
.shell()
|
||||
.command("bash")
|
||||
.args([script])
|
||||
.current_dir(resource_dir)
|
||||
.current_dir(state_dir)
|
||||
.status()
|
||||
.await
|
||||
{
|
||||
@@ -81,3 +114,24 @@ pub async fn restore_public_dns() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::restore_dns_state_dir;
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::expect_used)]
|
||||
fn restore_dns_state_dir_defaults_to_app_data_but_honors_legacy_file() {
|
||||
let root = std::env::temp_dir().join(format!("clash-verge-dns-{}", nanoid::nanoid!()));
|
||||
let resource_dir = root.join("resources");
|
||||
let state_dir = root.join("app-data");
|
||||
std::fs::create_dir_all(&resource_dir).expect("create test resource directory");
|
||||
|
||||
assert_eq!(restore_dns_state_dir(&resource_dir, state_dir.clone()), state_dir);
|
||||
|
||||
std::fs::write(resource_dir.join(".original_dns.txt"), "empty").expect("create legacy DNS state");
|
||||
assert_eq!(restore_dns_state_dir(&resource_dir, state_dir), resource_dir);
|
||||
|
||||
std::fs::remove_dir_all(root).expect("remove test directory");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user