use anyhow::{Result, bail};
use crate::{cargo, naming, project};
#[derive(Debug, Clone, Copy)]
pub enum Action<'a> {
Generate { name: &'a str },
Apply,
Reset,
}
impl Action<'_> {
fn args(self) -> Vec<&'static str> {
match self {
Self::Generate { .. } => vec!["migration", "generate", "--name"],
Self::Apply => vec!["migration", "apply"],
Self::Reset => vec!["migration", "reset"],
}
}
fn command_name(self) -> &'static str {
match self {
Self::Generate { .. } => "slave make:migration",
Self::Apply => "slave migrate",
Self::Reset => "slave migrate:fresh",
}
}
}
pub fn run(action: Action) -> Result<()> {
if let Action::Generate { name } = action {
naming::validate_migration_name(name)?;
}
let root = project::find_root()?;
if !root.join("src/bin/migrate.rs").is_file() || !root.join("Toasty.toml").is_file() {
bail!(
"src/bin/migrate.rs or Toasty.toml not found; migrations need the layout created by `slave new`"
);
}
let mut args = vec!["run", "--quiet", "--bin", "migrate", "--"];
args.extend(action.args());
if let Action::Generate { name } = action {
args.push(name);
}
let status = cargo::run(&root, &args, &[])?;
if !status.success() {
bail!("`{}` did not complete successfully", action.command_name());
}
Ok(())
}