// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 use miette::{IntoDiagnostic, Result, WrapErr}; use std::path::PathBuf; pub fn xdg_config_dir() -> Result { if let Ok(path) = std::env::var("XDG_CONFIG_HOME") { return Ok(PathBuf::from(path)); } let home = std::env::var("HOME") .into_diagnostic() .wrap_err("HOME is not set")?; Ok(PathBuf::from(home).join(".config")) } /// Path to the file that stores the active gateway name. /// /// Location: `$XDG_CONFIG_HOME/openshell/active_gateway` pub fn active_gateway_path() -> Result { Ok(xdg_config_dir()?.join("openshell").join("active_gateway")) } /// Base directory for all gateway metadata files. /// /// Location: `$XDG_CONFIG_HOME/openshell/gateways/` pub fn gateways_dir() -> Result { Ok(xdg_config_dir()?.join("openshell").join("gateways")) } /// Path to the file that stores the last-used sandbox name for a gateway. /// /// Location: `$XDG_CONFIG_HOME/openshell/gateways//last_sandbox` pub fn last_sandbox_path(gateway: &str) -> Result { Ok(gateways_dir()?.join(gateway).join("last_sandbox")) } #[cfg(test)] mod tests { use super::*; #[test] #[allow(unsafe_code)] fn last_sandbox_path_layout() { let _guard = crate::XDG_TEST_LOCK .lock() .unwrap_or_else(std::sync::PoisonError::into_inner); let tmp = tempfile::tempdir().unwrap(); let orig = std::env::var("XDG_CONFIG_HOME").ok(); unsafe { std::env::set_var("XDG_CONFIG_HOME", tmp.path()); } let path = last_sandbox_path("my-gateway").unwrap(); assert!( path.ends_with("openshell/gateways/my-gateway/last_sandbox"), "unexpected path: {path:?}" ); unsafe { match orig { Some(v) => std::env::set_var("XDG_CONFIG_HOME", v), None => std::env::remove_var("XDG_CONFIG_HOME"), } } } }