1use serde::{Deserialize, Serialize};
2use std::env;
3use std::path::{Path, PathBuf};
4
5#[derive(Debug, Deserialize, Serialize, Default)]
7#[serde(default)]
8pub struct CellarConfig {
9 pub ml_cellar: MlCellarConfig,
10 pub aws: AWSConfig,
11}
12
13#[derive(Debug, Deserialize, Serialize, Default)]
15#[serde(default)]
16pub struct MlCellarConfig {
17 pub use_custom_transfer_agent: bool,
22}
23
24#[derive(Debug, Deserialize, Serialize, Default)]
26#[serde(default)]
27pub struct AWSConfig {
28 pub profile: Option<String>,
31}
32
33pub fn load_cellar_config(path: &Path) -> (CellarConfig, PathBuf) {
58 let relative_dir = if path.is_dir() {
60 path.to_path_buf()
61 } else {
62 path.parent().unwrap().to_path_buf()
63 };
64
65 let mut absolute_dir = if relative_dir.is_absolute() {
67 relative_dir
68 } else {
69 env::current_dir().unwrap().join(relative_dir)
70 };
71
72 loop {
74 let candidate = absolute_dir.join(".mlcellar.toml");
75 if candidate.is_file() {
76 log::info!("Loading config from {:?}", candidate);
78 let config_content = std::fs::read_to_string(&candidate).unwrap();
79 return (toml::from_str(&config_content).unwrap(), absolute_dir);
80 }
81
82 match absolute_dir.parent() {
83 Some(parent) => absolute_dir = parent.to_path_buf(),
84 None => {
85 log::error!(
86 ".mlcellar.toml not found; reached filesystem root at {:?}\n\
87 Please ensure that .mlcellar.toml exists in the directory tree starting from the directory of the provided path.",
88 absolute_dir
89 );
90 panic!(
91 ".mlcellar.toml not found in the directory tree starting from {:?}",
92 path
93 );
94 }
95 }
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102 use tempfile::TempDir;
103 use toml::to_string_pretty;
104
105 #[test]
106 fn test_load_cellar_config() {
107 let temp = TempDir::new().unwrap();
108 let root_directory = temp.path();
109
110 let toml_str = to_string_pretty(&CellarConfig::default())
111 .expect("failed to serialize cellar config to TOML");
112 std::fs::write(root_directory.join(".mlcellar.toml"), toml_str)
113 .expect("failed to write .mlcellar.toml");
114
115 let (config, config_dir) = load_cellar_config(root_directory);
116 assert_eq!(config_dir, root_directory);
117 assert!(!config.ml_cellar.use_custom_transfer_agent);
118 }
119}