use clap::{ArgAction, Parser, Subcommand};
use dirs;
use serde::Deserialize;
use so6;
use std::env::current_dir;
use std::fs;
use std::io::{stdin, stdout, Write};
use std::path::PathBuf;
#[derive(Deserialize, Debug, Clone)]
pub struct Config {
#[serde(default = "default_workdir")]
workdir: PathBuf,
#[serde(default = "default_tasks")]
tasks: PathBuf,
}
fn default_workdir() -> PathBuf {
current_dir().unwrap()
}
fn default_tasks() -> PathBuf {
"**/so6.yml".into()
}
#[derive(Parser, Debug)]
#[clap(version)]
struct Args {
#[arg(short, long, env = "SO6_WORKDIR")]
workdir: Option<String>,
#[arg(short, long, env = "SO6_TASKS")]
tasks: Option<String>,
#[arg(short, long)]
config: Option<String>,
#[command(subcommand)]
cmd: Commands,
}
#[derive(Subcommand, Debug)]
enum Commands {
List {},
Configure {},
Execute {
migration_name: Option<String>,
},
Indexes {},
Index {
path: PathBuf,
key: String,
#[arg(long, action=ArgAction::SetTrue)]
locked: bool,
},
}
fn get_config(config: Option<String>, workdir: Option<String>, tasks: Option<String>) -> Config {
let config_path = match config {
None => dirs::config_dir().unwrap().join("so6.yml"),
Some(path_string) => PathBuf::from(path_string),
};
let mut computed_config: Config = serde_yaml::from_str(
match fs::read_to_string(config_path.to_str().unwrap()) {
Ok(content) => content,
Err(_) => String::from("{}"),
}
.as_str(),
)
.expect(format!("Couldn't deserialize {}", config_path.to_str().unwrap()).as_str());
if let Some(wd) = workdir {
computed_config.workdir = wd.into();
}
if let Some(t) = tasks {
computed_config.tasks = t.into();
}
computed_config
}
fn main() {
let args = Args::parse();
let config = get_config(args.config, args.workdir, args.tasks);
match args.cmd {
Commands::List {} => {
println!("list tasks");
}
Commands::Configure {} => {
println!("configure tasks {}", config.workdir.to_str().unwrap());
}
Commands::Execute { migration_name } => {
println!("Execute tasks {}", migration_name.unwrap());
}
Commands::Indexes {} => {
let indexes = so6::list(config.workdir, config.tasks);
for (counter, (path, name, _)) in indexes.iter().enumerate() {
println!("{} {}: {}", path.to_str().unwrap(), counter, name);
}
print!("Select the one you want to create: ");
let _ = stdout().flush();
let mut response = String::new();
stdin().read_line(&mut response).unwrap();
let id: usize = response
.as_str()
.trim()
.parse()
.expect("A number was expected!");
let (selected_index_file_path, selected_name, selected_index) = indexes[id].clone();
println!(
"You selected {selected_index_file_path:?} {selected_name}: {selected_index:?}"
);
println!("{}", selected_index.background_run());
}
Commands::Index { path, key, locked } => {
so6::create_index(path, key, locked);
}
}
}