Don't use scp on localhost

This commit is contained in:
Leonard Steppy 2026-08-31 21:27:06 +02:00
parent a4d7fd7506
commit ffc3c478d9
2 changed files with 77 additions and 38 deletions

View File

@ -18,7 +18,7 @@ use crate::os_string_builder::ReplaceWithOsStr;
use crate::server::{RelativeLocalPathAnker, ServerAddress}; use crate::server::{RelativeLocalPathAnker, ServerAddress};
use crate::shell_interface::{ScpParam, ServerCommand, ShellCommand, ShellInterface}; use crate::shell_interface::{ScpParam, ServerCommand, ShellCommand, ShellInterface};
use clap::{Parser, Subcommand, ValueEnum}; use clap::{Parser, Subcommand, ValueEnum};
use lazy_regex::{lazy_regex, Lazy, Regex}; use lazy_regex::{Lazy, Regex, lazy_regex};
use server::{Server, ServerReference}; use server::{Server, ServerReference};
use std::cell::LazyCell; use std::cell::LazyCell;
use std::ffi::OsString; use std::ffi::OsString;
@ -486,23 +486,36 @@ where
for file_action in server_actions.actions { for file_action in server_actions.actions {
match file_action.kind { match file_action.kind {
Action::Add | Action::Replace => { Action::Add | Action::Replace => {
let source = match &file_server { //don't use scp on localhost
Some(file_server) => ScpParam::from(( if file_server.is_none() && matches!(server.address, ServerAddress::Localhost) {
file_server, let file = file_action.file;
file_server.server_directory_path.join(&file_action.file), let dest = server_actions.working_directory.join(file_action.file_name);
)), fs::copy(&file, &dest).map_err(|e| {
None => ScpParam::from(file_action.file.as_path()), format!(
}; "Failed to copy from {} to {}: {e}",
let destination = ScpParam::from((server, &server_actions.working_directory)); file.to_string_lossy(),
scp! { dest.to_string_lossy()
source, )
destination, })?;
} 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 { Action::Delete => match &server.address {
ServerAddress::Ssh { ssh_address } => { ServerAddress::Ssh { ssh_address } => {
@ -649,24 +662,34 @@ where
for server in servers { for server in servers {
log!(logger, "Getting file from {}...", server.get_name()); log!(logger, "Getting file from {}...", server.get_name());
let source = ScpParam::from((&server, server.server_directory_path.join(&file))); let file_path = server.server_directory_path.join(&file);
scp! { let downloaded_file_path = download_directory.join(file_name);
source: source.clone(), if matches!(server.address, ServerAddress::Localhost) {
destination: ScpParam::from(download_directory.as_path()), //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 //open file in editor
let editor_command = shell_words::split(&editor) let editor_command = shell_words::split(&editor)
.map_err(|e| format!("failed to parse editor command: {e}"))? .map_err(|e| format!("failed to parse editor command: {e}"))?
.into_iter() .into_iter()
.map(|part| { .map(|part| part.replace_with_os_str(FILE_PLACEHOLDER, &file_path))
part.replace_with_os_str(FILE_PLACEHOLDER, download_directory.join(file_name))
})
.collect::<Vec<_>>(); .collect::<Vec<_>>();
ShellCommand::Editor(editor_command) ShellCommand::Editor(editor_command)
@ -676,16 +699,26 @@ where
.into_result_with_error_logging(&logger) .into_result_with_error_logging(&logger)
.map_err(|e| format!("failed to open file in editor: {e}"))?; .map_err(|e| format!("failed to open file in editor: {e}"))?;
//upload file again //upload file again; don't use scp on localhost
scp! { if matches!(server.address, ServerAddress::Localhost) {
source: ScpParam::from(download_directory.join(file_name).as_path()), fs::copy(&downloaded_file_path, &file_path).map_err(|e| {
destination: source, 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!"); log!(logger, "Done!");

View File

@ -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 { impl From<&ScpParam> for OsString {
fn from(value: &ScpParam) -> Self { fn from(value: &ScpParam) -> Self {
let mut builder = osf!(); let mut builder = osf!();