Add --source for migration subcommands (#1769)

This commit is contained in:
Pedro de Matos Fedricci
2022-04-01 16:19:51 -03:00
committed by GitHub
parent d3093d0b70
commit c30a4a5d88
3 changed files with 207 additions and 64 deletions

View File

@@ -15,35 +15,58 @@ pub async fn run(opt: Opt) -> Result<()> {
match opt.command {
Command::Migrate(migrate) => match migrate.command {
MigrateCommand::Add {
source,
description,
reversible,
} => migrate::add(&migrate.source, &description, reversible).await?,
} => migrate::add(source.resolve(&migrate.source), &description, reversible).await?,
MigrateCommand::Run {
source,
dry_run,
ignore_missing,
database_url,
} => migrate::run(&migrate.source, &database_url, dry_run, ignore_missing).await?,
MigrateCommand::Revert {
dry_run,
ignore_missing,
database_url,
} => migrate::revert(&migrate.source, &database_url, dry_run, ignore_missing).await?,
MigrateCommand::Info { database_url } => {
migrate::info(&migrate.source, &database_url).await?
} => {
migrate::run(
source.resolve(&migrate.source),
&database_url,
dry_run,
*ignore_missing,
)
.await?
}
MigrateCommand::Revert {
source,
dry_run,
ignore_missing,
database_url,
} => {
migrate::revert(
source.resolve(&migrate.source),
&database_url,
dry_run,
*ignore_missing,
)
.await?
}
MigrateCommand::Info {
source,
database_url,
} => migrate::info(source.resolve(&migrate.source), &database_url).await?,
MigrateCommand::BuildScript { source, force } => {
migrate::build_script(source.resolve(&migrate.source), force)?
}
MigrateCommand::BuildScript { force } => migrate::build_script(&migrate.source, force)?,
},
Command::Database(database) => match database.command {
DatabaseCommand::Create { database_url } => database::create(&database_url).await?,
DatabaseCommand::Drop { yes, database_url } => {
database::drop(&database_url, !yes).await?
}
DatabaseCommand::Drop {
confirmation,
database_url,
} => database::drop(&database_url, !confirmation).await?,
DatabaseCommand::Reset {
yes,
confirmation,
source,
database_url,
} => database::reset(&source, &database_url, !yes).await?,
} => database::reset(&source, &database_url, !confirmation).await?,
DatabaseCommand::Setup {
source,
database_url,

View File

@@ -1,4 +1,6 @@
use clap::Parser;
use std::ops::{Deref, Not};
use clap::{Args, Parser};
#[derive(Parser, Debug)]
#[clap(version, about, author)]
@@ -35,9 +37,8 @@ pub enum Command {
#[clap(last = true)]
args: Vec<String>,
/// Location of the DB, by default will be read from the DATABASE_URL env var
#[clap(long, short = 'D', env)]
database_url: String,
#[clap(flatten)]
database_url: DatabaseUrl,
},
#[clap(alias = "mig")]
@@ -55,48 +56,38 @@ pub struct DatabaseOpt {
pub enum DatabaseCommand {
/// Creates the database specified in your DATABASE_URL.
Create {
/// Location of the DB, by default will be read from the DATABASE_URL env var
#[clap(long, short = 'D', env)]
database_url: String,
#[clap(flatten)]
database_url: DatabaseUrl,
},
/// Drops the database specified in your DATABASE_URL.
Drop {
/// Automatic confirmation. Without this option, you will be prompted before dropping
/// your database.
#[clap(short)]
yes: bool,
#[clap(flatten)]
confirmation: Confirmation,
/// Location of the DB, by default will be read from the DATABASE_URL env var
#[clap(long, short = 'D', env)]
database_url: String,
#[clap(flatten)]
database_url: DatabaseUrl,
},
/// Drops the database specified in your DATABASE_URL, re-creates it, and runs any pending migrations.
Reset {
/// Automatic confirmation. Without this option, you will be prompted before dropping
/// your database.
#[clap(short)]
yes: bool,
#[clap(flatten)]
confirmation: Confirmation,
/// Path to folder containing migrations.
#[clap(long, default_value = "migrations")]
source: String,
#[clap(flatten)]
source: Source,
/// Location of the DB, by default will be read from the DATABASE_URL env var
#[clap(long, short = 'D', env)]
database_url: String,
#[clap(flatten)]
database_url: DatabaseUrl,
},
/// Creates the database specified in your DATABASE_URL and runs any pending migrations.
Setup {
/// Path to folder containing migrations.
#[clap(long, default_value = "migrations")]
source: String,
#[clap(flatten)]
source: Source,
/// Location of the DB, by default will be read from the DATABASE_URL env var
#[clap(long, short = 'D', env)]
database_url: String,
#[clap(flatten)]
database_url: DatabaseUrl,
},
}
@@ -104,6 +95,7 @@ pub enum DatabaseCommand {
#[derive(Parser, Debug)]
pub struct MigrateOpt {
/// Path to folder containing migrations.
/// Warning: deprecated, use <SUBCOMMAND> --source <SOURCE>
#[clap(long, default_value = "migrations")]
pub source: String,
@@ -118,6 +110,9 @@ pub enum MigrateCommand {
Add {
description: String,
#[clap(flatten)]
source: SourceOverride,
/// If true, creates a pair of up and down migration files with same version
/// else creates a single sql file
#[clap(short)]
@@ -126,47 +121,156 @@ pub enum MigrateCommand {
/// Run all pending migrations.
Run {
#[clap(flatten)]
source: SourceOverride,
/// List all the migrations to be run without applying
#[clap(long)]
dry_run: bool,
/// Ignore applied migrations that missing in the resolved migrations
#[clap(long)]
ignore_missing: bool,
#[clap(flatten)]
ignore_missing: IgnoreMissing,
/// Location of the DB, by default will be read from the DATABASE_URL env var
#[clap(long, short = 'D', env)]
database_url: String,
#[clap(flatten)]
database_url: DatabaseUrl,
},
/// Revert the latest migration with a down file.
Revert {
#[clap(flatten)]
source: SourceOverride,
/// List the migration to be reverted without applying
#[clap(long)]
dry_run: bool,
/// Ignore applied migrations that missing in the resolved migrations
#[clap(long)]
ignore_missing: bool,
#[clap(flatten)]
ignore_missing: IgnoreMissing,
/// Location of the DB, by default will be read from the DATABASE_URL env var
#[clap(long, short = 'D', env)]
database_url: String,
#[clap(flatten)]
database_url: DatabaseUrl,
},
/// List all available migrations.
Info {
/// Location of the DB, by default will be read from the DATABASE_URL env var
#[clap(long, env)]
database_url: String,
#[clap(flatten)]
source: SourceOverride,
#[clap(flatten)]
database_url: DatabaseUrl,
},
/// Generate a `build.rs` to trigger recompilation when a new migration is added.
///
/// Must be run in a Cargo project root.
BuildScript {
#[clap(flatten)]
source: SourceOverride,
/// Overwrite the build script if it already exists.
#[clap(long)]
force: bool,
},
}
/// Argument for the migration scripts source.
#[derive(Args, Debug)]
pub struct Source {
/// Path to folder containing migrations.
#[clap(long, default_value = "migrations")]
source: String,
}
impl Deref for Source {
type Target = String;
fn deref(&self) -> &Self::Target {
&self.source
}
}
/// Argument for overriding migration scripts source.
// Note: once `MigrateOpt.source` is removed, usage can be replaced with `Source`.
#[derive(Args, Debug)]
pub struct SourceOverride {
/// Path to folder containing migrations [default: migrations]
#[clap(long)]
source: Option<String>,
}
impl SourceOverride {
/// Override command's `source` flag value with subcommand's
/// `source` flag value when provided.
#[inline]
pub(super) fn resolve<'a>(&'a self, source: &'a str) -> &'a str {
match self.source {
Some(ref source) => source,
None => source,
}
}
}
/// Argument for the database URL.
#[derive(Args, Debug)]
pub struct DatabaseUrl {
/// Location of the DB, by default will be read from the DATABASE_URL env var
#[clap(long, short = 'D', env)]
database_url: String,
}
impl Deref for DatabaseUrl {
type Target = String;
fn deref(&self) -> &Self::Target {
&self.database_url
}
}
/// Argument for automatic confirmantion.
#[derive(Args, Copy, Clone, Debug)]
pub struct Confirmation {
/// Automatic confirmation. Without this option, you will be prompted before dropping
/// your database.
#[clap(short)]
yes: bool,
}
impl Deref for Confirmation {
type Target = bool;
fn deref(&self) -> &Self::Target {
&self.yes
}
}
impl Not for Confirmation {
type Output = bool;
fn not(self) -> Self::Output {
!self.yes
}
}
/// Argument for ignoring applied migrations that were not resolved.
#[derive(Args, Copy, Clone, Debug)]
pub struct IgnoreMissing {
/// Ignore applied migrations that are missing in the resolved migrations
#[clap(long)]
ignore_missing: bool,
}
impl Deref for IgnoreMissing {
type Target = bool;
fn deref(&self) -> &Self::Target {
&self.ignore_missing
}
}
impl Not for IgnoreMissing {
type Output = bool;
fn not(self) -> Self::Output {
!self.ignore_missing
}
}