Canonicalize files to upload if they are on remote server
This commit is contained in:
parent
329ba8f381
commit
6e4a23254a
39
src/main.rs
39
src/main.rs
@ -15,9 +15,11 @@ 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::{OsStr, OsString};
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::iter::once;
|
use std::iter::once;
|
||||||
|
use std::os::unix::ffi::OsStrExt;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::{env, fs, io};
|
use std::{env, fs, io};
|
||||||
@ -178,7 +180,7 @@ fn main() -> Result<(), String> {
|
|||||||
|
|
||||||
match args.command {
|
match args.command {
|
||||||
Command::Upload {
|
Command::Upload {
|
||||||
files,
|
mut files,
|
||||||
file_server,
|
file_server,
|
||||||
old_version_policy,
|
old_version_policy,
|
||||||
mut upload_directory,
|
mut upload_directory,
|
||||||
@ -186,6 +188,7 @@ fn main() -> Result<(), String> {
|
|||||||
file_name,
|
file_name,
|
||||||
} => {
|
} => {
|
||||||
require_non_empty_servers(&servers)?;
|
require_non_empty_servers(&servers)?;
|
||||||
|
require_non_empty(&files, "files to upload")?;
|
||||||
start_ssh_agent(&logger)?;
|
start_ssh_agent(&logger)?;
|
||||||
|
|
||||||
//resolve file server
|
//resolve file server
|
||||||
@ -204,6 +207,25 @@ fn main() -> Result<(), String> {
|
|||||||
match &file_server {
|
match &file_server {
|
||||||
Some(file_server) => match &file_server.address {
|
Some(file_server) => match &file_server.address {
|
||||||
ServerAddress::Ssh { ssh_address } => {
|
ServerAddress::Ssh { ssh_address } => {
|
||||||
|
//canonicalize remote files
|
||||||
|
let joined_files = osf!("{{")
|
||||||
|
+ files
|
||||||
|
.iter()
|
||||||
|
.map(|file| file.as_os_str())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(&OsString::from(","))
|
||||||
|
+ "}";
|
||||||
|
let realpath_output = ShellCmd::new("ssh")
|
||||||
|
.arg(ssh_address)
|
||||||
|
.arg(osf!("realpath ") + file_server.server_directory_path.join(joined_files))
|
||||||
|
.collect_output()
|
||||||
|
.map_err(|e| format!("failed to canonicalize files to upload: {e}"))?;
|
||||||
|
files = realpath_output
|
||||||
|
.stdout
|
||||||
|
.split(|&b| b == b'\n') //split at line breaks
|
||||||
|
.map(|bytes| PathBuf::from(OsStr::from_bytes(bytes)))
|
||||||
|
.collect();
|
||||||
|
|
||||||
for file in &files {
|
for file in &files {
|
||||||
check_file_exists_on_server(file, ssh_address, &file_server.server_directory_path)?;
|
check_file_exists_on_server(file, ssh_address, &file_server.server_directory_path)?;
|
||||||
}
|
}
|
||||||
@ -580,12 +602,17 @@ fn get_home_directory() -> Result<PathBuf, String> {
|
|||||||
.and_then(|home_dir| home_dir.ok_or("Failed to find home directory".to_string()))
|
.and_then(|home_dir| home_dir.ok_or("Failed to find home directory".to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn require_non_empty_servers(servers: &[Server]) -> Result<(), String> {
|
fn require_non_empty_servers<T>(servers: &[T]) -> Result<(), String> {
|
||||||
if servers.is_empty() {
|
require_non_empty(servers, "servers for this operation")
|
||||||
Err("You did not provide any servers for this operation. Please see --help".to_string())
|
}
|
||||||
} else {
|
|
||||||
Ok(())
|
fn require_non_empty<T>(slice: &[T], slice_name: &str) -> Result<(), String> {
|
||||||
|
if slice.is_empty() {
|
||||||
|
Err(format!(
|
||||||
|
"You did not provide any {slice_name}. Please see --help"
|
||||||
|
))?
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_ssh_agent(logger: &Logger) -> Result<(), String> {
|
fn start_ssh_agent(logger: &Logger) -> Result<(), String> {
|
||||||
|
|||||||
@ -2,6 +2,7 @@ use std::ffi::{OsStr, OsString};
|
|||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::ops::{Add, AddAssign};
|
use std::ops::{Add, AddAssign};
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
pub trait ReplaceWithOsStr<'a, Pattern = &'a str> {
|
pub trait ReplaceWithOsStr<'a, Pattern = &'a str> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
@ -56,6 +57,12 @@ impl AsRef<OsStr> for OsStringBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AsRef<Path> for OsStringBuilder {
|
||||||
|
fn as_ref(&self) -> &Path {
|
||||||
|
self.result.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<P> Add<P> for OsStringBuilder
|
impl<P> Add<P> for OsStringBuilder
|
||||||
where
|
where
|
||||||
P: AsRef<OsStr>,
|
P: AsRef<OsStr>,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user