use std::{
fs::{create_dir_all, read_to_string, File},
io::Write,
path::PathBuf,
};
use home::home_dir;
use serde::{Deserialize, Serialize};
use crate::{
cli::GitMoverCli, codeberg::config::CodebergConfig, errors::GitMoverError,
github::config::GithubConfig, gitlab::config::GitlabConfig,
};
#[derive(Deserialize, Default, Clone, Debug)]
pub struct GitMoverConfig {
pub config_path: PathBuf,
pub config_data: ConfigData,
pub cli_args: GitMoverCli,
}
#[derive(Deserialize, Serialize, Default, Clone, Debug)]
pub struct ConfigData {
pub gitlab: Option<GitlabConfig>,
pub github: Option<GithubConfig>,
pub codeberg: Option<CodebergConfig>,
}
impl GitMoverConfig {
pub fn try_new(cli_args: GitMoverCli) -> Result<Self, GitMoverError> {
let config_path = match cli_args.config.clone() {
Some(p) => p,
None => Self::get_config_path()?,
};
let contents = read_to_string(config_path.clone())
.map_err(|e| GitMoverError::new_with_source("Unable to open", e))?;
let config_data = toml::from_str(&contents)?;
Ok(GitMoverConfig {
config_path,
config_data,
cli_args,
})
}
pub fn save(&self) -> Result<(), GitMoverError> {
let config_str = toml::to_string(&self.config_data)
.map_err(|e| GitMoverError::new_with_source("Unable to serialize config", e))?;
let mut file = File::create(&self.config_path)
.map_err(|e| GitMoverError::new_with_source("Unable to create config file", e))?;
file.write_all(config_str.as_bytes())
.map_err(|e| GitMoverError::new_with_source("Unable to write to config file", e))
}
pub fn get_config_path() -> Result<PathBuf, GitMoverError> {
let home_dir = match home_dir() {
Some(path) if !path.as_os_str().is_empty() => path,
_ => return Err("Unable to get your home dir! home::home_dir() isn't working".into()),
};
let config_directory = home_dir.join(".config").join(".git-mover");
let config_path = config_directory.join("config.toml");
create_dir_all(config_directory)
.map_err(|e| GitMoverError::new_with_source("Unable to create config dir", e))?;
if !config_path.exists() {
let mut file = File::create(&config_path)
.map_err(|e| GitMoverError::new_with_source("Unable to create config file", e))?;
file.write_all(b"")
.map_err(|e| GitMoverError::new_with_source("Unable to write to config file", e))?;
}
Ok(config_path)
}
pub fn update(
&mut self,
updater_fn: impl FnOnce(&mut ConfigData),
) -> Result<(), GitMoverError> {
updater_fn(&mut self.config_data);
self.save()?;
Ok(())
}
}