feature/api-setup #4
3
.gitignore
vendored
3
.gitignore
vendored
@@ -23,4 +23,7 @@ target
|
||||
#.idea/
|
||||
|
||||
# generated environment variables file
|
||||
.env
|
||||
.env.generated
|
||||
|
||||
generated-config.yaml
|
||||
|
||||
@@ -15,3 +15,4 @@ tokio = { version = "1.47.0", features = ["full"] }
|
||||
url = "2.5.7"
|
||||
clap = { version = "4.5.48", features = ["derive", "env"] }
|
||||
path-clean = "1.0.1"
|
||||
serde_json = "1.0.145"
|
||||
|
||||
@@ -13,24 +13,151 @@ pub struct EnvFile {
|
||||
pub file_type: EnvFileType,
|
||||
pub db_type: DBType,
|
||||
pub db_url: String,
|
||||
//
|
||||
buffer: serde_json::Value,
|
||||
}
|
||||
|
||||
impl EnvFile {
|
||||
pub fn write(self, path: impl AsRef<std::path::Path>) {
|
||||
let path_ref = path.as_ref();
|
||||
println!("Config file path: {}", path_ref.display());
|
||||
let mut config_file =
|
||||
std::fs::File::create(path_ref).expect("Failed to create config file");
|
||||
//
|
||||
self._write_line(&mut config_file, "DB_TYPE", &self.db_type.to_string());
|
||||
self._write_line(&mut config_file, "DATABASE_URL", &self.db_url.to_string())
|
||||
pub fn new(file_type: EnvFileType, db_type: DBType, db_url: String) -> Self {
|
||||
let mut env_file = EnvFile {
|
||||
file_type,
|
||||
db_type,
|
||||
db_url,
|
||||
buffer: serde_json::Value::Object(serde_json::Map::new()),
|
||||
};
|
||||
|
||||
env_file._write_line_buffer("DATABASE__TYPE", &env_file.db_type.to_string());
|
||||
env_file._write_line_buffer("DATABASE__URL", &env_file.db_url.to_string());
|
||||
|
||||
env_file
|
||||
}
|
||||
|
||||
fn _write_line(&self, file: &mut std::fs::File, key: &str, value: &str) {
|
||||
pub fn write(&mut self, stream: &mut dyn Write, with_prefix: bool) {
|
||||
self._write_buffer(stream, with_prefix);
|
||||
}
|
||||
|
||||
fn key_into_buffer_key(&self, key: &str) -> Vec<String> {
|
||||
key.split("__").map(String::from).collect()
|
||||
}
|
||||
|
||||
fn _write_line_buffer(&mut self, key: &str, value: &str) {
|
||||
let buffer_key = self.key_into_buffer_key(key);
|
||||
let mut current = &mut self.buffer;
|
||||
for k in &buffer_key[0..(buffer_key.len() - 1)] {
|
||||
if current.get(k).is_none() {
|
||||
current[k] = serde_json::Value::Object(serde_json::Map::new());
|
||||
}
|
||||
current = &mut current[k];
|
||||
}
|
||||
current[buffer_key.last().unwrap()] = serde_json::Value::String(value.to_string());
|
||||
}
|
||||
|
||||
fn _write_buffer(&self, file: &mut dyn Write, with_prefix: bool) {
|
||||
match self.file_type {
|
||||
EnvFileType::DotEnv => writeln!(file, "{}={}", key, value),
|
||||
EnvFileType::Yaml => writeln!(file, "{}: \"{}\"", key, value),
|
||||
}
|
||||
.expect("Failed to write to config file");
|
||||
EnvFileType::DotEnv => self._write_buffer_env(file, with_prefix),
|
||||
EnvFileType::Yaml => self._write_buffer_yaml(file),
|
||||
}
|
||||
}
|
||||
|
||||
fn _write_buffer_env(&self, file: &mut dyn Write, with_prefix: bool) {
|
||||
fn _write_buffer_env_layer(
|
||||
file: &mut dyn Write,
|
||||
buffer: &serde_json::Value,
|
||||
prefix: String,
|
||||
with_root_prefix: bool,
|
||||
) {
|
||||
if let serde_json::Value::Object(map) = buffer {
|
||||
for (key, value) in map {
|
||||
let current_key = if prefix.is_empty() {
|
||||
if with_root_prefix {
|
||||
format!("YANPM__{}", key)
|
||||
} else {
|
||||
key.to_string()
|
||||
}
|
||||
} else {
|
||||
format!("{}__{}", prefix, key)
|
||||
};
|
||||
match value {
|
||||
serde_json::Value::Object(_) => {
|
||||
_write_buffer_env_layer(file, value, current_key, with_root_prefix);
|
||||
}
|
||||
_ => {
|
||||
writeln!(file, "{}={}", current_key, value).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_write_buffer_env_layer(file, &self.buffer, String::new(), with_prefix);
|
||||
}
|
||||
|
||||
fn _write_buffer_yaml(&self, file: &mut dyn Write) {
|
||||
let mut layer = 0;
|
||||
fn _write_buffer_yaml_layer(
|
||||
file: &mut dyn Write,
|
||||
buffer: &serde_json::Value,
|
||||
layer: &mut usize,
|
||||
) {
|
||||
if let serde_json::Value::Object(map) = buffer {
|
||||
for (key, value) in map {
|
||||
let indent = " ".repeat(*layer);
|
||||
match value {
|
||||
serde_json::Value::Object(_) => {
|
||||
writeln!(file, "{}{}:", indent, key).unwrap();
|
||||
*layer += 1;
|
||||
_write_buffer_yaml_layer(file, value, layer);
|
||||
*layer -= 1;
|
||||
}
|
||||
_ => {
|
||||
writeln!(file, "{}{}: {}", indent, key, value).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_write_buffer_yaml_layer(file, &self.buffer, &mut layer);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_env_file_write_yaml() {
|
||||
let mut env_file_nested = EnvFile::new(
|
||||
EnvFileType::Yaml,
|
||||
DBType::SQLite,
|
||||
"mysql://user:pass@localhost/db".to_string(),
|
||||
);
|
||||
|
||||
let mut output_stream = Vec::new();
|
||||
env_file_nested.write(&mut output_stream, false);
|
||||
let output_string = String::from_utf8(output_stream).unwrap();
|
||||
let expected_output = "\
|
||||
DATABASE:
|
||||
TYPE: \"SQLite\"
|
||||
URL: \"mysql://user:pass@localhost/db\"
|
||||
";
|
||||
assert_eq!(output_string, expected_output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_env_file_write_env() {
|
||||
let mut env_file_nested = EnvFile::new(
|
||||
EnvFileType::DotEnv,
|
||||
DBType::PostgreSQL,
|
||||
"postgres://user:pass@localhost/db".to_string(),
|
||||
);
|
||||
let mut output_stream = Vec::new();
|
||||
env_file_nested.write(&mut output_stream, true);
|
||||
let output_string = String::from_utf8(output_stream).unwrap();
|
||||
let expected_output = "\
|
||||
YANPM__DATABASE__TYPE=\"PostgreSQL\"
|
||||
YANPM__DATABASE__URL=\"postgres://user:pass@localhost/db\"
|
||||
";
|
||||
assert_eq!(output_string, expected_output);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,17 +29,18 @@ pub fn write_env_files(db_config: &DBConfigInfoType) {
|
||||
DBConfigInfoType::PreExisting(config) => (config.db_type.clone(), config.url.clone()),
|
||||
};
|
||||
|
||||
let api_env_file = EnvFile {
|
||||
file_type: env::EnvFileType::Yaml,
|
||||
db_type,
|
||||
db_url,
|
||||
};
|
||||
let mut api_env = EnvFile::new(env::EnvFileType::Yaml, db_type, db_url);
|
||||
let mut db_env = api_env.clone();
|
||||
db_env.file_type = env::EnvFileType::DotEnv;
|
||||
|
||||
let mut db_env_file = api_env_file.clone();
|
||||
db_env_file.file_type = env::EnvFileType::DotEnv;
|
||||
let mut api_file =
|
||||
std::fs::File::create(&api_config_path_absolute).expect("Failed to create API config file");
|
||||
|
||||
api_env_file.write(&api_config_path_absolute);
|
||||
db_env_file.write(&db_config_path_absolute);
|
||||
let mut db_file =
|
||||
std::fs::File::create(&db_config_path_absolute).expect("Failed to create DB config file");
|
||||
|
||||
api_env.write(&mut api_file, true);
|
||||
db_env.write(&mut db_file, false);
|
||||
}
|
||||
|
||||
pub async fn stop_container(
|
||||
|
||||
Reference in New Issue
Block a user