refac: preparatory work for subsequent changes

Moved the main logic such as running a command or getting a config
into it.

Changed incoming paramenters for commands.
This commit is contained in:
Dmitriy Pleshevskiy 2021-04-08 01:26:30 +03:00
parent a49b9b4ecb
commit 07d17c9e93
10 changed files with 94 additions and 65 deletions

58
migra-cli/src/app.rs Normal file
View File

@ -0,0 +1,58 @@
use crate::commands;
use crate::error::*;
use crate::opts::Command;
use crate::AppOpt;
use crate::Config;
use std::path::PathBuf;
use structopt::StructOpt;
#[derive(Debug, Clone)]
pub(crate) struct App {
app_opt: AppOpt,
}
impl App {
pub fn new(app_opt: AppOpt) -> Self {
App { app_opt }
}
pub fn config_path(&self) -> Option<&PathBuf> {
self.app_opt.config_path.as_ref()
}
pub fn config(&self) -> MigraResult<Config> {
Config::read(self.config_path())
}
pub fn run_command(&self) -> StdResult<()> {
match self.app_opt.command.clone() {
Command::Init => {
commands::initialize_migra_manifest(self)?;
}
Command::Apply(cmd_opts) => {
commands::apply_sql(self, cmd_opts)?;
}
Command::Make(cmd_opts) => {
commands::make_migration(self, cmd_opts)?;
}
Command::List => {
commands::print_migration_lists(self)?;
}
Command::Upgrade(cmd_opts) => {
commands::upgrade_pending_migrations(self, cmd_opts)?;
}
Command::Downgrade(cmd_opts) => {
commands::rollback_applied_migrations(self, cmd_opts)?;
}
Command::Completions(cmd_opts) => {
AppOpt::clap().gen_completions_to(
env!("CARGO_BIN_NAME"),
cmd_opts.into(),
&mut std::io::stdout(),
);
}
}
Ok(())
}
}

View File

