From 4696c9069b1a863ab243e16eb9a78ec0328409cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Katona?= Date: Thu, 3 Sep 2020 17:44:53 -0600 Subject: [PATCH] use fs_extra to recursively move folders (#2487) --- Cargo.lock | 7 ++++++ crates/nu-cli/Cargo.toml | 1 + crates/nu-cli/src/shell/filesystem_shell.rs | 28 +++++++++++++++------ 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0fc87aff64..ac01c984a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1502,6 +1502,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "fs_extra" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" + [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -3032,6 +3038,7 @@ dependencies = [ "eml-parser", "encoding_rs", "filesize", + "fs_extra", "futures 0.3.5", "futures-util", "futures_codec", diff --git a/crates/nu-cli/Cargo.toml b/crates/nu-cli/Cargo.toml index fe706c247a..9042a13031 100644 --- a/crates/nu-cli/Cargo.toml +++ b/crates/nu-cli/Cargo.toml @@ -41,6 +41,7 @@ dtparse = "1.1.0" dunce = "1.0.1" eml-parser = "0.1.0" filesize = "0.2.0" +fs_extra = "1.2.0" futures = {version = "0.3", features = ["compat", "io-compat"]} futures-util = "0.3.5" futures_codec = "0.4" diff --git a/crates/nu-cli/src/shell/filesystem_shell.rs b/crates/nu-cli/src/shell/filesystem_shell.rs index cdd5f73e8b..ec4d755515 100644 --- a/crates/nu-cli/src/shell/filesystem_shell.rs +++ b/crates/nu-cli/src/shell/filesystem_shell.rs @@ -751,17 +751,31 @@ fn move_file(from: TaggedPathBuf, to: TaggedPathBuf) -> Result<(), ShellError> { to.push(from_file_name); } + move_item(&from, from_tag, &to) +} + +fn move_item(from: &Path, from_tag: &Tag, to: &Path) -> Result<(), ShellError> { // We first try a rename, which is a quick operation. If that doesn't work, we'll try a copy - // and remove the old file. This is necessary if we're moving across filesystems. - std::fs::rename(&from, &to) - .or_else(|_| std::fs::copy(&from, &to).and_then(|_| std::fs::remove_file(&from))) - .map_err(|e| { - ShellError::labeled_error( + // and remove the old file/folder. This is necessary if we're moving across filesystems or devices. + std::fs::rename(&from, &to).or_else(|_| { + match if from.is_file() { + let mut options = fs_extra::file::CopyOptions::new(); + options.overwrite = true; + fs_extra::file::move_file(from, to, &options) + } else { + let mut options = fs_extra::dir::CopyOptions::new(); + options.overwrite = true; + options.copy_inside = true; + fs_extra::dir::move_dir(from, to, &options) + } { + Ok(_) => Ok(()), + Err(e) => Err(ShellError::labeled_error( format!("Could not move {:?} to {:?}. {:}", from, to, e.to_string()), "could not move", from_tag, - ) - }) + )), + } + }) } fn is_empty_dir(dir: impl AsRef) -> bool {