Skip to content

Commit f559f0a

Browse files
authored
CLI - Unify copies of the confirmation/--force logic (#1740)
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
1 parent 7478737 commit f559f0a

File tree

7 files changed

+43
-60
lines changed

7 files changed

+43
-60
lines changed

crates/cli/src/subcommands/generate/mod.rs

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ use spacetimedb_schema::def::{ModuleDef, ReducerDef, ScopedTypeName, TableDef, T
1818
use spacetimedb_schema::identifier::Identifier;
1919
use spacetimedb_schema::schema::TableSchema;
2020
use std::fs;
21-
use std::io::Write;
2221
use std::ops::Deref;
2322
use std::path::{Path, PathBuf};
2423
use wasmtime::{Caller, StoreContextMut};
2524

25+
use crate::util::y_or_n;
2626
use crate::Config;
2727

2828
mod code_indenter;
@@ -190,22 +190,12 @@ pub fn exec(_config: Config, args: &clap::ArgMatches) -> anyhow::Result<()> {
190190
}
191191
}
192192
if !files_to_delete.is_empty() {
193-
let mut input = "y".to_string();
194193
println!("The following files were not generated by this command and will be deleted:");
195194
for path in &files_to_delete {
196195
println!(" {}", path.to_str().unwrap());
197196
}
198197

199-
if !force {
200-
print!("Are you sure you want to delete these files? [y/N] ");
201-
input = "".to_string();
202-
std::io::stdout().flush()?;
203-
std::io::stdin().read_line(&mut input)?;
204-
} else {
205-
println!("Force flag present, deleting files without prompting.");
206-
}
207-
208-
if input.trim().to_lowercase() == "y" || input.trim().to_lowercase() == "yes" {
198+
if y_or_n(force, "Are you sure you want to delete these files?")? {
209199
for path in files_to_delete {
210200
fs::remove_file(path)?;
211201
}

crates/cli/src/subcommands/identity.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,10 @@ async fn exec_remove(mut config: Config, args: &ArgMatches) -> Result<(), anyhow
316316
}
317317

318318
fn should_continue(force: bool, prompt: &str) -> anyhow::Result<bool> {
319-
Ok(force || y_or_n(&format!("Are you sure you want to remove all identities{}?", prompt))?)
319+
y_or_n(
320+
force,
321+
&format!("Are you sure you want to remove all identities{}?", prompt),
322+
)
320323
}
321324

322325
if let Some(identity_or_name) = identity_or_name {

crates/cli/src/subcommands/local.rs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use crate::config::Config;
2+
use crate::util::y_or_n;
23
use clap::ArgAction::SetTrue;
34
use clap::ArgMatches;
45
use clap::{Arg, Command};
56
use spacetimedb::stdb_path;
6-
use std::io::Write;
77
use std::path::PathBuf;
88

99
pub fn cli() -> Command {
@@ -60,17 +60,12 @@ async fn exec_clear(_config: Config, args: &ArgMatches) -> Result<(), anyhow::Er
6060
println!("Worker node database path: <not found>");
6161
}
6262

63-
if !force {
64-
print!("Are you sure you want to delete all data from the local database? (y/n) ");
65-
std::io::stdout().flush()?;
66-
let mut input = String::new();
67-
std::io::stdin().read_line(&mut input)?;
68-
if input.trim().to_lowercase() != "y" && input.trim().to_lowercase() != "yes" {
69-
println!("Aborting");
70-
return Ok(());
71-
}
72-
} else {
73-
println!("Force flag is present, skipping confirmation");
63+
if !y_or_n(
64+
force,
65+
"Are you sure you want to delete all data from the local database?",
66+
)? {
67+
println!("Aborting");
68+
return Ok(());
7469
}
7570

7671
if control_node_dir.exists() {

crates/cli/src/subcommands/publish.rs

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,12 @@ use reqwest::{StatusCode, Url};
66
use spacetimedb_client_api_messages::name::PublishOp;
77
use spacetimedb_client_api_messages::name::{is_address, parse_domain_name, PublishResult};
88
use std::fs;
9-
use std::io::Write;
109
use std::path::PathBuf;
1110

1211
use crate::common_args;
1312
use crate::config::Config;
14-
use crate::util::unauth_error_context;
1513
use crate::util::{add_auth_header_opt, get_auth_header};
14+
use crate::util::{unauth_error_context, y_or_n};
1615

1716
pub fn cli() -> clap::Command {
1817
clap::Command::new("publish")
@@ -166,25 +165,21 @@ pub async fn exec(mut config: Config, args: &ArgMatches) -> Result<(), anyhow::E
166165
);
167166

168167
if clear_database {
169-
if force {
170-
println!("Skipping confirmation due to --force.");
171-
} else {
172-
// Note: `name_or_address` should be set, because it is `required` in the CLI arg config.
173-
println!(
174-
"This will DESTROY the current {} module, and ALL corresponding data.",
168+
// Note: `name_or_address` should be set, because it is `required` in the CLI arg config.
169+
println!(
170+
"This will DESTROY the current {} module, and ALL corresponding data.",
171+
name_or_address.unwrap()
172+
);
173+
if !y_or_n(
174+
force,
175+
format!(
176+
"Are you sure you want to proceed? [deleting {}]",
175177
name_or_address.unwrap()
176-
);
177-
print!(
178-
"Are you sure you want to proceed? (y/N) [deleting {}] ",
179-
name_or_address.unwrap()
180-
);
181-
std::io::stdout().flush()?;
182-
let mut input = String::new();
183-
std::io::stdin().read_line(&mut input)?;
184-
if input.trim().to_lowercase() != "y" && input.trim().to_lowercase() != "yes" {
185-
println!("Aborting");
186-
return Ok(());
187-
}
178+
)
179+
.as_str(),
180+
)? {
181+
println!("Aborting");
182+
return Ok(());
188183
}
189184
query_params.push(("clear", "true"));
190185
}

crates/cli/src/subcommands/server.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ pub async fn exec_remove(mut config: Config, args: &ArgMatches) -> Result<(), an
260260
for id in deleted_ids {
261261
println!("{}", id.identity);
262262
}
263-
if !(force || y_or_n("Continue?")?) {
263+
if !y_or_n(force, "Continue?")? {
264264
anyhow::bail!("Aborted");
265265
}
266266

@@ -339,7 +339,7 @@ pub async fn exec_fingerprint(mut config: Config, args: &ArgMatches) -> Result<(
339339
let force = args.get_flag("force");
340340

341341
if update_server_fingerprint(&mut config, server, delete_identities).await? {
342-
if !(force || y_or_n("Continue?")?) {
342+
if !y_or_n(force, "Continue?")? {
343343
anyhow::bail!("Aborted");
344344
}
345345

@@ -412,7 +412,7 @@ pub async fn exec_edit(mut config: Config, args: &ArgMatches) -> Result<(), anyh
412412
}
413413
}
414414

415-
if !(force || y_or_n("Continue?")?) {
415+
if !y_or_n(force, "Continue?")? {
416416
anyhow::bail!("Aborted");
417417
}
418418

crates/cli/src/subcommands/upgrade.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::{env, fs};
33

44
extern crate regex;
55

6+
use crate::util::y_or_n;
67
use crate::{version, Config};
78
use clap::{Arg, ArgMatches};
89
use flate2::read::GzDecoder;
@@ -152,10 +153,8 @@ pub async fn exec(_config: Config, args: &ArgMatches) -> Result<(), anyhow::Erro
152153

153154
if release_version == version::CLI_VERSION {
154155
println!("You're already running the latest version: {}", version::CLI_VERSION);
155-
if !force {
156+
if !y_or_n(force, "Do you want to reinstall? ")? {
156157
return Ok(());
157-
} else {
158-
println!("Force flag is set, continuing with upgrade.");
159158
}
160159
}
161160

@@ -177,11 +176,8 @@ pub async fn exec(_config: Config, args: &ArgMatches) -> Result<(), anyhow::Erro
177176
"This will replace the current executable at {}.",
178177
current_exe_path.display()
179178
);
180-
print!("Do you want to continue? [y/N] ");
181-
std::io::stdout().flush()?;
182-
let mut input = String::new();
183-
std::io::stdin().read_line(&mut input)?;
184-
if input.trim().to_lowercase() != "y" && input.trim().to_lowercase() != "yes" {
179+
180+
if !y_or_n(force, "Do you want to continue?")? {
185181
println!("Aborting upgrade.");
186182
return Ok(());
187183
}

crates/cli/src/util.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -344,13 +344,17 @@ pub fn host_or_url_to_host_and_protocol(host_or_url: &str) -> (&str, Option<&str
344344
/// Prompt the user for `y` or `n` from stdin.
345345
///
346346
/// Return `false` unless the input is `y`.
347-
pub fn y_or_n(prompt: &str) -> anyhow::Result<bool> {
347+
pub fn y_or_n(force: bool, prompt: &str) -> anyhow::Result<bool> {
348+
if force {
349+
println!("Force flag is present, skipping confirmation");
350+
return Ok(true);
351+
}
348352
let mut input = String::new();
349-
print!("{} (y/n)", prompt);
353+
print!("{} [y/N]", prompt);
350354
std::io::stdout().flush()?;
351355
std::io::stdin().read_line(&mut input)?;
352-
353-
Ok(input.trim() == "y")
356+
let input = input.trim().to_lowercase();
357+
Ok(input == "y" || input == "yes")
354358
}
355359

356360
pub fn unauth_error_context<T>(res: anyhow::Result<T>, identity: &str, server: &str) -> anyhow::Result<T> {

0 commit comments

Comments
 (0)