@ -1,18 +1,19 @@
use crate::config::Config;
use crate::app::App;
use crate::database::prelude::*;
use crate::database::transaction::with_transaction;
use crate::database::{DatabaseConnectionManager, MigrationManager};
use crate::opts::ApplyCommandOpt;
use crate::StdResult;
pub(crate) fn apply_sql(config: Config, opts: ApplyCommandOpt) -> StdResult<()> {
pub(crate) fn apply_sql(app: &App, cmd_opts: ApplyCommandOpt) -> StdResult<()> {
let config = app.config()?;
let mut connection_manager = DatabaseConnectionManager::connect(&config.database)?;
let conn = connection_manager.connection();
let migration_manager = MigrationManager::new();
let file_path = {
let mut file_path = config.directory_path().join(opts.file_name);
let mut file_path = config.directory_path().join(cmd_opts.file_name);
if file_path.extension().is_none() {
file_path.set_extension("sql");
}

View File

@ -1,4 +1,4 @@
use crate::config::Config;
use crate::app::App;
use crate::database::prelude::*;
use crate::database::transaction::with_transaction;
use crate::database::{DatabaseConnectionManager, MigrationManager};
@ -6,10 +6,8 @@ use crate::opts::DowngradeCommandOpt;
use crate::StdResult;
use std::cmp;
pub(crate) fn rollback_applied_migrations(
config: Config,
opts: DowngradeCommandOpt,
) -> StdResult<()> {
pub(crate) fn rollback_applied_migrations(app: &App, opts: DowngradeCommandOpt) -> StdResult<()> {
let config = app.config()?;
let mut connection_manager = DatabaseConnectionManager::connect(&config.database)?;
let conn = connection_manager.connection();
let migration_manager = MigrationManager::new();

View File

@ -1,9 +1,12 @@
use crate::app::App;
use crate::config::{Config, MIGRA_TOML_FILENAME};
use crate::StdResult;
use std::path::PathBuf;
pub(crate) fn initialize_migra_manifest(config_path: Option<PathBuf>) -> StdResult<()> {
let config_path = config_path
pub(crate) fn initialize_migra_manifest(app: &App) -> StdResult<()> {
let config_path = app
.config_path()
.cloned()
.map(|mut config_path| {
let ext = config_path.extension();
if config_path.is_dir() || ext.is_none() {

View File

@ -1,4 +1,4 @@
use crate::config::Config;
use crate::app::App;
use crate::database::migration::filter_pending_migrations;
use crate::database::prelude::*;
use crate::database::{DatabaseConnectionManager, Migration, MigrationManager};
@ -6,7 +6,8 @@ use crate::error::{Error, StdResult};
const EM_DASH: char = '—';
pub(crate) fn print_migration_lists(config: Config) -> StdResult<()> {
pub(crate) fn print_migration_lists(app: &App) -> StdResult<()> {
let config = app.config()?;
let applied_migration_names = match config.database.connection_string() {
Ok(ref database_connection_string) => {
let mut connection_manager = DatabaseConnectionManager::connect_with_string(

View File

@ -1,10 +1,11 @@
use crate::app::App;
use crate::opts::MakeCommandOpt;
use crate::Config;
use crate::StdResult;
use chrono::Local;
use std::fs;
pub(crate) fn make_migration(config: Config, opts: MakeCommandOpt) -> StdResult<()> {
pub(crate) fn make_migration(app: &App, opts: MakeCommandOpt) -> StdResult<()> {
let config = app.config()?;
let now = Local::now().format("%y%m%d%H%M%S");
let migration_name: String = opts

View File

@ -1,11 +1,12 @@
use crate::app::App;
use crate::database::migration::*;
use crate::database::transaction::with_transaction;
use crate::database::DatabaseConnectionManager;
use crate::opts::UpgradeCommandOpt;
use crate::Config;
use crate::StdResult;
pub(crate) fn upgrade_pending_migrations(config: Config, opts: UpgradeCommandOpt) -> StdResult<()> {
pub(crate) fn upgrade_pending_migrations(app: &App, opts: UpgradeCommandOpt) -> StdResult<()> {
let config = app.config()?;
let mut connection_manager = DatabaseConnectionManager::connect(&config.database)?;
let conn = connection_manager.connection();

View File

@ -134,12 +134,12 @@ fn recursive_find_project_root() -> MigraResult<PathBuf> {
}
impl Config {
pub fn read(config_path: Option<PathBuf>) -> MigraResult<Config> {
pub fn read(config_path: Option<&PathBuf>) -> MigraResult<Config> {
let config_path = match config_path {
Some(config_path) if config_path.is_dir() => {
Some(config_path.join(MIGRA_TOML_FILENAME))
}
Some(config_path) => Some(config_path),
Some(config_path) => Some(config_path.clone()),
None => recursive_find_project_root()
.map(|path| path.join(MIGRA_TOML_FILENAME))
.ok(),

View File

@ -7,6 +7,7 @@ extern crate cfg_if;
#[cfg(not(any(feature = "postgres", feature = "mysql")))]
compile_error!(r#"Either features "postgres" or "mysql" must be enabled for "migra" crate"#);
mod app;
mod commands;
mod config;
mod database;
@ -14,48 +15,13 @@ mod error;
mod opts;
use crate::error::StdResult;
use app::App;
use config::Config;
use opts::{AppOpt, Command, StructOpt};
use std::io;
use opts::{AppOpt, StructOpt};
fn main() -> StdResult<()> {
#[cfg(feature = "dotenv")]
dotenv::dotenv().ok();
let opt = AppOpt::from_args();
match opt.command {
Command::Init => {
commands::initialize_migra_manifest(opt.config)?;
}
Command::Apply(opts) => {
let config = Config::read(opt.config)?;
commands::apply_sql(config, opts)?;
}
Command::Make(opts) => {
let config = Config::read(opt.config)?;
commands::make_migration(config, opts)?;
}
Command::List => {
let config = Config::read(opt.config)?;
commands::print_migration_lists(config)?;
}
Command::Upgrade(opts) => {
let config = Config::read(opt.config)?;
commands::upgrade_pending_migrations(config, opts)?;
}
Command::Downgrade(opts) => {
let config = Config::read(opt.config)?;
commands::rollback_applied_migrations(config, opts)?;
}
Command::Completions(opts) => {
AppOpt::clap().gen_completions_to(
env!("CARGO_BIN_NAME"),
opts.into(),
&mut io::stdout(),
);
}
}
Ok(())
App::new(AppOpt::from_args()).run_command()
}

View File

@ -2,17 +2,17 @@ use std::path::PathBuf;
use structopt::clap;
pub use structopt::StructOpt;
#[derive(Debug, StructOpt)]
#[derive(Debug, StructOpt, Clone)]
#[structopt(bin_name = "migra", name = "Migra")]
pub(crate) struct AppOpt {
#[structopt(short, long)]
pub config: Option<PathBuf>,
#[structopt(name = "config", short, long)]
pub config_path: Option<PathBuf>,
#[structopt(subcommand)]
pub command: Command,
}
#[derive(Debug, StructOpt)]
#[derive(Debug, StructOpt, Clone)]
pub(crate) enum Command {
Init,
@ -32,20 +32,20 @@ pub(crate) enum Command {
Completions(CompletionsShell),
}
#[derive(Debug, StructOpt)]
#[derive(Debug, StructOpt, Clone)]
pub(crate) struct ApplyCommandOpt {
#[structopt(parse(from_str))]
pub file_name: String,
}
#[derive(Debug, StructOpt)]
#[derive(Debug, StructOpt, Clone)]
pub(crate) struct MakeCommandOpt {
/// Name of the migration to create in specify directory.
#[structopt(parse(from_str))]
pub migration_name: String,
}
#[derive(Debug, StructOpt)]
#[derive(Debug, StructOpt, Clone)]
pub(crate) struct UpgradeCommandOpt {
/// Name of the existing migration that will update the schema
/// in the database.
@ -57,7 +57,7 @@ pub(crate) struct UpgradeCommandOpt {
pub migrations_number: Option<usize>,
}
#[derive(Debug, StructOpt)]
#[derive(Debug, StructOpt, Clone)]
pub(crate) struct DowngradeCommandOpt {
/// How many applied migrations do we have to rollback.
#[structopt(long = "number", short = "n", default_value = "1")]
@ -68,7 +68,7 @@ pub(crate) struct DowngradeCommandOpt {
pub all_migrations: bool,
}
#[derive(Debug, StructOpt)]
#[derive(Debug, StructOpt, Clone)]
pub(crate) enum CompletionsShell {
Bash,
Fish,