use crate::util::strip_unc_pathbuf;
use color_eyre::Result;
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::{Path, PathBuf};
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct Settings {
pub root_path: Option<PathBuf>,
#[serde(default)]
pub update_by_default: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CachedRepo {
pub path: PathBuf,
pub remote: Option<String>,
}
impl Settings {
pub fn load() -> Result<Self> {
let config_path = Self::config_file_path()?;
if !config_path.exists() {
return Ok(Self::default());
}
let contents = fs::read_to_string(&config_path)?;
let settings: Settings = toml::from_str(&contents)?;
Ok(settings)
}
pub fn save(&self) -> Result<()> {
let config_path = Self::config_file_path()?;
if let Some(parent) = config_path.parent() {
fs::create_dir_all(parent)?;
}
let contents = toml::to_string_pretty(self)?;
fs::write(&config_path, contents)?;
Ok(())
}
fn config_file_path() -> Result<PathBuf> {
let config_dir = dirs::config_dir()
.ok_or_else(|| color_eyre::eyre::eyre!("Could not determine config directory"))?;
Ok(config_dir.join("git-repos").join("config.toml"))
}
pub fn set_root_path(&mut self, path: PathBuf) -> Result<()> {
let cleaned_path = strip_unc_pathbuf(path.as_path());
self.root_path = Some(cleaned_path);
self.save()
}
pub fn set_update(&mut self, enabled: bool) -> Result<()> {
self.update_by_default = enabled;
self.save()
}
}
pub fn save_repo_cache(_root: &Path, repos: &[CachedRepo]) -> Result<()> {
let config_dir = dirs::config_dir()
.ok_or_else(|| color_eyre::eyre::eyre!("Could not determine config directory"))?;
let cache_path = config_dir.join("git-repos").join("repos.yaml");
if let Some(parent) = cache_path.parent() {
fs::create_dir_all(parent)?;
}
let yaml = yaml_serde::to_string(repos)?;
fs::write(&cache_path, yaml)?;
Ok(())
}
pub fn load_repo_cache() -> Result<Vec<CachedRepo>> {
let config_dir = dirs::config_dir()
.ok_or_else(|| color_eyre::eyre::eyre!("Could not determine config directory"))?;
let cache_path = config_dir.join("git-repos").join("repos.yaml");
if !cache_path.exists() {
return Ok(Vec::new());
}
let contents = fs::read_to_string(&cache_path)?;
let repos: Vec<CachedRepo> = yaml_serde::from_str(&contents)?;
Ok(repos)
}
pub fn remove_from_cache(relative_path: &Path) -> Result<()> {
let mut cached_repos = load_repo_cache()?;
cached_repos.retain(|repo| repo.path != relative_path);
let config_dir = dirs::config_dir()
.ok_or_else(|| color_eyre::eyre::eyre!("Could not determine config directory"))?;
let cache_path = config_dir.join("git-repos").join("repos.yaml");
if let Some(parent) = cache_path.parent() {
fs::create_dir_all(parent)?;
}
let yaml = yaml_serde::to_string(&cached_repos)?;
fs::write(&cache_path, yaml)?;
Ok(())
}