use crate::{types::*, Result};
use figment::{
providers::{Env, Format, Serialized, Toml},
Figment,
};
use std::path::PathBuf;
pub fn build_figment(project_info: &Option<ProjectInfo>) -> Result<Figment> {
let mut figment = Figment::new();
figment = add_builtin_defaults(figment);
figment = add_global_user_config(figment);
figment = add_project_config(figment, project_info)?;
figment = add_vx_project_config(figment);
figment = add_environment_variables(figment);
Ok(figment)
}
fn add_builtin_defaults(figment: Figment) -> Figment {
figment.merge(Serialized::defaults(VxConfig::default()))
}
fn add_global_user_config(figment: Figment) -> Figment {
if let Some(config_dir) = dirs::config_dir() {
let global_config = config_dir.join("vx").join("config.toml");
if global_config.exists() {
return figment.merge(Toml::file(global_config));
}
}
figment
}
fn add_project_config(figment: Figment, project_info: &Option<ProjectInfo>) -> Result<Figment> {
if let Some(project_info) = project_info {
let project_config = create_project_config_from_info(project_info)?;
Ok(figment.merge(Serialized::defaults(project_config)))
} else {
Ok(figment)
}
}
fn add_vx_project_config(figment: Figment) -> Figment {
let vx_project_config = PathBuf::from(".vx.toml");
if vx_project_config.exists() {
if let Ok(project_config) = parse_vx_project_config(&vx_project_config) {
return figment.merge(Serialized::defaults(project_config));
}
}
figment
}
fn add_environment_variables(figment: Figment) -> Figment {
figment.merge(Env::prefixed("VX_"))
}
fn create_project_config_from_info(project_info: &ProjectInfo) -> Result<VxConfig> {
let mut config = VxConfig::default();
for (tool_name, version) in &project_info.tool_versions {
config.tools.insert(
tool_name.clone(),
ToolConfig {
version: Some(version.clone()),
install_method: None,
registry: None,
custom_sources: None,
},
);
}
Ok(config)
}
fn parse_vx_project_config(path: &PathBuf) -> Result<VxConfig> {
let content = std::fs::read_to_string(path)?;
let project_config: ProjectConfig = toml::from_str(&content)?;
let mut vx_config = VxConfig::default();
for (tool_name, version) in project_config.tools {
vx_config.tools.insert(
tool_name,
ToolConfig {
version: Some(version),
install_method: None,
registry: None,
custom_sources: None,
},
);
}
vx_config.defaults.auto_install = project_config.settings.auto_install;
Ok(vx_config)
}