diff --git a/src/commands/repo/add.rs b/src/commands/repo/add.rs index 707d682..b62af43 100644 --- a/src/commands/repo/add.rs +++ b/src/commands/repo/add.rs @@ -2,6 +2,7 @@ use crate::common::git; use crate::filesystem::{ all_cheat_files, all_git_files, create_dir, default_cheat_pathbuf, remove_dir, tmp_pathbuf, }; +use crate::finder::questions::finder_yes_no_question; use crate::finder::structures::{Opts as FinderOpts, SuggestionType}; use crate::finder::FinderChoice; use crate::prelude::*; @@ -16,28 +17,30 @@ fn ask_if_should_import_all(finder: &FinderChoice) -> Result { ..Default::default() }; - let (response, _) = finder - .call(opts, |stdin| { - stdin - .write_all(b"Yes\nNo") - .context("Unable to writer alternatives")?; - Ok(()) - }) - .context("Unable to get response")?; + finder_yes_no_question(finder, opts) +} +fn ask_folder_present_question(finder: &FinderChoice) -> Result { + let opts = FinderOpts { + column: Some(1), + header: Some( + "It seems this cheatsheet repository has been previously added, do you still want to continue?" + .to_string(), + ), + ..Default::default() + }; - Ok(response.to_lowercase().starts_with('y')) + finder_yes_no_question(finder, opts) } pub fn main(uri: String, yes_flag: bool) -> Result<()> { let finder = CONFIG.finder(); - let should_import_all; - // If the user hasn't set the yes flag, we ask a confirmation - if ! yes_flag { - should_import_all = ask_if_should_import_all(&finder).unwrap_or(false); + // If the user has set the yes flag, we don't ask a confirmation + let should_import_all = if yes_flag { + true } else { - should_import_all = true; - } + ask_if_should_import_all(&finder).unwrap_or(false) + }; let (actual_uri, user, repo) = git::meta(uri.as_str()); @@ -46,6 +49,23 @@ pub fn main(uri: String, yes_flag: bool) -> Result<()> { let cheat_pathbuf = default_cheat_pathbuf()?; let tmp_pathbuf = tmp_pathbuf()?; let tmp_path_str = &tmp_pathbuf.to_string(); + let to_folder = { + let mut p = cheat_pathbuf; + p.push(format!("{user}__{repo}")); + p + }; + + // Before anything else, we check to see if the folder exists + // if it exists -> ask confirmation if we continue + if fs::exists(&to_folder)? { + // When the yes_flag has been raised => follow through and removes the existing directory + // When the yes_flag has not been raised => ask for confirmation + if yes_flag || ask_folder_present_question(&finder).unwrap_or(false) { + fs::remove_dir_all(&to_folder)?; + } else { + return Ok(()); + } + } let _ = remove_dir(&tmp_pathbuf); create_dir(&tmp_pathbuf)?; @@ -80,12 +100,6 @@ pub fn main(uri: String, yes_flag: bool) -> Result<()> { files }; - let to_folder = { - let mut p = cheat_pathbuf; - p.push(format!("{user}__{repo}")); - p - }; - for file in files.split('\n') { let from = { let mut p = tmp_pathbuf.clone(); @@ -128,16 +142,22 @@ pub fn main(uri: String, yes_flag: bool) -> Result<()> { local_collection[0..&local_collection.len() - 1].join(MAIN_SEPARATOR_STR) ); + let complete_local_path = format!( + "{}{}", + &to_folder.clone().to_str().unwrap(), + &to.clone().to_str().unwrap() + ); + + eprintln!("=> {}", &complete_local_path); + fs::create_dir_all(&local_to_folder).unwrap_or(()); - fs::copy( - &from, + fs::copy(&from, &complete_local_path).with_context(|| { format!( - "{}{}", - &to_folder.clone().to_str().unwrap(), - &to.clone().to_str().unwrap() - ), - ) - .with_context(|| format!("Failed to copy `{}` to `{}`", &from.to_string(), &to.to_string()))?; + "Failed to copy `{}` to `{}`", + &from.to_string(), + &complete_local_path + ) + })?; } remove_dir(&tmp_pathbuf)?; diff --git a/src/commands/repo/mod.rs b/src/commands/repo/mod.rs index d87e2ca..a14e2d6 100644 --- a/src/commands/repo/mod.rs +++ b/src/commands/repo/mod.rs @@ -16,8 +16,8 @@ pub enum RepoCommand { /// A URI to a git repository containing .cheat files ("user/repo" will download cheats from github.com/user/repo) uri: String, /// Assumes yes for all confirmations - #[clap(short='y', long="yes")] - yes_flag: bool + #[clap(short = 'y', long = "yes")] + yes_flag: bool, }, /// Synchronize either all cheatsheet repositories or a given one. Sync { @@ -38,7 +38,7 @@ impl Runnable for Input { fn run(&self) -> Result<()> { match &self.cmd { RepoCommand::Add { uri, yes_flag } => { - add::main(uri.clone(), yes_flag.clone()) + add::main(uri.clone(), *yes_flag) .with_context(|| format!("Failed to import cheatsheets from `{uri}`"))?; commands::core::main() diff --git a/src/finder/mod.rs b/src/finder/mod.rs index a1edee6..624edd7 100644 --- a/src/finder/mod.rs +++ b/src/finder/mod.rs @@ -1,20 +1,22 @@ use crate::deser; use crate::prelude::*; +use clap::ValueEnum; +pub use post::process; use std::io::Write; use std::process::{self, Output}; use std::process::{Command, Stdio}; -pub mod structures; -use clap::ValueEnum; -pub use post::process; use structures::Opts; use structures::SuggestionType; +pub mod questions; +pub mod structures; + +mod post; + const MIN_FZF_VERSION_MAJOR: u32 = 0; const MIN_FZF_VERSION_MINOR: u32 = 23; const MIN_FZF_VERSION_PATCH: u32 = 1; -mod post; - #[derive(Debug, Clone, Copy, Deserialize, ValueEnum)] pub enum FinderChoice { Fzf, diff --git a/src/finder/questions.rs b/src/finder/questions.rs new file mode 100644 index 0000000..d2d6eec --- /dev/null +++ b/src/finder/questions.rs @@ -0,0 +1,16 @@ +use crate::finder::structures::Opts; +use crate::finder::FinderChoice; +use crate::prelude::*; + +pub fn finder_yes_no_question(finder: &FinderChoice, opts: Opts) -> anyhow::Result { + let (response, _) = finder + .call(opts, |stdin| { + stdin + .write_all(b"Yes\nNo") + .context("Unable to writer alternatives")?; + Ok(()) + }) + .context("Unable to get response")?; + + Ok(response.to_lowercase().starts_with('y')) +}