//! Check the local environment: CLI version, platform, state/socket dirs, //! and free disk space. use std::path::Path; use super::helpers::{disk_free_bytes, human_size, is_writable_dir}; use super::{Check, Status}; use crate::connection::get_socket_dir; use crate::native::state::get_state_dir; pub(super) fn check(checks: &mut Vec) { let category = "Environment"; let version = env!("CARGO_PKG_VERSION"); let platform = format!("{} {}", std::env::consts::OS, std::env::consts::ARCH); checks.push(Check::new( "env.version", category, Status::Pass, format!("CLI version {} ({})", version, platform), )); match dirs::home_dir() { Some(home) => checks.push(Check::new( "env.home", category, Status::Pass, format!("Home directory {}", home.display()), )), None => checks.push(Check::new( "env.home", category, Status::Fail, "Could not determine home directory", )), } let state_dir = get_state_dir(); let socket_dir = get_socket_dir(); // Under the default setup, state and socket dirs are the same // (~/.chrome-use). Collapse to a single line when they match; // split when XDG_RUNTIME_DIR or AGENT_BROWSER_SOCKET_DIR diverts // sockets elsewhere. if state_dir == socket_dir { push_dir_check( checks, "env.state_dir", category, "State and socket directory", &state_dir, ); } else { push_dir_check( checks, "env.state_dir", category, "State directory", &state_dir, ); push_dir_check( checks, "env.socket_dir", category, "Socket directory", &socket_dir, ); } match disk_free_bytes(&state_dir) { Some(bytes) => { let mb = bytes / (1024 * 1024); let human = human_size(bytes); if mb < 500 { checks.push( Check::new( "env.disk_free", category, Status::Warn, format!("Low disk space at state dir: {} free", human), ) .with_fix("free up disk space; Chrome installs require ~500 MB"), ); } else { checks.push(Check::new( "env.disk_free", category, Status::Pass, format!("{} free at state dir", human), )); } } None => checks.push(Check::new( "env.disk_free", category, Status::Info, "Disk free check unavailable on this platform", )), } } fn push_dir_check( checks: &mut Vec, id: &'static str, category: &'static str, label: &str, dir: &Path, ) { if dir.exists() { if is_writable_dir(dir) { checks.push(Check::new( id, category, Status::Pass, format!("{} {}", label, dir.display()), )); } else { checks.push( Check::new( id, category, Status::Fail, format!("{} not writable: {}", label, dir.display()), ) .with_fix(format!("chmod u+rwx {}", dir.display())), ); } } else { checks.push(Check::new( id, category, Status::Info, format!( "{} does not exist yet (will be created on first use): {}", label, dir.display() ), )); } }