From 51c8b302272e70b5906b0fa5aa91096c7a0f94db Mon Sep 17 00:00:00 2001 From: Thanh Van Date: Tue, 10 May 2022 10:28:47 +0700 Subject: [PATCH] sea-orm-cli: bump clap to 3.1.17 --- sea-orm-cli/Cargo.toml | 2 +- sea-orm-cli/src/bin/main.rs | 13 +- sea-orm-cli/src/bin/sea.rs | 13 +- sea-orm-cli/src/cli.rs | 64 +++-- sea-orm-cli/src/commands.rs | 521 +++++++++++++++++------------------ sea-orm-cli/src/migration.rs | 43 ++- 6 files changed, 326 insertions(+), 330 deletions(-) diff --git a/sea-orm-cli/Cargo.toml b/sea-orm-cli/Cargo.toml index 26615dba00..8cdcade0ff 100644 --- a/sea-orm-cli/Cargo.toml +++ b/sea-orm-cli/Cargo.toml @@ -29,7 +29,7 @@ path = "src/bin/sea.rs" required-features = ["codegen"] [dependencies] -clap = { version = "^2.33.3" } +clap = { version = "^3.1.17", features = ["env"] } dotenv = { version = "^0.15" } async-std = { version = "^1.9", features = [ "attributes", "tokio1" ] } sea-orm-codegen = { version = "^0.8.0", path = "../sea-orm-codegen", optional = true } diff --git a/sea-orm-cli/src/bin/main.rs b/sea-orm-cli/src/bin/main.rs index 6861ffd76e..8941a92f38 100644 --- a/sea-orm-cli/src/bin/main.rs +++ b/sea-orm-cli/src/bin/main.rs @@ -8,10 +8,13 @@ async fn main() { let matches = cli::build_cli().get_matches(); match matches.subcommand() { - ("generate", Some(matches)) => run_generate_command(matches) - .await - .unwrap_or_else(handle_error), - ("migrate", Some(matches)) => run_migrate_command(matches).unwrap_or_else(handle_error), - _ => unreachable!("You should never see this message"), + Some((subcommand, matches)) => match subcommand { + "generate" => run_generate_command(matches) + .await + .unwrap_or_else(handle_error), + "migrate" => run_migrate_command(matches).unwrap_or_else(handle_error), + _ => unreachable!("You should never see this message"), + }, + None => unreachable!("You should never see this message"), } } diff --git a/sea-orm-cli/src/bin/sea.rs b/sea-orm-cli/src/bin/sea.rs index fac8eb2b73..a57bbf6be3 100644 --- a/sea-orm-cli/src/bin/sea.rs +++ b/sea-orm-cli/src/bin/sea.rs @@ -10,10 +10,13 @@ async fn main() { let matches = cli::build_cli().get_matches(); match matches.subcommand() { - ("generate", Some(matches)) => run_generate_command(matches) - .await - .unwrap_or_else(handle_error), - ("migrate", Some(matches)) => run_migrate_command(matches).unwrap_or_else(handle_error), - _ => unreachable!("You should never see this message"), + Some((subcommand, matches)) => match subcommand { + "generate" => run_generate_command(matches) + .await + .unwrap_or_else(handle_error), + "migrate" => run_migrate_command(matches).unwrap_or_else(handle_error), + _ => unreachable!("You should never see this message"), + }, + None => unreachable!("You should never see this message"), } } diff --git a/sea-orm-cli/src/cli.rs b/sea-orm-cli/src/cli.rs index 1a0ebfe68c..57b05fdcab 100644 --- a/sea-orm-cli/src/cli.rs +++ b/sea-orm-cli/src/cli.rs @@ -1,26 +1,25 @@ use crate::migration::get_subcommands; -use clap::{App, AppSettings, Arg, SubCommand}; +use clap::{Arg, Command}; -pub fn build_cli() -> App<'static, 'static> { - let entity_subcommand = SubCommand::with_name("generate") +pub fn build_cli() -> Command<'static> { + let entity_subcommand = Command::new("generate") .about("Codegen related commands") - .setting(AppSettings::VersionlessSubcommands) .subcommand( - SubCommand::with_name("entity") + Command::new("entity") .about("Generate entity") .arg( - Arg::with_name("DATABASE_URL") + Arg::new("DATABASE_URL") .long("database-url") - .short("u") + .short('u') .help("Database URL") .takes_value(true) .required(true) .env("DATABASE_URL"), ) .arg( - Arg::with_name("DATABASE_SCHEMA") + Arg::new("DATABASE_SCHEMA") .long("database-schema") - .short("s") + .short('s') .help("Database schema") .long_help("Database schema\n \ - For MySQL, this argument is ignored.\n \ @@ -29,78 +28,77 @@ pub fn build_cli() -> App<'static, 'static> { .env("DATABASE_SCHEMA"), ) .arg( - Arg::with_name("OUTPUT_DIR") + Arg::new("OUTPUT_DIR") .long("output-dir") - .short("o") + .short('o') .help("Entity file output directory") .takes_value(true) .default_value("./"), ) .arg( - Arg::with_name("INCLUDE_HIDDEN_TABLES") + Arg::new("INCLUDE_HIDDEN_TABLES") .long("include-hidden-tables") .help("Generate entity file for hidden tables (i.e. table name starts with an underscore)") .takes_value(false), ) .arg( - Arg::with_name("TABLES") + Arg::new("TABLES") .long("tables") - .short("t") - .use_delimiter(true) + .short('t') + .use_value_delimiter(true) .help("Generate entity file for specified tables only (comma seperated)") .takes_value(true) .conflicts_with("INCLUDE_HIDDEN_TABLES"), ) .arg( - Arg::with_name("EXPANDED_FORMAT") + Arg::new("EXPANDED_FORMAT") .long("expanded-format") .help("Generate entity file of expanded format") .takes_value(false) .conflicts_with("COMPACT_FORMAT"), ) .arg( - Arg::with_name("COMPACT_FORMAT") + Arg::new("COMPACT_FORMAT") .long("compact-format") .help("Generate entity file of compact format") .takes_value(false) .conflicts_with("EXPANDED_FORMAT"), ) .arg( - Arg::with_name("WITH_SERDE") + Arg::new("WITH_SERDE") .long("with-serde") .help("Automatically derive serde Serialize / Deserialize traits for the entity (none, serialize, deserialize, both)") .takes_value(true) .default_value("none") ) .arg( - Arg::with_name("MAX_CONNECTIONS") + Arg::new("MAX_CONNECTIONS") .long("max-connections") .help("The maximum amount of connections to use when connecting to the database.") .takes_value(true) .default_value("1") ), - ) - .setting(AppSettings::SubcommandRequiredElseHelp); + ).subcommand_required(true).arg_required_else_help(true); - let arg_migration_dir = Arg::with_name("MIGRATION_DIR") + let arg_migration_dir = Arg::new("MIGRATION_DIR") .long("migration-dir") - .short("d") + .short('d') .help("Migration script directory") .takes_value(true) .default_value("./migration"); - let mut migrate_subcommands = SubCommand::with_name("migrate") + let mut migrate_subcommands = Command::new("migrate") .about("Migration related commands") .subcommand( - SubCommand::with_name("init") + Command::new("init") .about("Initialize migration directory") .arg(arg_migration_dir.clone()), ) .subcommand( - SubCommand::with_name("generate") + Command::new("generate") .about("Generate a new, empty migration") .arg( - Arg::with_name("MIGRATION_NAME") - .help("Name of the new migation") + Arg::new("MIGRATION_NAME") + .help("Name of the new migration") .required(true) .takes_value(true), ) @@ -112,18 +110,18 @@ pub fn build_cli() -> App<'static, 'static> { migrate_subcommands.subcommand(subcommand.arg(arg_migration_dir.clone())); } - App::new("sea-orm-cli") + Command::new("sea-orm-cli") .version(env!("CARGO_PKG_VERSION")) - .setting(AppSettings::VersionlessSubcommands) .subcommand(entity_subcommand) .subcommand(migrate_subcommands) .arg( - Arg::with_name("VERBOSE") + Arg::new("VERBOSE") .long("verbose") - .short("v") + .short('v') .help("Show debug messages") .takes_value(false) .global(true), ) - .setting(AppSettings::SubcommandRequiredElseHelp) + .subcommand_required(true) + .arg_required_else_help(true) } diff --git a/sea-orm-cli/src/commands.rs b/sea-orm-cli/src/commands.rs index bf2b745afb..db49c56d83 100644 --- a/sea-orm-cli/src/commands.rs +++ b/sea-orm-cli/src/commands.rs @@ -5,175 +5,178 @@ use sea_orm_codegen::{EntityTransformer, OutputFile, WithSerde}; use std::{error::Error, fmt::Display, fs, io::Write, path::Path, process::Command, str::FromStr}; use url::Url; -pub async fn run_generate_command(matches: &ArgMatches<'_>) -> Result<(), Box> { +pub async fn run_generate_command(matches: &ArgMatches) -> Result<(), Box> { match matches.subcommand() { - ("entity", Some(args)) => { - let output_dir = args.value_of("OUTPUT_DIR").unwrap(); - let include_hidden_tables = args.is_present("INCLUDE_HIDDEN_TABLES"); - let tables = args - .values_of("TABLES") - .unwrap_or_default() - .collect::>(); - let expanded_format = args.is_present("EXPANDED_FORMAT"); - let with_serde = args.value_of("WITH_SERDE").unwrap(); - if args.is_present("VERBOSE") { - let _ = tracing_subscriber::fmt() - .with_max_level(tracing::Level::DEBUG) - .with_test_writer() - .try_init(); - } - - let max_connections = args - .value_of("MAX_CONNECTIONS") - .map(str::parse::) - .transpose()? - .unwrap(); - - // The database should be a valid URL that can be parsed - // protocol://username:password@host/database_name - let url = Url::parse( - args.value_of("DATABASE_URL") - .expect("No database url could be found"), - )?; - - // Make sure we have all the required url components - // - // Missing scheme will have been caught by the Url::parse() call - // above - let url_username = url.username(); - let url_host = url.host_str(); - - let is_sqlite = url.scheme() == "sqlite"; - - // Skip checking if it's SQLite - if !is_sqlite { - // Panic on any that are missing - if url_username.is_empty() { - panic!("No username was found in the database url"); - } - if url_host.is_none() { - panic!("No host was found in the database url"); + Some((name, args)) => match name { + "entity" => { + let output_dir = args.value_of("OUTPUT_DIR").unwrap(); + let include_hidden_tables = args.is_present("INCLUDE_HIDDEN_TABLES"); + let tables = args + .values_of("TABLES") + .unwrap_or_default() + .collect::>(); + let expanded_format = args.is_present("EXPANDED_FORMAT"); + let with_serde = args.value_of("WITH_SERDE").unwrap(); + if args.is_present("VERBOSE") { + let _ = tracing_subscriber::fmt() + .with_max_level(tracing::Level::DEBUG) + .with_test_writer() + .try_init(); } - } - // Closures for filtering tables - let filter_tables = |table: &str| -> bool { - if !tables.is_empty() { - return tables.contains(&table); - } + let max_connections = args + .value_of("MAX_CONNECTIONS") + .map(str::parse::) + .transpose()? + .unwrap(); - true - }; - let filter_hidden_tables = |table: &str| -> bool { - if include_hidden_tables { - true - } else { - !table.starts_with('_') - } - }; + // The database should be a valid URL that can be parsed + // protocol://username:password@host/database_name + let url = Url::parse( + args.value_of("DATABASE_URL") + .expect("No database url could be found"), + )?; - let database_name = if !is_sqlite { - // The database name should be the first element of the path string + // Make sure we have all the required url components // - // Throwing an error if there is no database name since it might be - // accepted by the database without it, while we're looking to dump - // information from a particular database - let database_name = url - .path_segments() - .unwrap_or_else(|| { + // Missing scheme will have been caught by the Url::parse() call + // above + let url_username = url.username(); + let url_host = url.host_str(); + + let is_sqlite = url.scheme() == "sqlite"; + + // Skip checking if it's SQLite + if !is_sqlite { + // Panic on any that are missing + if url_username.is_empty() { + panic!("No username was found in the database url"); + } + if url_host.is_none() { + panic!("No host was found in the database url"); + } + } + + // Closures for filtering tables + let filter_tables = |table: &str| -> bool { + if !tables.is_empty() { + return tables.contains(&table); + } + + true + }; + let filter_hidden_tables = |table: &str| -> bool { + if include_hidden_tables { + true + } else { + !table.starts_with('_') + } + }; + + let database_name = if !is_sqlite { + // The database name should be the first element of the path string + // + // Throwing an error if there is no database name since it might be + // accepted by the database without it, while we're looking to dump + // information from a particular database + let database_name = url + .path_segments() + .unwrap_or_else(|| { + panic!( + "There is no database name as part of the url path: {}", + url.as_str() + ) + }) + .next() + .unwrap(); + + // An empty string as the database name is also an error + if database_name.is_empty() { panic!( "There is no database name as part of the url path: {}", url.as_str() - ) - }) - .next() - .unwrap(); + ); + } - // An empty string as the database name is also an error - if database_name.is_empty() { - panic!( - "There is no database name as part of the url path: {}", - url.as_str() - ); + database_name + } else { + Default::default() + }; + + let table_stmts = match url.scheme() { + "mysql" => { + use sea_schema::mysql::discovery::SchemaDiscovery; + use sqlx::MySql; + + let connection = connect::(max_connections, url.as_str()).await?; + let schema_discovery = SchemaDiscovery::new(connection, database_name); + let schema = schema_discovery.discover().await; + schema + .tables + .into_iter() + .filter(|schema| filter_tables(&schema.info.name)) + .filter(|schema| filter_hidden_tables(&schema.info.name)) + .map(|schema| schema.write()) + .collect() + } + "sqlite" => { + use sea_schema::sqlite::discovery::SchemaDiscovery; + use sqlx::Sqlite; + + let connection = connect::(max_connections, url.as_str()).await?; + let schema_discovery = SchemaDiscovery::new(connection); + let schema = schema_discovery.discover().await?; + schema + .tables + .into_iter() + .filter(|schema| filter_tables(&schema.name)) + .filter(|schema| filter_hidden_tables(&schema.name)) + .map(|schema| schema.write()) + .collect() + } + "postgres" | "postgresql" => { + use sea_schema::postgres::discovery::SchemaDiscovery; + use sqlx::Postgres; + + let schema = args.value_of("DATABASE_SCHEMA").unwrap_or("public"); + let connection = connect::(max_connections, url.as_str()).await?; + let schema_discovery = SchemaDiscovery::new(connection, schema); + let schema = schema_discovery.discover().await; + schema + .tables + .into_iter() + .filter(|schema| filter_tables(&schema.info.name)) + .filter(|schema| filter_hidden_tables(&schema.info.name)) + .map(|schema| schema.write()) + .collect() + } + _ => unimplemented!("{} is not supported", url.scheme()), + }; + + let output = EntityTransformer::transform(table_stmts)? + .generate(expanded_format, WithSerde::from_str(with_serde).unwrap()); + + let dir = Path::new(output_dir); + fs::create_dir_all(dir)?; + + for OutputFile { name, content } in output.files.iter() { + let file_path = dir.join(name); + let mut file = fs::File::create(file_path)?; + file.write_all(content.as_bytes())?; } - database_name - } else { - Default::default() - }; - - let table_stmts = match url.scheme() { - "mysql" => { - use sea_schema::mysql::discovery::SchemaDiscovery; - use sqlx::MySql; - - let connection = connect::(max_connections, url.as_str()).await?; - let schema_discovery = SchemaDiscovery::new(connection, database_name); - let schema = schema_discovery.discover().await; - schema - .tables - .into_iter() - .filter(|schema| filter_tables(&schema.info.name)) - .filter(|schema| filter_hidden_tables(&schema.info.name)) - .map(|schema| schema.write()) - .collect() + // Format each of the files + for OutputFile { name, .. } in output.files.iter() { + Command::new("rustfmt") + .arg(dir.join(name)) + .spawn()? + .wait()?; } - "sqlite" => { - use sea_schema::sqlite::discovery::SchemaDiscovery; - use sqlx::Sqlite; - - let connection = connect::(max_connections, url.as_str()).await?; - let schema_discovery = SchemaDiscovery::new(connection); - let schema = schema_discovery.discover().await?; - schema - .tables - .into_iter() - .filter(|schema| filter_tables(&schema.name)) - .filter(|schema| filter_hidden_tables(&schema.name)) - .map(|schema| schema.write()) - .collect() - } - "postgres" | "postgresql" => { - use sea_schema::postgres::discovery::SchemaDiscovery; - use sqlx::Postgres; - - let schema = args.value_of("DATABASE_SCHEMA").unwrap_or("public"); - let connection = connect::(max_connections, url.as_str()).await?; - let schema_discovery = SchemaDiscovery::new(connection, schema); - let schema = schema_discovery.discover().await; - schema - .tables - .into_iter() - .filter(|schema| filter_tables(&schema.info.name)) - .filter(|schema| filter_hidden_tables(&schema.info.name)) - .map(|schema| schema.write()) - .collect() - } - _ => unimplemented!("{} is not supported", url.scheme()), - }; - - let output = EntityTransformer::transform(table_stmts)? - .generate(expanded_format, WithSerde::from_str(with_serde).unwrap()); - - let dir = Path::new(output_dir); - fs::create_dir_all(dir)?; - - for OutputFile { name, content } in output.files.iter() { - let file_path = dir.join(name); - let mut file = fs::File::create(file_path)?; - file.write_all(content.as_bytes())?; - } - - // Format each of the files - for OutputFile { name, .. } in output.files.iter() { - Command::new("rustfmt") - .arg(dir.join(name)) - .spawn()? - .wait()?; } - } - _ => unreachable!("You should never see this message"), - }; + _ => unreachable!("You should never see this message"), + }, + None => unreachable!("You should never see this message"), + } Ok(()) } @@ -189,66 +192,71 @@ where .map_err(Into::into) } -pub fn run_migrate_command(matches: &ArgMatches<'_>) -> Result<(), Box> { +pub fn run_migrate_command(matches: &ArgMatches) -> Result<(), Box> { let migrate_subcommand = matches.subcommand(); - // If it's `migrate init` - if let ("init", Some(args)) = migrate_subcommand { - let migration_dir = args.value_of("MIGRATION_DIR").unwrap(); - let migration_dir = match migration_dir.ends_with('/') { - true => migration_dir.to_string(), - false => format!("{}/", migration_dir), - }; - println!("Initializing migration directory..."); - macro_rules! write_file { - ($filename: literal) => { - write_file!($filename, $filename); - }; - ($filename: literal, $template: literal) => { - let filepath = [&migration_dir, $filename].join(""); - println!("Creating file `{}`", filepath); - let path = Path::new(&filepath); - let prefix = path.parent().unwrap(); - fs::create_dir_all(prefix).unwrap(); - let mut file = fs::File::create(path)?; - let content = include_str!(concat!("../template/migration/", $template)); - file.write_all(content.as_bytes())?; + + if let Some((name, args)) = migrate_subcommand { + if name == "init" { + let migration_dir = args.value_of("MIGRATION_DIR").unwrap(); + let migration_dir = match migration_dir.ends_with('/') { + true => migration_dir.to_string(), + false => format!("{}/", migration_dir), }; + println!("Initializing migration directory..."); + macro_rules! write_file { + ($filename: literal) => { + write_file!($filename, $filename); + }; + ($filename: literal, $template: literal) => { + let filepath = [&migration_dir, $filename].join(""); + println!("Creating file `{}`", filepath); + let path = Path::new(&filepath); + let prefix = path.parent().unwrap(); + fs::create_dir_all(prefix).unwrap(); + let mut file = fs::File::create(path)?; + let content = include_str!(concat!("../template/migration/", $template)); + file.write_all(content.as_bytes())?; + }; + } + write_file!("src/lib.rs"); + write_file!("src/m20220101_000001_create_table.rs"); + write_file!("src/main.rs"); + write_file!("Cargo.toml", "_Cargo.toml"); + write_file!("README.md"); + println!("Done!"); + // Early exit! + return Ok(()); } - write_file!("src/lib.rs"); - write_file!("src/m20220101_000001_create_table.rs"); - write_file!("src/main.rs"); - write_file!("Cargo.toml", "_Cargo.toml"); - write_file!("README.md"); - println!("Done!"); - // Early exit! - return Ok(()); - } else if let ("generate", Some(args)) = migrate_subcommand { - let migration_dir = args.value_of("MIGRATION_DIR").unwrap(); - let migration_name = args.value_of("MIGRATION_NAME").unwrap(); - println!("Generating new migration..."); - - // build new migration filename - let now = Local::now(); - let migration_name = format!( - "m{}_{}", - now.format("%Y%m%d_%H%M%S").to_string(), - migration_name - ); - create_new_migration(&migration_name, migration_dir)?; - update_migrator(&migration_name, migration_dir)?; - return Ok(()); + if name == "generate" { + let migration_dir = args.value_of("MIGRATION_DIR").unwrap(); + let migration_name = args.value_of("MIGRATION_NAME").unwrap(); + println!("Generating new migration..."); + + // build new migration filename + let now = Local::now(); + let migration_name = format!( + "m{}_{}", + now.format("%Y%m%d_%H%M%S").to_string(), + migration_name + ); + + create_new_migration(&migration_name, migration_dir)?; + update_migrator(&migration_name, migration_dir)?; + return Ok(()); + } } + let (subcommand, migration_dir, steps, verbose) = match migrate_subcommand { // Catch all command with pattern `migrate xxx` - (subcommand, Some(args)) => { + Some((subcommand, args)) => { let migration_dir = args.value_of("MIGRATION_DIR").unwrap(); let steps = args.value_of("NUM_MIGRATION"); let verbose = args.is_present("VERBOSE"); (subcommand, migration_dir, steps, verbose) } // Catch command `migrate`, this will be treated as `migrate up` - _ => { + None => { let migration_dir = matches.value_of("MIGRATION_DIR").unwrap(); let verbose = matches.is_present("VERBOSE"); ("up", migration_dir, None, verbose) @@ -349,23 +357,20 @@ where mod tests { use super::*; use crate::cli; - use clap::AppSettings; #[test] #[should_panic( expected = "called `Result::unwrap()` on an `Err` value: RelativeUrlWithoutBase" )] fn test_generate_entity_no_protocol() { - let matches = cli::build_cli() - .setting(AppSettings::NoBinaryName) - .get_matches_from(vec![ - "generate", - "entity", - "--database-url", - "://root:root@localhost:3306/database", - ]); - - smol::block_on(run_generate_command(matches.subcommand().1.unwrap())).unwrap(); + let matches = cli::build_cli().no_binary_name(true).get_matches_from(vec![ + "generate", + "entity", + "--database-url", + "://root:root@localhost:3306/database", + ]); + + smol::block_on(run_generate_command(matches.subcommand().unwrap().1)).unwrap(); } #[test] @@ -373,16 +378,14 @@ mod tests { expected = "There is no database name as part of the url path: postgresql://root:root@localhost:3306" )] fn test_generate_entity_no_database_section() { - let matches = cli::build_cli() - .setting(AppSettings::NoBinaryName) - .get_matches_from(vec![ - "generate", - "entity", - "--database-url", - "postgresql://root:root@localhost:3306", - ]); - - smol::block_on(run_generate_command(matches.subcommand().1.unwrap())).unwrap(); + let matches = cli::build_cli().no_binary_name(true).get_matches_from(vec![ + "generate", + "entity", + "--database-url", + "postgresql://root:root@localhost:3306", + ]); + + smol::block_on(run_generate_command(matches.subcommand().unwrap().1)).unwrap(); } #[test] @@ -390,61 +393,53 @@ mod tests { expected = "There is no database name as part of the url path: mysql://root:root@localhost:3306/" )] fn test_generate_entity_no_database_path() { - let matches = cli::build_cli() - .setting(AppSettings::NoBinaryName) - .get_matches_from(vec![ - "generate", - "entity", - "--database-url", - "mysql://root:root@localhost:3306/", - ]); - - smol::block_on(run_generate_command(matches.subcommand().1.unwrap())).unwrap(); + let matches = cli::build_cli().no_binary_name(true).get_matches_from(vec![ + "generate", + "entity", + "--database-url", + "mysql://root:root@localhost:3306/", + ]); + + smol::block_on(run_generate_command(matches.subcommand().unwrap().1)).unwrap(); } #[test] #[should_panic(expected = "No username was found in the database url")] fn test_generate_entity_no_username() { - let matches = cli::build_cli() - .setting(AppSettings::NoBinaryName) - .get_matches_from(vec![ - "generate", - "entity", - "--database-url", - "mysql://:root@localhost:3306/database", - ]); - - smol::block_on(run_generate_command(matches.subcommand().1.unwrap())).unwrap(); + let matches = cli::build_cli().no_binary_name(true).get_matches_from(vec![ + "generate", + "entity", + "--database-url", + "mysql://:root@localhost:3306/database", + ]); + + smol::block_on(run_generate_command(matches.subcommand().unwrap().1)).unwrap(); } #[test] #[should_panic(expected = "called `Result::unwrap()` on an `Err` value: PoolTimedOut")] fn test_generate_entity_no_password() { - let matches = cli::build_cli() - .setting(AppSettings::NoBinaryName) - .get_matches_from(vec![ - "generate", - "entity", - "--database-url", - "mysql://root:@localhost:3306/database", - ]); - - smol::block_on(run_generate_command(matches.subcommand().1.unwrap())).unwrap(); + let matches = cli::build_cli().no_binary_name(true).get_matches_from(vec![ + "generate", + "entity", + "--database-url", + "mysql://root:@localhost:3306/database", + ]); + + smol::block_on(run_generate_command(matches.subcommand().unwrap().1)).unwrap(); } #[test] #[should_panic(expected = "called `Result::unwrap()` on an `Err` value: EmptyHost")] fn test_generate_entity_no_host() { - let matches = cli::build_cli() - .setting(AppSettings::NoBinaryName) - .get_matches_from(vec![ - "generate", - "entity", - "--database-url", - "postgres://root:root@/database", - ]); - - smol::block_on(run_generate_command(matches.subcommand().1.unwrap())).unwrap(); + let matches = cli::build_cli().no_binary_name(true).get_matches_from(vec![ + "generate", + "entity", + "--database-url", + "postgres://root:root@/database", + ]); + + smol::block_on(run_generate_command(matches.subcommand().unwrap().1)).unwrap(); } #[test] fn test_create_new_migration() { diff --git a/sea-orm-cli/src/migration.rs b/sea-orm-cli/src/migration.rs index 41cd507bbe..157b9ffdd2 100644 --- a/sea-orm-cli/src/migration.rs +++ b/sea-orm-cli/src/migration.rs @@ -1,13 +1,12 @@ -use clap::{App, AppSettings, Arg, SubCommand}; +use clap::{Arg, Command}; -pub fn build_cli() -> App<'static, 'static> { - let mut app = App::new("sea-schema-migration") +pub fn build_cli() -> Command<'static> { + let mut app = Command::new("sea-schema-migration") .version(env!("CARGO_PKG_VERSION")) - .setting(AppSettings::VersionlessSubcommands) .arg( - Arg::with_name("VERBOSE") + Arg::new("VERBOSE") .long("verbose") - .short("v") + .short('v') .help("Show debug messages") .takes_value(false) .global(true), @@ -18,29 +17,27 @@ pub fn build_cli() -> App<'static, 'static> { app } -pub fn get_subcommands() -> Vec> { +pub fn get_subcommands() -> Vec> { vec![ - SubCommand::with_name("fresh") + Command::new("fresh") .about("Drop all tables from the database, then reapply all migrations"), - SubCommand::with_name("refresh") + Command::new("refresh") .about("Rollback all applied migrations, then reapply all migrations"), - SubCommand::with_name("reset").about("Rollback all applied migrations"), - SubCommand::with_name("status").about("Check the status of all migrations"), - SubCommand::with_name("up") - .about("Apply pending migrations") - .arg( - Arg::with_name("NUM_MIGRATION") - .long("num") - .short("n") - .help("Number of pending migrations to be applied") - .takes_value(true), - ), - SubCommand::with_name("down") + Command::new("reset").about("Rollback all applied migrations"), + Command::new("status").about("Check the status of all migrations"), + Command::new("up").about("Apply pending migrations").arg( + Arg::new("NUM_MIGRATION") + .long("num") + .short('n') + .help("Number of pending migrations to be applied") + .takes_value(true), + ), + Command::new("down") .about("Rollback applied migrations") .arg( - Arg::with_name("NUM_MIGRATION") + Arg::new("NUM_MIGRATION") .long("num") - .short("n") + .short('n') .help("Number of pending migrations to be rolled back") .takes_value(true) .default_value("1"),