use std::fs;
use std::io;
use std::path::{Path, PathBuf};
pub fn default_profile_dir() -> Option<PathBuf> {
let home = std::env::var_os("HOME").map(PathBuf::from);
if cfg!(target_os = "linux") {
let h = home?;
for candidate in [
".config/google-chrome",
".config/chromium",
".config/microsoft-edge",
] {
let p = h.join(candidate);
if p.exists() {
return Some(p);
}
}
None
} else if cfg!(target_os = "macos") {
let h = home?;
for candidate in [
"Library/Application Support/Google/Chrome",
"Library/Application Support/Chromium",
"Library/Application Support/Microsoft Edge",
] {
let p = h.join(candidate);
if p.exists() {
return Some(p);
}
}
None
} else if cfg!(target_os = "windows") {
std::env::var_os("LOCALAPPDATA").map(|d| {
PathBuf::from(d)
.join("Google")
.join("Chrome")
.join("User Data")
})
} else {
None
}
}
pub fn clone_profile_dir(src: &Path) -> io::Result<PathBuf> {
static COUNTER: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
let n = COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
let dst = std::env::temp_dir().join(format!("eoka-profile-clone-{}-{}", std::process::id(), n));
fs::create_dir_all(&dst)?;
copy_recursive(src, &dst)?;
Ok(dst)
}
fn should_skip(name: &str) -> bool {
matches!(
name,
"SingletonSocket" | "SingletonCookie" | "SingletonLock"
| "Crashpad" | "Crash Reports" | "GrShaderCache" | "ShaderCache"
| "GraphiteDawnCache" | "component_crx_cache"
| "Service Worker" | "Code Cache" | "CacheStorage" | "Cache"
| "Extension Rules" | "Extension State"
)
}
fn copy_recursive(src: &Path, dst: &Path) -> io::Result<()> {
if !src.is_dir() {
return Ok(());
}
for entry in fs::read_dir(src)? {
let entry = entry?;
let name = entry.file_name();
let name_str = name.to_string_lossy();
if should_skip(&name_str) {
continue;
}
let from = entry.path();
let to = dst.join(&name);
let ft = entry.file_type()?;
if ft.is_dir() {
fs::create_dir_all(&to)?;
copy_recursive(&from, &to)?;
} else if ft.is_file() {
if let Err(e) = fs::copy(&from, &to) {
eprintln!("[eoka] skipping {}: {}", from.display(), e);
}
}
}
Ok(())
}