use anyhow::Context;
use cargo_util::paths;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use tracing::{debug, warn};
use crate::paths::PathExt;
use crate::CIResult;
#[derive(Serialize, Deserialize, Default, Debug)]
pub struct Config {
pub library_path: PathBuf,
pub library_debug_path: PathBuf,
pub library_args: Vec<String>,
pub llvm_version: String,
pub checksum: String,
pub url: String,
}
impl Config {
pub fn load() -> CIResult<Self> {
let default = Self::default();
let mut path = Config::dir()?;
path.push("default.cfg");
let file = match paths::read(&path) {
Ok(file) => file,
Err(error) => {
Self::save(&default).context("failed to save default config")?;
warn!("config file not found, use default config");
debug!(?error);
return Ok(default);
}
};
match toml::from_str(&file) {
Ok(config) => Ok(config),
Err(error) => {
let old_path = path.append_suffix("old")?;
paths::copy(&path, &old_path).context("failed to backup the old config")?;
Self::save(&default)?;
warn!("found incompatible config file, replaced with default config");
warn!("old config file can be found at: {}", old_path.display());
debug!(?error);
Self::load()
}
}
}
pub fn save(config: &Self) -> CIResult<()> {
let mut path = Config::dir()?;
path.push("default.cfg");
let s = toml::to_string_pretty(config).context("failed to parse the config")?;
paths::write(path, s).context("failed to save the config")
}
pub fn dir() -> CIResult<PathBuf> {
let mut path = dirs::config_dir().context("failed to get the config directory")?;
path.push("cargo-compiler-interrupts");
paths::create_dir_all(&path)?;
Ok(path)
}
}