diff --git a/src/cli/install.rs b/src/cli/install.rs index 1f40f31f5..7f36b9551 100644 --- a/src/cli/install.rs +++ b/src/cli/install.rs @@ -23,7 +23,7 @@ use crate::platform::{binary_path, config_dir, home_dir}; use crate::portable::platform; use crate::portable::project::project_dir; use crate::portable::project::{self, Init}; -use crate::print::{self, echo}; +use crate::print::{self, msg}; use crate::print_markdown; use crate::process; use crate::question::{self, read_choice}; @@ -452,13 +452,13 @@ fn _main(options: &CliInstall) -> anyhow::Result<()> { if !options.no_confirm { match home_dir_from_passwd().zip(env::var_os("HOME")) { Some((passwd, env)) if passwd != env => { - echo!( + msg!( "$HOME differs from euid-obtained home directory: \ you may be using sudo" ); - echo!("$HOME directory:", Path::new(&env).display()); - echo!("euid-obtained home directory:", passwd.display()); - echo!( + msg!("$HOME directory: {}", Path::new(&env).display()); + msg!("euid-obtained home directory: {}", passwd.display()); + msg!( "if this is what you want, \ restart the installation with `-y'" ); @@ -499,10 +499,7 @@ fn _main(options: &CliInstall) -> anyhow::Result<()> { } if cfg!(all(target_os = "macos", target_arch = "x86_64")) && platform::is_arm64_hardware() { - echo!( - BRANDING, - "now supports native M1 build. Downloading binary..." - ); + msg!("{BRANDING} now supports native M1 build. Downloading binary..."); return upgrade::upgrade_to_arm64(); } diff --git a/src/cli/upgrade.rs b/src/cli/upgrade.rs index b28473d97..cf9cfcbd8 100644 --- a/src/cli/upgrade.rs +++ b/src/cli/upgrade.rs @@ -12,7 +12,7 @@ use crate::platform::{binary_path, current_exe, home_dir, tmp_file_path}; use crate::portable::platform; use crate::portable::repository::{self, download, Channel}; use crate::portable::ver; -use crate::print::{self, echo, Highlight}; +use crate::print::{self, msg, Highlight}; use crate::process; const INDEX_TIMEOUT: Duration = Duration::new(60, 0); @@ -226,7 +226,7 @@ fn _main(options: &CliUpgrade, path: PathBuf) -> anyhow::Result<()> { .run()?; fs::remove_file(&tmp_path).ok(); if !options.quiet { - echo!("Upgraded to version", pkg.version.emphasize()); + msg!("Upgraded to version {}", pkg.version.emphasize()); } Ok(()) } diff --git a/src/cloud/secret_keys.rs b/src/cloud/secret_keys.rs index 4712a72c0..172bfb583 100644 --- a/src/cloud/secret_keys.rs +++ b/src/cloud/secret_keys.rs @@ -12,8 +12,7 @@ use crate::portable::exit_codes; use crate::table::{self, Cell, Row, Table}; -use crate::echo; -use crate::print::{self, Highlight}; +use crate::print::{self, msg, Highlight}; use crate::question; #[derive(Debug, serde::Deserialize, serde::Serialize)] @@ -142,15 +141,15 @@ pub async fn _do_create(c: &options::CreateSecretKey, client: &CloudClient) -> a if c.non_interactive { print!("{sk}"); } else { - echo!( - "\nYour new ", + msg!( + "\nYour new {} {}", BRANDING_CLOUD, " secret key is printed below. \ Be sure to copy and store it securely, as you will \ not be able to see it again.\n" .green() ); - echo!(sk.emphasize()); + msg!("{}", sk.emphasize()); } } diff --git a/src/commands/ui.rs b/src/commands/ui.rs index 632afef9a..94d2e66b2 100644 --- a/src/commands/ui.rs +++ b/src/commands/ui.rs @@ -9,7 +9,7 @@ use crate::commands::ExitCode; use crate::options::{Options, UI}; use crate::portable::local; use crate::portable::repository::USER_AGENT; -use crate::print; +use crate::print::{self, msg}; pub fn show_ui(cmd: &UI, opts: &Options) -> anyhow::Result<()> { let connector = opts.block_on_create_connector()?; @@ -102,10 +102,10 @@ fn _get_local_ui_url(cmd: &UI, cfg: &edgedb_tokio::Config) -> anyhow::Result { - print::echo!("{} returned status code {}, retry HTTP.", https_url, status); + msg!("{https_url} returned status code {status}, retry HTTP."); } Err(e) => { - print::echo!("Failed to probe {}: {:#}, retry HTTP.", https_url, e); + msg!("Failed to probe {https_url}: {e:#}, retry HTTP."); } } } @@ -118,7 +118,7 @@ fn _get_local_ui_url(cmd: &UI, cfg: &edgedb_tokio::Config) -> anyhow::Result Result<(), anyhow::Error> { pub async fn _main(options: Options, mut state: repl::State, cfg: Config) -> anyhow::Result<()> { state.connect().await?; if let Some(config_path) = &cfg.file_name { - echo!(format_args!("Applied {} configuration file", config_path.display(),).fade()); + msg!( + "{}", + format_args!("Applied {} configuration file", config_path.display(),).fade() + ); } - echo!(r#"Type \help for help, \quit to quit."#.light_gray()); + msg!("{}", r#"Type \help for help, \quit to quit."#.light_gray()); state.set_history_limit(state.history_limit).await?; match _interactive_main(&options, &mut state).await { Ok(()) => Ok(()), @@ -586,7 +588,7 @@ async fn _interactive_main( continue 'retry; } print::error("State could not be updated automatically"); - echo!( + msg!( " Hint: This means that migrations or DDL \ statements were run in a concurrent \ connection during the interactive \ diff --git a/src/migrations/edit.rs b/src/migrations/edit.rs index 4e7a7a69f..3dd68b69f 100644 --- a/src/migrations/edit.rs +++ b/src/migrations/edit.rs @@ -12,7 +12,7 @@ use crate::migrations::grammar::parse_migration; use crate::migrations::migration::{file_num, read_names}; use crate::migrations::options::MigrationEdit; use crate::platform::{spawn_editor, tmp_file_path}; -use crate::print::{echo, err_marker, Highlight}; +use crate::print::{err_marker, msg, Highlight}; use crate::question::Choice; #[derive(Copy, Clone)] @@ -102,9 +102,9 @@ pub async fn edit_no_check( } fs::write(&tmp_file, migration.replace_id(&text, &new_id)).await?; fs::rename(&tmp_file, &path).await?; - echo!("Updated migration id to", new_id.emphasize()); + msg!("Updated migration id to {}", new_id.emphasize()); } else { - echo!("Id", migration.id.emphasize(), "is already correct."); + msg!("Id {} is already correct.", migration.id.emphasize()); } Ok(()) } @@ -175,9 +175,9 @@ async fn _edit( anyhow::Ok(()) }) .await?; - echo!("Updated migration id to", new_id.emphasize()); + msg!("Updated migration id to {}", new_id.emphasize()); } else { - echo!("Id", migration.id.emphasize(), "is already correct."); + msg!("Id {} is already correct.", migration.id.emphasize()); } } else { let temp_path = path.parent().unwrap().join(format!(".editing.{n}.edgeql")); @@ -226,7 +226,7 @@ async fn _edit( let migration = match parse_migration(&new_data) { Ok(migr) => migr, Err(e) => { - echo!(err_marker(), "error parsing file:", e); + msg!("{} error parsing file: {}", err_marker(), e); loop { let mut q = Choice::new("Edit again?"); q.option( @@ -276,14 +276,14 @@ async fn _edit( if migration.id != new_id { new_data = migration.replace_id(&new_data, &new_id); fs::write(&temp_path, &new_data).await?; - echo!("Updated migration id to", new_id.emphasize()); + msg!("Updated migration id to {}", new_id.emphasize()); } else { - echo!("Id", migration.id.emphasize(), "is already correct."); + msg!("Id {} is already correct.", migration.id.emphasize()); } match check_migration(cli, &new_data, &path).await { Ok(()) => {} Err(e) => { - echo!(err_marker(), "error checking migration:", e); + msg!("{} error checking migration: {}", err_marker(), e); loop { let mut q = Choice::new("Edit again?"); q.option(FailAction::Edit, &["y", "yes"][..], "edit the file again"); diff --git a/src/migrations/squash.rs b/src/migrations/squash.rs index 54a00d0f5..ed4b94188 100644 --- a/src/migrations/squash.rs +++ b/src/migrations/squash.rs @@ -20,7 +20,7 @@ use crate::migrations::migration; use crate::migrations::options::CreateMigration; use crate::migrations::status::migrations_applied; use crate::migrations::timeout; -use crate::print::{echo, Highlight}; +use crate::print::{msg, Highlight}; use crate::question::Confirm; struct TwoStageRemove<'a> { @@ -41,11 +41,11 @@ pub async fn main( let needs_fixup = needs_fixup(cli, &ctx).await?; if db_rev == "initial" { - echo!("No migrations exist. No actions will be taken."); + msg!("No migrations exist. No actions will be taken."); return Ok(()); } if migrations.len() == 1 && !needs_fixup { - echo!("Only a single revision exists. No actions will be taken."); + msg!("Only a single revision exists. No actions will be taken."); return Ok(()); } if !create.non_interactive { @@ -122,29 +122,29 @@ async fn create_revision( } async fn confirm_squashing(db_rev: &str) -> anyhow::Result<()> { - echo!("Current database revision:", db_rev.emphasize()); - echo!( + msg!("Current database revision: {}", db_rev.emphasize()); + msg!( "While squashing migrations is non-destructive, it may lead to manual work \ if done incorrectly." ); - echo!(""); - echo!("Items to check before using --squash:"); - echo!(" 1. Ensure that the `./dbschema` dir is committed to version control"); - echo!( + msg!(); + msg!("Items to check before using --squash:"); + msg!(" 1. Ensure that the `./dbschema` dir is committed to version control"); + msg!( " 2. Ensure that other users of the database either have all .edgeql files\n \ up to the revision above or can create the database from scratch.\n \ Hint: To see the current revision for a specific instance, run:" ); - echo!( - " ", + msg!( + " {} {}", BRANDING_CLI_CMD, " -I migration log --from-db --newest-first --limit 1".command_hint() ); - echo!( + msg!( " 3. Merge version control branches that contain schema changes \ if possible." ); - echo!(""); + msg!(); if !Confirm::new("Proceed?").async_ask().await? { return Err(ExitCode::new(0))?; } @@ -152,45 +152,49 @@ async fn confirm_squashing(db_rev: &str) -> anyhow::Result<()> { } async fn want_fixup() -> anyhow::Result { - echo!( + msg!( "Your schema differs from the last revision. \ A fixup file can be created to automate \ upgrading other instances to a squashed revision. \ This starts the usual migration creation process." ); - echo!(""); - echo!( + msg!(); + msg!( "Feel free to skip this step if you don't have \ other instances to migrate" ); - echo!(""); + msg!(); Confirm::new("Create a fixup file?").async_ask().await } fn print_final_message(fixup_created: bool) -> anyhow::Result<()> { if fixup_created { - echo!("Squash is complete."); - echo!(""); - echo!( + msg!("Squash is complete."); + msg!(); + msg!( "Remember to commit the `dbschema` directory including deleted \ files and `fixups` subdirectory. Recommended command:" ); - echo!(" git add dbschema".command_hint()); - echo!(""); - echo!("The normal migration process will update your migration history:"); - echo!(" ", BRANDING_CLI_CMD, "migrate".command_hint()); + msg!("{}", " git add dbschema".command_hint()); + msg!(); + msg!("The normal migration process will update your migration history:"); + msg!(" {} {}", BRANDING_CLI_CMD, "migrate".command_hint()); } else { - echo!("Squash is complete."); - echo!(""); - echo!( + msg!("Squash is complete."); + msg!(); + msg!( "Remember to commit the `dbschema` directory including deleted \ files. Recommended command:" ); - echo!(" git add dbschema".command_hint()); - echo!(""); - echo!("You can now wipe your instances and apply the new schema:"); - echo!(" ", BRANDING_CLI_CMD, "database wipe".command_hint()); - echo!(" ", BRANDING_CLI_CMD, "migrate".command_hint()); + msg!("{}", " git add dbschema".command_hint()); + msg!(); + msg!("You can now wipe your instances and apply the new schema:"); + msg!( + " {} {}", + BRANDING_CLI_CMD, + "database wipe".command_hint() + ); + msg!(" {} {}", BRANDING_CLI_CMD, "migrate".command_hint()); } Ok(()) } diff --git a/src/migrations/upgrade_check.rs b/src/migrations/upgrade_check.rs index fc29e5fbb..e0159f28a 100644 --- a/src/migrations/upgrade_check.rs +++ b/src/migrations/upgrade_check.rs @@ -23,7 +23,7 @@ use crate::portable::config::Config; use crate::portable::install; use crate::portable::local::InstallInfo; use crate::portable::repository::{self, PackageInfo, Query}; -use crate::print::{echo, success, warn, Highlight}; +use crate::print::{msg, success, warn, Highlight}; use crate::process; use crate::watch::wait_changes; @@ -214,9 +214,9 @@ async fn do_check(ctx: &Context, status_file: &Path, watch: bool) -> anyhow::Res match single_check(ctx, cli).await? { Okay => {} SchemaIssue => { - echo!("For faster feedback loop use:"); - echo!( - " ", + msg!("For faster feedback loop use:"); + msg!( + " {} {}", BRANDING_CLI_CMD, " migration upgrade-check --watch".command_hint() ); @@ -228,7 +228,7 @@ async fn do_check(ctx: &Context, status_file: &Path, watch: bool) -> anyhow::Res } } if !ctx.quiet { - echo!("The schema is forward compatible. Ready for upgrade."); + msg!("The schema is forward compatible. Ready for upgrade."); } Ok(()) } @@ -294,9 +294,9 @@ fn print_apply_migration_error() { "The current schema is compatible, \ but some of the migrations are outdated.", ); - echo!("Please squash all migrations to fix the issue:"); - echo!( - " ", + msg!("Please squash all migrations to fix the issue:"); + msg!( + " {} {}", BRANDING_CLI_CMD, " migration create --squash".command_hint() ); diff --git a/src/portable/backup.rs b/src/portable/backup.rs index b39a5cd4d..2ab61d7a6 100644 --- a/src/portable/backup.rs +++ b/src/portable/backup.rs @@ -3,7 +3,7 @@ use color_print::cformat; use crate::branding::{BRANDING_CLI_CMD, BRANDING_CLOUD}; use crate::cloud; use crate::portable::options::{Backup, InstanceName, ListBackups, Restore}; -use crate::print::echo; +use crate::print::msg; use crate::question; pub fn list(cmd: &ListBackups, opts: &crate::options::Options) -> anyhow::Result<()> { @@ -75,12 +75,7 @@ fn backup_cloud_cmd( }; cloud::backups::backup_cloud_instance(&client, &request)?; - echo!( - "Successfully created a backup for ", - BRANDING_CLOUD, - " instance", - inst_name, - ); + msg!("Successfully created a backup for {BRANDING_CLOUD} instance {inst_name}"); Ok(()) } @@ -144,13 +139,8 @@ fn restore_cloud_cmd( }; cloud::backups::restore_cloud_instance(&client, &request)?; - echo!( - BRANDING_CLOUD, - " instance", - inst_name, - "has been restored successfully." - ); - echo!("To connect to the instance run:"); - echo!(" ", BRANDING_CLI_CMD, "-I", inst_name); + msg!("{BRANDING_CLOUD} instance {inst_name} has been restored successfully."); + msg!("To connect to the instance run:"); + msg!(" {BRANDING_CLI_CMD} -I {inst_name}"); Ok(()) } diff --git a/src/portable/config.rs b/src/portable/config.rs index ed681ead9..72960dbb5 100644 --- a/src/portable/config.rs +++ b/src/portable/config.rs @@ -11,7 +11,7 @@ use crate::commands::ExitCode; use crate::platform::tmp_file_path; use crate::portable::exit_codes; use crate::portable::repository::{Channel, Query}; -use crate::print::{self, echo, Highlight}; +use crate::print::{self, msg, Highlight}; #[derive(serde::Deserialize)] #[serde(rename_all = "kebab-case")] @@ -175,10 +175,9 @@ where #[context("cannot modify `{}`", config.display())] pub fn modify_server_ver(config: &Path, ver: &Query) -> anyhow::Result { - echo!( - "Setting `server-version = ", + msg!( + "Setting `server-version = {}` in `{}`", format_args!("{:?}", ver.as_config_value()).emphasize(), - "` in `{}`", config.file_name().unwrap_or_default().to_string_lossy() ); read_modify_write( diff --git a/src/portable/create.rs b/src/portable/create.rs index 7d1f5741e..5ae1a4afb 100644 --- a/src/portable/create.rs +++ b/src/portable/create.rs @@ -23,7 +23,7 @@ use crate::portable::platform::optional_docker_check; use crate::portable::repository::{Query, QueryOptions}; use crate::portable::reset_password::{generate_password, password_hash}; use crate::portable::{linux, macos, windows}; -use crate::print::{self, echo, err_marker, Highlight}; +use crate::print::{self, err_marker, msg, Highlight}; use crate::process; use crate::question; @@ -54,11 +54,10 @@ fn ask_name(cloud_client: &mut cloud::client::CloudClient) -> anyhow::Result anyhow::Result<() let inst_name = if let Some(name) = &cmd.name { name.to_owned() } else if cmd.non_interactive { - echo!( - err_marker(), - "Instance name is required \ - in non-interactive mode" + msg!( + "{} Instance name is required \ + in non-interactive mode", + err_marker() ); return Err(ExitCode::new(2).into()); } else { @@ -204,9 +203,9 @@ pub fn create(cmd: &Create, opts: &crate::options::Options) -> anyhow::Result<() } } - echo!("Instance", name.emphasize(), "is up and running."); - echo!("To connect to the instance run:"); - echo!(" ", BRANDING_CLI_CMD, "-I", name); + msg!("Instance {} is up and running.", name.emphasize()); + msg!("To connect to the instance run:"); + msg!(" {BRANDING_CLI_CMD} -I {name}"); Ok(()) } @@ -390,9 +389,9 @@ fn create_cloud( source_backup_id: cmd.cloud_backup_source.from_backup_id.clone(), }; cloud::ops::create_cloud_instance(client, &request)?; - echo!(BRANDING_CLOUD, "instance", inst_name, "is up and running."); - echo!("To connect to the instance run:"); - echo!(" ", BRANDING_CLI_CMD, "-I", inst_name); + msg!("{BRANDING_CLOUD} instance {inst_name} is up and running."); + msg!("To connect to the instance run:"); + msg!(" {BRANDING_CLI_CMD} -I {inst_name}"); Ok(()) } @@ -446,7 +445,7 @@ pub fn bootstrap( let password = generate_password(); let script = bootstrap_script(user, &password); - echo!("Initializing", BRANDING, "instance..."); + msg!("Initializing {BRANDING} instance..."); let mut cmd = process::Native::new("bootstrap", "edgedb", server_path); cmd.arg("--bootstrap-only"); cmd.env_default("EDGEDB_SERVER_LOG_LEVEL", "warn"); diff --git a/src/portable/destroy.rs b/src/portable/destroy.rs index dc331f7c4..efea89264 100644 --- a/src/portable/destroy.rs +++ b/src/portable/destroy.rs @@ -11,7 +11,7 @@ use crate::portable::local; use crate::portable::options::{instance_arg, Destroy, InstanceName}; use crate::portable::project; use crate::portable::windows; -use crate::print::{self, echo, Highlight}; +use crate::print::{self, msg, Highlight}; use crate::question; #[derive(Debug, thiserror::Error)] @@ -69,7 +69,7 @@ pub fn destroy(options: &Destroy, opts: &Options) -> anyhow::Result<()> { } })?; if !options.quiet { - echo!("Instance", name_str.emphasize(), "is successfully deleted."); + msg!("Instance {} is successfully deleted.", name_str.emphasize()); } Ok(()) } diff --git a/src/portable/install.rs b/src/portable/install.rs index 1050cf4fb..385d58558 100644 --- a/src/portable/install.rs +++ b/src/portable/install.rs @@ -20,7 +20,7 @@ use crate::portable::repository::QueryOptions; use crate::portable::repository::{download, PackageHash, PackageInfo, Query}; use crate::portable::repository::{get_server_package, get_specific_package}; use crate::portable::ver::{self, Build}; -use crate::print::{self, echo, Highlight}; +use crate::print::{self, msg, Highlight}; static INSTALLED_VERSIONS: Lazy>> = Lazy::new(|| Mutex::new(BTreeSet::new())); @@ -195,12 +195,12 @@ pub fn package(pkg_info: &PackageInfo) -> anyhow::Result { .unwrap() .insert(meta.version.clone()) { - echo!("Version", meta.version.emphasize(), "is already downloaded"); + msg!("Version {} is already downloaded", meta.version.emphasize()); } return Ok(meta); } - echo!("Downloading package..."); + msg!("Downloading package..."); let cache_path = download_package(pkg_info)?; let tmp_target = platform::tmp_file_path(&target_dir); unpack_package(&cache_path, &tmp_target)?; @@ -215,7 +215,7 @@ pub fn package(pkg_info: &PackageInfo) -> anyhow::Result { fs::rename(&tmp_target, &target_dir) .with_context(|| format!("cannot rename {tmp_target:?} -> {target_dir:?}"))?; unlink_cache(&cache_path); - echo!("Successfully installed", pkg_info.version.emphasize()); + msg!("Successfully installed {}", pkg_info.version.emphasize()); INSTALLED_VERSIONS .lock() .unwrap() diff --git a/src/portable/macos.rs b/src/portable/macos.rs index f436bd405..0de7d6985 100644 --- a/src/portable/macos.rs +++ b/src/portable/macos.rs @@ -13,7 +13,7 @@ use crate::platform::{data_dir, get_current_uid, home_dir}; use crate::portable::local::{log_file, runstate_dir, InstanceInfo}; use crate::portable::options::{instance_arg, InstanceName, Logs}; use crate::portable::status::Service; -use crate::print::{self, echo, Highlight}; +use crate::print::{self, msg, Highlight}; use crate::process; enum Status { @@ -383,15 +383,20 @@ fn wait_started(name: &str) -> anyhow::Result<()> { Failed { exit_code: Some(code), } => { - echo!( + msg!( + "{} {} with exit code {}", print::err_marker(), "{BRANDING} failed".emphasize(), - "with exit code", code ); } Failed { exit_code: None } => { - echo!(print::err_marker(), BRANDING, "failed".emphasize()); + msg!( + "{} {} {}", + print::err_marker(), + BRANDING, + "failed".emphasize() + ); } } } diff --git a/src/portable/options.rs b/src/portable/options.rs index 377d7e769..580d71da0 100644 --- a/src/portable/options.rs +++ b/src/portable/options.rs @@ -16,7 +16,7 @@ use crate::portable::local::{ }; use crate::portable::repository::Channel; use crate::portable::ver; -use crate::print::{echo, err_marker, warn}; +use crate::print::{err_marker, msg, warn}; use crate::process::{self, IntoArg}; const DOMAIN_LABEL_MAX_LENGTH: usize = 63; @@ -933,11 +933,11 @@ pub fn instance_arg<'x>( ) -> anyhow::Result<&'x InstanceName> { if let Some(name) = positional { if named.is_some() { - echo!( - err_marker(), - "Instance name is specified twice \ + msg!( + "{} Instance name is specified twice \ as positional argument and via `-I`. \ - The latter is preferred." + The latter is preferred.", + err_marker() ); return Err(ExitCode::new(2).into()); } @@ -950,9 +950,9 @@ pub fn instance_arg<'x>( if let Some(name) = named { return Ok(name); } - echo!( - err_marker(), - "Instance name argument is required, use '-I name'" + msg!( + "{} Instance name argument is required, use '-I name'", + err_marker() ); Err(ExitCode::new(2).into()) } diff --git a/src/portable/project.rs b/src/portable/project.rs index 7b462c17e..a77d90dc2 100644 --- a/src/portable/project.rs +++ b/src/portable/project.rs @@ -44,7 +44,7 @@ use crate::portable::upgrade; use crate::portable::ver; use crate::portable::ver::Specific; use crate::portable::windows; -use crate::print::{self, echo, Highlight}; +use crate::print::{self, msg, Highlight}; use crate::question; use crate::table; @@ -421,15 +421,15 @@ fn link( config_path: PathBuf, cloud_options: &crate::options::CloudOptions, ) -> anyhow::Result { - echo!( - "Found `{}` in", + msg!( + "Found `{}` in {}", config_path .file_name() .unwrap_or_default() .to_string_lossy(), project_dir.display() ); - echo!("Linking project..."); + msg!("Linking project..."); let stash_dir = get_stash_path(project_dir)?; if stash_dir.exists() { @@ -607,15 +607,15 @@ pub fn init_existing( config_path: PathBuf, cloud_options: &crate::options::CloudOptions, ) -> anyhow::Result { - echo!( - "Found `{}` in", + msg!( + "Found `{}` in {}", config_path .file_name() .unwrap_or_default() .to_string_lossy(), project_dir.display() ); - echo!("Initializing project..."); + msg!("Initializing project..."); let stash_dir = get_stash_path(project_dir)?; if stash_dir.exists() { @@ -667,7 +667,7 @@ pub fn init_existing( match &name { InstanceName::Cloud { org_slug, name } => { - echo!("Checking", BRANDING_CLOUD, "versions..."); + msg!("Checking {BRANDING_CLOUD} versions..."); let ver = cloud::versions::get_version(&ver_query, &client) .with_context(|| "could not initialize project")?; @@ -716,7 +716,7 @@ pub fn init_existing( ) } InstanceName::Local(name) => { - echo!("Checking", BRANDING, "versions..."); + msg!("Checking {BRANDING} versions..."); let pkg = repository::get_server_package(&ver_query)?.with_context(|| { format!( @@ -998,7 +998,7 @@ pub fn init_new( match &inst_name { InstanceName::Cloud { org_slug, name } => { - echo!("Checking", BRANDING_CLOUD, "versions..."); + msg!("Checking {BRANDING_CLOUD} versions..."); client.ensure_authenticated()?; let (ver_query, version) = ask_cloud_version(options, &client)?; @@ -1047,7 +1047,7 @@ pub fn init_new( ) } InstanceName::Local(name) => { - echo!("Checking", BRANDING, "versions..."); + msg!("Checking {BRANDING} versions..."); let (ver_query, pkg) = ask_local_version(options)?; let specific_version = &pkg.version.specific(); ver::print_version_hint(specific_version, &ver_query); @@ -1197,7 +1197,7 @@ async fn migrate_async(inst: &Handle<'_>, ask_for_running: bool) -> anyhow::Resu Skip, } - echo!("Applying migrations..."); + msg!("Applying migrations..."); let mut conn = loop { match inst.get_default_connection().await { @@ -1231,10 +1231,8 @@ async fn migrate_async(inst: &Handle<'_>, ask_for_running: bool) -> anyhow::Resu Retry => continue, Skip => { print::warn("Skipping migrations."); - echo!( - "You can use `", - BRANDING_CLI_CMD, - " migrate` to apply migrations \ + msg!( + "You can use `{BRANDING_CLI_CMD} migrate` to apply migrations \ once the service is up and running." ); return Ok(()); @@ -1423,10 +1421,18 @@ fn find_schema_files(path: &Path) -> anyhow::Result { fn print_initialized(name: &str, dir_option: &Option) { print::success("Project initialized."); if let Some(dir) = dir_option { - echo!("To connect to", name.emphasize(); - ", navigate to", dir.display(), "and run `", BRANDING_CLI_CMD, "`"); + msg!( + "To connect to {}, navigate to {} and run `{}`", + name.emphasize(), + dir.display(), + BRANDING_CLI_CMD + ); } else { - echo!("To connect to", name.emphasize(); ", run `", BRANDING_CLI_CMD, "`"); + msg!( + "To connect to {}, run `{}`", + name.emphasize(), + BRANDING_CLI_CMD + ); } } @@ -1691,7 +1697,7 @@ pub fn unlink(options: &Unlink, opts: &crate::options::Options) -> anyhow::Resul } else { match fs::read_to_string(stash_path.join("instance-name")) { Ok(name) => { - echo!("Unlinking instance", name.emphasize()); + msg!("Unlinking instance {}", name.emphasize()); } Err(e) => { print::error(format!("Cannot read instance name: {e}")); @@ -1727,10 +1733,10 @@ pub fn info(options: &Info) -> anyhow::Result<()> { }; let stash_dir = get_stash_path(&root)?; if !stash_dir.exists() { - echo!( + msg!( + "{} {} Run `edgedb project init`.", print::err_marker(), - "Project is not initialized.".emphasize(), - "Run `edgedb project init`." + "Project is not initialized.".emphasize() ); return Err(ExitCode::new(1).into()); } @@ -1903,11 +1909,10 @@ pub fn update_toml( } else { print::success("Config is up to date."); } - echo!( - "Run", + msg!( + "Run {} {} to initialize an instance.", BRANDING_CLI_CMD, - " project init".command_hint(), - "to initialize an instance." + " project init".command_hint() ); } else { let name = instance_name(&stash_dir)?; @@ -1936,21 +1941,16 @@ pub fn update_toml( }; if config::modify_server_ver(&config_path, &config_version)? { - echo!("Remember to commit it to version control."); + msg!("Remember to commit it to version control."); } let name_str = name.to_string(); print_other_project_warning(&name_str, &root, &query)?; } upgrade::UpgradeAction::Cancelled => { - echo!("Canceled."); + msg!("Canceled."); } upgrade::UpgradeAction::None => { - echo!( - "Already up to date.\nRequested upgrade version is", - result.requested_version.emphasize().to_string() + ",", - "current instance version is", - result.prior_version.emphasize().to_string() + ".", - ); + msg!("Already up to date.\nRequested upgrade version is {} current instance version is {}", result.requested_version.emphasize().to_string() + ",", result.prior_version.emphasize().to_string() + "."); } } }; @@ -2025,10 +2025,10 @@ pub fn upgrade_instance(options: &Upgrade, opts: &crate::options::Options) -> an // would have already printed a message. } upgrade::UpgradeAction::Cancelled => { - echo!("Canceled."); + msg!("Canceled."); } upgrade::UpgradeAction::None => { - echo!( + msg!( "{BRANDING} instance is up to date with \ the specification in `{}`.", config_path @@ -2037,12 +2037,11 @@ pub fn upgrade_instance(options: &Upgrade, opts: &crate::options::Options) -> an .to_string_lossy() ); if let Some(available) = result.available_upgrade { - echo!("New major version is available:", available.emphasize()); - echo!( + msg!("New major version is available: {}", available.emphasize()); + msg!( "To update `{}` and upgrade to this version, \ - run:\n ", + run:\n {} project upgrade --to-latest", BRANDING_CLI_CMD, - " project upgrade --to-latest", config_path .file_name() .unwrap_or_default() @@ -2159,10 +2158,9 @@ fn upgrade_cloud( if let upgrade::UpgradeAction::Upgraded = result.action { let inst_name = format!("{org}/{name}"); - echo!( - "Instance", + msg!( + "Instance {} has been successfully upgraded to {}", inst_name.emphasize(), - "has been successfully upgraded to", result.requested_version.emphasize().to_string() + "." ); } diff --git a/src/portable/resize.rs b/src/portable/resize.rs index 8e882661b..cc9bd03d6 100644 --- a/src/portable/resize.rs +++ b/src/portable/resize.rs @@ -5,7 +5,7 @@ use anyhow::Context; use crate::branding::{BRANDING_CLI_CMD, BRANDING_CLOUD}; use crate::cloud; use crate::portable::options::{InstanceName, Resize}; -use crate::print::echo; +use crate::print::msg; use crate::question; pub fn resize(cmd: &Resize, opts: &crate::options::Options) -> anyhow::Result<()> { @@ -178,13 +178,8 @@ fn resize_cloud_cmd( }; cloud::ops::resize_cloud_instance(&client, &request)?; } - echo!( - BRANDING_CLOUD, - " instance", - inst_name, - "has been resized successfuly." - ); - echo!("To connect to the instance run:"); - echo!(" ", BRANDING_CLI_CMD, "-I", inst_name); + msg!("{BRANDING_CLOUD} instance {inst_name} has been resized successfuly."); + msg!("To connect to the instance run:"); + msg!(" {BRANDING_CLI_CMD} -I {inst_name}"); Ok(()) } diff --git a/src/portable/revert.rs b/src/portable/revert.rs index c77a5777b..7c8078e10 100644 --- a/src/portable/revert.rs +++ b/src/portable/revert.rs @@ -14,7 +14,7 @@ use crate::portable::install; use crate::portable::local::Paths; use crate::portable::options::{instance_arg, InstanceName, Revert}; use crate::portable::status::{instance_status, BackupStatus, DataDirectory}; -use crate::print::{self, echo, Highlight}; +use crate::print::{self, msg, Highlight}; use crate::process; use crate::question; @@ -53,35 +53,34 @@ pub fn revert(options: &Revert) -> anyhow::Result<()> { data_meta: Ok(d), } => (b, d), }; - echo!(BRANDING, "version:", old_inst.get_version()?); - echo!( - "Backup timestamp:", + msg!("{} version: {:?}", BRANDING, old_inst.get_version()); + msg!( + "Backup timestamp: {} {}", humantime::format_rfc3339(backup_info.timestamp), format!("({})", format::done_before(backup_info.timestamp)) ); if !options.ignore_pid_check { match status.data_status { DataDirectory::Upgrading(Ok(up)) if process::exists(up.pid) => { - echo!( + msg!( "Upgrade appears to still be in progress \ - with pid", - up.pid.emphasize(), + with pid {}", + up.pid.emphasize() ); - echo!("Run with `--ignore-pid-check` to override"); + msg!("Run with `--ignore-pid-check` to override"); Err(ExitCode::new(exit_codes::NEEDS_FORCE))?; } DataDirectory::Upgrading(_) => { - echo!("Note: backup appears to be from a broken upgrade"); + msg!("Note: backup appears to be from a broken upgrade"); } _ => {} } } if !options.no_confirm { eprintln!(); - echo!( - "Currently stored data", - "will be lost".emphasize(), - "and overwritten by the backup." + msg!( + "Currently stored data {} and overwritten by the backup.", + "will be lost".emphasize() ); let q = question::Confirm::new_dangerous("Do you really want to revert?"); if !q.ask()? { @@ -110,7 +109,7 @@ pub fn revert(options: &Revert) -> anyhow::Result<()> { fs::rename(&paths.backup_dir, &paths.data_dir)?; let inst = old_inst; - echo!("Starting", BRANDING, inst.get_version()?; "..."); + msg!("Starting {} {:?}...", BRANDING, inst.get_version()); create::create_service(&inst) .map_err(|e| { @@ -119,10 +118,9 @@ pub fn revert(options: &Revert) -> anyhow::Result<()> { .ok(); control::do_restart(&inst)?; - echo!( - "Instance", + msg!( + "Instance {} is successfully reverted to {}", inst.name.emphasize(), - "is successfully reverted to", inst.get_version()?.emphasize() ); diff --git a/src/portable/status.rs b/src/portable/status.rs index 24ad42e83..c1cc3bdfe 100644 --- a/src/portable/status.rs +++ b/src/portable/status.rs @@ -33,7 +33,7 @@ use crate::portable::local::{InstanceInfo, Paths}; use crate::portable::options::{instance_arg, InstanceName, List, Status}; use crate::portable::upgrade::{BackupMeta, UpgradeMeta}; use crate::portable::{linux, macos, windows}; -use crate::print::{self, echo, Highlight}; +use crate::print::{self, msg, Highlight}; use crate::process; use crate::table::{self, Cell, Row, Table}; @@ -312,11 +312,10 @@ async fn _remote_status(name: &str, quiet: bool) -> anyhow::Result let cred_path = credentials::path(name)?; if !cred_path.exists() { if !quiet { - echo!( + msg!( + "{} No instance {} found", print::err_marker(), - "No instance", - name.emphasize(), - "found" + name.emphasize() ); } return Err(ExitCode::new(exit_codes::INSTANCE_NOT_FOUND).into()); diff --git a/src/portable/uninstall.rs b/src/portable/uninstall.rs index 2ba5c6844..71bf70562 100644 --- a/src/portable/uninstall.rs +++ b/src/portable/uninstall.rs @@ -10,7 +10,7 @@ use crate::portable::options::Uninstall; use crate::portable::repository::Query; use crate::portable::status; use crate::portable::ver; -use crate::print::{self, echo, Highlight}; +use crate::print::{self, msg, Highlight}; pub fn uninstall(options: &Uninstall) -> anyhow::Result<()> { let mut candidates = local::get_installed()?; @@ -68,14 +68,13 @@ pub fn uninstall(options: &Uninstall) -> anyhow::Result<()> { } if !all && !options.unused { - echo!("Uninstalled", uninstalled.emphasize(), "versions."); + msg!("Uninstalled {} versions.", uninstalled.emphasize()); print::error("some instances are in use. See messages above."); Err(ExitCode::new(exit_codes::PARTIAL_SUCCESS))?; } else if uninstalled > 0 { - echo!( - "Successfully uninstalled", - uninstalled.emphasize(), - "versions." + msg!( + "Successfully uninstalled {} versions.", + uninstalled.emphasize() ); } else { print::success("Nothing to uninstall.") diff --git a/src/portable/upgrade.rs b/src/portable/upgrade.rs index 31c6ae63c..ef61f0aff 100644 --- a/src/portable/upgrade.rs +++ b/src/portable/upgrade.rs @@ -21,7 +21,7 @@ use crate::portable::project; use crate::portable::repository::{self, Channel, PackageInfo, Query, QueryOptions}; use crate::portable::ver; use crate::portable::windows; -use crate::print::{self, echo, Highlight}; +use crate::print::{self, msg, Highlight}; use crate::question; #[derive(serde::Serialize, serde::Deserialize, Debug)] @@ -139,12 +139,10 @@ fn upgrade_local_cmd(cmd: &Upgrade, name: &str) -> anyhow::Result<()> { let pkg_ver = pkg.version.specific(); if pkg_ver <= inst_ver && !cmd.force { - echo!( - "Latest version found", + msg!( + "Latest version found {} current instance version is {} Already up to date.", pkg.version.to_string() + ",", - "current instance version is", - inst.get_version()?.emphasize().to_string() + ".", - "Already up to date." + inst.get_version()?.emphasize().to_string() + "." ); return Ok(()); } @@ -203,21 +201,16 @@ fn upgrade_cloud_cmd( match result.action { UpgradeAction::Upgraded => { - echo!(format!( + msg!( "{BRANDING_CLOUD} instance {inst_name} has been successfully \ - upgraded to version {target_ver_str}.", - )); + upgraded to version {target_ver_str}." + ); } UpgradeAction::Cancelled => { - echo!("Canceled."); + msg!("Canceled."); } UpgradeAction::None => { - echo!( - "Already up to date.\nRequested upgrade version is", - target_ver_str.emphasize().to_string() + ",", - "current instance version is", - result.prior_version.emphasize().to_string() + ".", - ); + msg!("Already up to date.\nRequested upgrade version is {} current instance version is {}", target_ver_str.emphasize().to_string() + ",", result.prior_version.emphasize().to_string() + "."); } } @@ -272,7 +265,7 @@ pub fn upgrade_cloud( } pub fn upgrade_compatible(mut inst: InstanceInfo, pkg: PackageInfo) -> anyhow::Result<()> { - echo!("Upgrading to a minor version", pkg.version.emphasize()); + msg!("Upgrading to a minor version {}", pkg.version.emphasize()); let install = install::package(&pkg).context(concatcp!("error installing ", BRANDING))?; inst.installation = Some(install); @@ -285,10 +278,9 @@ pub fn upgrade_compatible(mut inst: InstanceInfo, pkg: PackageInfo) -> anyhow::R }) .ok(); control::do_restart(&inst)?; - echo!( - "Instance", + msg!( + "Instance {} successfully upgraded to {}", inst.name.emphasize(), - "successfully upgraded to", pkg.version.emphasize() ); Ok(()) @@ -299,7 +291,7 @@ pub fn upgrade_incompatible( pkg: PackageInfo, non_interactive: bool, ) -> anyhow::Result<()> { - echo!("Upgrading to a major version", pkg.version.emphasize()); + msg!("Upgrading to a major version {}", pkg.version.emphasize()); let old_version = inst.get_version()?.clone(); @@ -364,10 +356,9 @@ pub fn upgrade_incompatible( .ok(); control::do_restart(&inst)?; - echo!( - "Instance", + msg!( + "Instance {} successfully upgraded to {}", inst.name.emphasize(), - "successfully upgraded to", pkg.version.emphasize() ); @@ -377,7 +368,7 @@ pub fn upgrade_incompatible( #[context("cannot dump {:?} -> {}", inst.name, path.display())] pub fn dump_and_stop(inst: &InstanceInfo, path: &Path) -> anyhow::Result<()> { // in case not started for now - echo!("Dumping the database..."); + msg!("Dumping the database..."); log::info!("Ensuring instance is started"); let res = control::do_start(inst); if let Err(err) = res { @@ -464,7 +455,7 @@ fn reinit_and_restore(inst: &InstanceInfo, paths: &Paths) -> anyhow::Result<()> fs::create_dir_all(&paths.data_dir) .with_context(|| format!("cannot create {:?}", paths.data_dir))?; - echo!("Restoring the database..."); + msg!("Restoring the database..."); control::ensure_runstate_dir(&inst.name)?; let mut cmd = control::get_server_cmd(inst, false)?; control::self_signed_arg(&mut cmd, inst.get_version()?); diff --git a/src/portable/ver.rs b/src/portable/ver.rs index bd0530bc9..625c87ce3 100644 --- a/src/portable/ver.rs +++ b/src/portable/ver.rs @@ -10,7 +10,7 @@ use regex::Regex; use crate::branding::BRANDING_CLI_CMD; use crate::connect::Connection; use crate::portable::repository::Query; -use crate::print::{echo, Highlight}; +use crate::print::{msg, Highlight}; use crate::process::{self, IntoArg}; #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] @@ -396,9 +396,12 @@ pub async fn check_client(cli: &mut Connection, minimum_version: &Build) -> anyh pub fn print_version_hint(version: &Specific, ver_query: &Query) { if let Some(filter) = &ver_query.version { if !filter.matches_exact(version) { - echo!("Using", version.emphasize(), - "(matches `"; filter; "`), use `"; filter.clone().with_exact(); - "` for exact version"); + msg!( + "Using {} (matches `{}`), use `{}` for exact version", + version.emphasize(), + filter, + filter.clone().with_exact() + ); } } } diff --git a/src/portable/windows.rs b/src/portable/windows.rs index 29d9a6dc8..1ecec00a3 100644 --- a/src/portable/windows.rs +++ b/src/portable/windows.rs @@ -32,7 +32,7 @@ use crate::portable::project; use crate::portable::repository::{self, download, PackageHash, PackageInfo}; use crate::portable::status::{self, Service}; use crate::portable::ver; -use crate::print::{self, echo, Highlight}; +use crate::print::{self, msg, Highlight}; use crate::process; const CURRENT_DISTRO: &str = BRANDING_WSL; @@ -264,7 +264,7 @@ pub fn destroy(options: &options::Destroy, name: &str) -> anyhow::Result<()> { } } if !found { - echo!("No instance named", name.emphasize(), "found"); + msg!("No instance named {} found", name.emphasize()); return Err(ExitCode::new(exit_codes::INSTANCE_NOT_FOUND).into()); } Ok(()) @@ -456,7 +456,7 @@ fn get_wsl_distro(install: bool) -> anyhow::Result { let download_path = download_dir.join("debian.zip"); download(&download_path, &*DISTRO_URL, false)?; - echo!("Unpacking WSL distribution..."); + msg!("Unpacking WSL distribution..."); let appx_path = download_dir.join("debian.appx"); unpack_appx(&download_path, &appx_path)?; let root_path = download_dir.join("install.tar"); @@ -464,7 +464,7 @@ fn get_wsl_distro(install: bool) -> anyhow::Result { let distro_path = wsl_dir()?.join(CURRENT_DISTRO); fs::create_dir_all(&distro_path)?; - echo!("Initializing WSL distribution..."); + msg!("Initializing WSL distribution..."); let result = process::Native::new("wsl check", "wsl", "wsl") .arg("--help") @@ -509,7 +509,7 @@ fn get_wsl_distro(install: bool) -> anyhow::Result { } if update_cli { - echo!("Updating container CLI version..."); + msg!("Updating container CLI version..."); if let Some(bin_path) = env::var_os("_EDGEDB_WSL_LINUX_BINARY") { let bin_path = fs::canonicalize(bin_path)?; wsl_simple_cmd( @@ -537,7 +537,7 @@ fn get_wsl_distro(install: bool) -> anyhow::Result { let certs_timestamp = if let Some(ts) = certs_timestamp { ts } else { - echo!("Checking certificate updates..."); + msg!("Checking certificate updates..."); process::Native::new("update certificates", "apt", "wsl") .arg("--distribution") .arg(&distro) @@ -866,7 +866,7 @@ pub fn status(options: &options::Status) -> anyhow::Result<()> { .args(options) .run()?; } else { - echo!( + msg!( "WSL distribution is not installed, \ so no {BRANDING} instances are present." ); diff --git a/src/print/color.rs b/src/print/color.rs index c3c5b3f5a..a00f4200e 100644 --- a/src/print/color.rs +++ b/src/print/color.rs @@ -148,34 +148,8 @@ impl fmt::Display for Colored<&T> { } #[macro_export] -macro_rules! echo { - ($word1:expr $(; $semi_word1:expr)* - $(,$word:expr $(; $semi_word:expr )*)* $(,)?) => { - // Buffer the whole output so mutliple processes do not interfere - // each other - { - use ::std::fmt::Write; - let mut buf = ::std::string::String::with_capacity(4096); - write!(&mut buf, "{}", $word1) - .expect("buffering of echo succeeds"); - $( - write!(&mut buf, "{}", $semi_word1) - .expect("buffering of echo succeeds"); - )* - $( - buf.push(' '); - write!(&mut buf, "{}", $word) - .expect("buffering of echo succeeds"); - $( - write!(&mut buf, "{}", $semi_word) - .expect("buffering of echo succeeds"); - )* - )* - if cfg!(windows) { - buf.push('\r'); - } - buf.push('\n'); - eprint!("{}", buf); - }; +macro_rules! msg { + ($($tt:tt)*) => { + eprintln!($($tt)*); } } diff --git a/src/print/mod.rs b/src/print/mod.rs index a4dd58ff9..d453d3a53 100644 --- a/src/print/mod.rs +++ b/src/print/mod.rs @@ -15,7 +15,7 @@ use edgedb_errors::display::display_error; use crate::branding::BRANDING_CLI_CMD; use crate::repl::VectorLimit; -pub use crate::echo; +pub use crate::msg; mod buffer; mod color; @@ -398,41 +398,42 @@ pub fn err_marker() -> impl fmt::Display { pub fn error(line: impl fmt::Display) { let text = format!("{line:#}"); if text.len() > 60 { - echo!(err_marker(), text); + msg!("{} {}", err_marker(), text); } else { // Emphasise only short lines. Long lines with bold look ugly. - echo!(err_marker(), text.emphasize()); + msg!("{} {}", err_marker(), text.emphasize()); } } pub fn edgedb_error(err: &edgedb_errors::Error, verbose: bool) { // Note: not using `error()` as display_error has markup inside - echo!(err_marker(), display_error(err, verbose)); + msg!("{} {}", err_marker(), display_error(err, verbose)); } pub fn success(line: impl fmt::Display) { if use_color() { - echo!(line.to_string().bold().light_green()); + msg!("{}", line.to_string().bold().light_green()); } else { - echo!(line); + msg!("{line}"); } } pub fn success_msg(title: impl fmt::Display, msg: impl fmt::Display) { if use_color() { - echo!( - title.to_string().bold().light_green(); ":", - msg.to_string().bold().white(), + msg!( + "{}: {}", + title.to_string().bold().light_green(), + msg.to_string().bold().white() ); } else { - echo!(title; ":", msg); + msg!("{title}: {msg}"); } } pub fn warn(line: impl fmt::Display) { if use_color() { - echo!(line.to_string().bold().yellow()); + msg!("{}", line.to_string().bold().yellow()); } else { - echo!(line); + msg!("{line}"); } } diff --git a/src/repl.rs b/src/repl.rs index 2f076b8c4..c7b73b57b 100644 --- a/src/repl.rs +++ b/src/repl.rs @@ -21,9 +21,8 @@ use crate::async_util::timeout; use crate::branding::BRANDING; use crate::connect::Connection; use crate::connect::Connector; -use crate::echo; use crate::portable::ver; -use crate::print::{self, Highlight}; +use crate::print::{self, msg, Highlight}; use crate::prompt::variable::VariableInput; use crate::prompt::{self, Control}; @@ -164,10 +163,11 @@ impl State { Ok(()) } fn print_banner(&self, version: &ver::Build) -> anyhow::Result<()> { - echo!( + msg!( + "{} {} {}", format!("{}\r{BRANDING}", ansi_escapes::EraseLine).light_gray(), version.to_string().light_gray(), - format_args!("(repl {})", env!("CARGO_PKG_VERSION")).fade(), + format_args!("(repl {})", env!("CARGO_PKG_VERSION")).fade() ); Ok(()) }