feat(cli): add recursive migra config search

... in parent directories
This commit is contained in:
Dmitriy Pleshevskiy 2021-02-01 23:51:23 +03:00
parent cc6899d416
commit 942edd0f8b
3 changed files with 39 additions and 17 deletions

View File

@ -1,38 +1,60 @@
use migra_core::path::PathBuilder;
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::Path;
use std::io;
use std::path::{Path, PathBuf};
const MIGRA_TOML_FILENAME: &str = "Migra.toml";
#[derive(Debug, Serialize, Deserialize)]
pub(crate) struct Config {
pub directory: String,
#[serde(skip)]
pub root: PathBuf,
pub directory: PathBuf,
pub database: DatabaseConfig,
}
#[derive(Debug, Serialize, Deserialize)]
pub(crate) struct DatabaseConfig {
pub connection: String
pub connection: String,
}
impl Default for Config {
fn default() -> Config {
Config {
directory: String::from("database"),
root: PathBuf::new(),
directory: PathBuf::from("database"),
database: DatabaseConfig {
connection: String::new(),
}
},
}
}
}
impl Config {
pub fn read() -> Config {
fs::read_to_string(MIGRA_TOML_FILENAME)
.ok()
.and_then(|content| toml::from_str(&content).ok())
.unwrap_or_default()
pub fn read() -> io::Result<Config> {
let current_dir = std::env::current_dir()?;
let mut read_dir = Some(current_dir.as_path());
loop {
if let Some(dir) = read_dir {
let migra_file_path = PathBuilder::from(dir).append(MIGRA_TOML_FILENAME).build();
if !migra_file_path.exists() {
read_dir = dir.parent();
continue;
}
let content = fs::read_to_string(migra_file_path)?;
let mut config: Config = toml::from_str(&content).expect("Cannot parse Migra.toml");
config.root = PathBuf::from(dir);
return Ok(config);
} else {
return Err(io::Error::from(io::ErrorKind::NotFound));
}
}
}
pub fn initialize() -> Result<(), Box<dyn std::error::Error>> {

View File

@ -4,7 +4,7 @@ mod config;
mod opts;
use config::Config;
use opts::{StructOpt, AppOpt, ApplyOpt};
use opts::{AppOpt, ApplyOpt, StructOpt};
use std::fs;
fn main() -> Result<(), Box<dyn std::error::Error>> {
@ -13,13 +13,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
match opt {
AppOpt::Init => {
Config::initialize()?;
},
}
AppOpt::Apply(ApplyOpt { file_name }) => {
let config = Config::read();
let config = Config::read()?;
let mut client = migra_core::database::connect(&config.database.connection)?;
let file_path = migra_core::path::PathBuilder::new(config.directory)
let file_path = migra_core::path::PathBuilder::from(config.root)
.append(config.directory)
.append(file_name)
.default_extension("sql")
.build();

View File

@ -6,9 +6,8 @@ pub(crate) enum AppOpt {
Apply(ApplyOpt),
}
#[derive(Debug, StructOpt)]
pub(crate) struct ApplyOpt {
#[structopt(parse(from_str))]
pub file_name: String
pub file_name: String,
}