diff --git a/src/main.rs b/src/main.rs index 96c614c..b2ed947 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,7 +18,7 @@ use crate::os_string_builder::ReplaceWithOsStr; use crate::server::{RelativeLocalPathAnker, ServerAddress}; use crate::shell_interface::{ScpParam, ServerCommand, ShellCommand, ShellInterface}; use clap::{Parser, Subcommand, ValueEnum}; -use lazy_regex::{lazy_regex, Lazy, Regex}; +use lazy_regex::{Lazy, Regex, lazy_regex}; use server::{Server, ServerReference}; use std::cell::LazyCell; use std::ffi::OsString; @@ -486,23 +486,36 @@ where for file_action in server_actions.actions { match file_action.kind { Action::Add | Action::Replace => { - let source = match &file_server { - Some(file_server) => ScpParam::from(( - file_server, - file_server.server_directory_path.join(&file_action.file), - )), - None => ScpParam::from(file_action.file.as_path()), - }; - let destination = ScpParam::from((server, &server_actions.working_directory)); - scp! { - source, - destination, + //don't use scp on localhost + if file_server.is_none() && matches!(server.address, ServerAddress::Localhost) { + let file = file_action.file; + let dest = server_actions.working_directory.join(file_action.file_name); + fs::copy(&file, &dest).map_err(|e| { + format!( + "Failed to copy from {} to {}: {e}", + file.to_string_lossy(), + dest.to_string_lossy() + ) + })?; + } else { + let source = match &file_server { + Some(file_server) => ScpParam::from(( + file_server, + file_server.server_directory_path.join(&file_action.file), + )), + None => ScpParam::from(&file_action.file), + }; + let destination = ScpParam::from((server, &server_actions.working_directory)); + scp! { + source, + destination, + } + .in_env(env!()) + .run_logged(&logger) + .and_expect_success() + .into_result_with_error_logging(&logger) + .map_err(|e| format!("upload failure: {e}"))?; } - .in_env(env!()) - .run_logged(&logger) - .and_expect_success() - .into_result_with_error_logging(&logger) - .map_err(|e| format!("upload failure: {e}"))?; } Action::Delete => match &server.address { ServerAddress::Ssh { ssh_address } => { @@ -649,24 +662,34 @@ where for server in servers { log!(logger, "Getting file from {}...", server.get_name()); - let source = ScpParam::from((&server, server.server_directory_path.join(&file))); - scp! { - source: source.clone(), - destination: ScpParam::from(download_directory.as_path()), + let file_path = server.server_directory_path.join(&file); + let downloaded_file_path = download_directory.join(file_name); + if matches!(server.address, ServerAddress::Localhost) { + //no need to use scp on localhost + fs::copy(&file_path, &downloaded_file_path).map_err(|e| { + format!( + "failed to copy {} to {}: {e}", + file_path.to_string_lossy(), + downloaded_file_path.to_string_lossy() + ) + })?; + } else { + scp! { + source: ScpParam::from((&server, &file_path)), + destination: ScpParam::from(&download_directory), + } + .in_env(env!()) + .run_logged(&logger) + .and_expect_success() + .into_result_with_error_logging(&logger) + .map_err(|e| format!("download failure: {e}"))?; } - .in_env(env!()) - .run_logged(&logger) - .and_expect_success() - .into_result_with_error_logging(&logger) - .map_err(|e| format!("download failure: {e}"))?; //open file in editor let editor_command = shell_words::split(&editor) .map_err(|e| format!("failed to parse editor command: {e}"))? .into_iter() - .map(|part| { - part.replace_with_os_str(FILE_PLACEHOLDER, download_directory.join(file_name)) - }) + .map(|part| part.replace_with_os_str(FILE_PLACEHOLDER, &file_path)) .collect::>(); ShellCommand::Editor(editor_command) @@ -676,16 +699,26 @@ where .into_result_with_error_logging(&logger) .map_err(|e| format!("failed to open file in editor: {e}"))?; - //upload file again - scp! { - source: ScpParam::from(download_directory.join(file_name).as_path()), - destination: source, + //upload file again; don't use scp on localhost + if matches!(server.address, ServerAddress::Localhost) { + fs::copy(&downloaded_file_path, &file_path).map_err(|e| { + format!( + "failed to copy {} to {}: {e}", + file_path.to_string_lossy(), + download_directory.to_string_lossy() + ) + })?; + } else { + scp! { + source: ScpParam::from(&downloaded_file_path), + destination: ScpParam::from((&server, &file_path)), + } + .in_env(env!()) + .run_logged(&logger) + .and_expect_success() + .into_result_with_error_logging(&logger) + .map_err(|e| format!("failed to re-upload file: {e}"))?; } - .in_env(env!()) - .run_logged(&logger) - .and_expect_success() - .into_result_with_error_logging(&logger) - .map_err(|e| format!("failed to re-upload file: {e}"))?; } log!(logger, "Done!"); diff --git a/src/shell_interface.rs b/src/shell_interface.rs index 7407a69..d2a19c1 100644 --- a/src/shell_interface.rs +++ b/src/shell_interface.rs @@ -129,6 +129,12 @@ impl From<&Path> for ScpParam { } } +impl From<&PathBuf> for ScpParam { + fn from(value: &PathBuf) -> Self { + Self::from(value.as_path()) + } +} + impl From<&ScpParam> for OsString { fn from(value: &ScpParam) -> Self { let mut builder = osf!();