Add relative local path ankers, when parsing servers

This commit is contained in:
Leonard Steppy 2025-02-03 00:29:23 +01:00
parent f2f7f3bae9
commit da2b6097e9
2 changed files with 31 additions and 14 deletions

View File

@ -10,7 +10,7 @@ use crate::command::{ExecutionError, LogRunnable, SpecificExecutionError};
use crate::file::{FileMatcher, FileNameInfo}; use crate::file::{FileMatcher, FileNameInfo};
use crate::logger::{LogLevel, Logger}; use crate::logger::{LogLevel, Logger};
use crate::os_string_builder::ReplaceWithOsStr; use crate::os_string_builder::ReplaceWithOsStr;
use crate::server::ServerAddress; use crate::server::{RelativeLocalPathAnker, ServerAddress};
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};
@ -614,7 +614,7 @@ fn parse_server_configuration(config_str: &str) -> Result<Vec<Server>, String> {
config_str config_str
.split(',') .split(',')
.map(|server_entry| { .map(|server_entry| {
Server::from_str(server_entry) Server::from_str(server_entry, RelativeLocalPathAnker::Home)
.map_err(|e| format!("Invalid server entry '{server_entry}': {e}")) .map_err(|e| format!("Invalid server entry '{server_entry}': {e}"))
}) })
.collect() .collect()

View File

@ -2,6 +2,7 @@ use crate::get_home_directory;
use std::cell::LazyCell; use std::cell::LazyCell;
use std::error::Error; use std::error::Error;
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::fs;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::ops::Deref; use std::ops::Deref;
use std::path::PathBuf; use std::path::PathBuf;
@ -71,7 +72,7 @@ impl FromStr for ServerReference {
type Err = ServerReferenceParseError; type Err = ServerReferenceParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
Server::from_str(s) Server::from_str(s, RelativeLocalPathAnker::CurrentDirectory)
.map(Self::Resolved) .map(Self::Resolved)
.or_else(|_| Ok(Self::Identifier(s.to_string()))) .or_else(|_| Ok(Self::Identifier(s.to_string())))
} }
@ -124,22 +125,28 @@ impl Server {
ServerAddress::Localhost => "this computer", ServerAddress::Localhost => "this computer",
} }
} }
}
impl FromStr for Server { pub fn from_str(
type Err = ServerParseError; s: &str,
relative_local_path_anker: RelativeLocalPathAnker,
fn from_str(s: &str) -> Result<Self, Self::Err> { ) -> Result<Self, ServerParseError> {
s.split_once(':') s.split_once(':')
.ok_or(ServerParseError::MissingServerDirectory) .ok_or(ServerParseError::MissingServerDirectory)
.and_then(|(identifier, server_directory)| { .and_then(|(identifier, server_directory)| {
let address = ServerAddress::from_str(identifier); let address = ServerAddress::from_str(identifier);
let mut server_directory_path = PathBuf::from(server_directory); let server_directory_path = match &address {
if let ServerAddress::Localhost = &address { ServerAddress::Ssh { .. } => PathBuf::from(server_directory),
let home_directory = get_home_directory() ServerAddress::Localhost => fs::canonicalize(match relative_local_path_anker {
.map_err(|e| ServerParseError::HomeDirectoryRequired { detail_message: e })?; RelativeLocalPathAnker::Home => {
server_directory_path = home_directory.join(&server_directory_path); let home_directory = get_home_directory()
} .map_err(|e| ServerParseError::HomeDirectoryRequired { detail_message: e })?;
home_directory.join(server_directory)
}
RelativeLocalPathAnker::CurrentDirectory => PathBuf::from(server_directory),
})
.map_err(|_| ServerParseError::ServerDirectoryNonExistent)?,
};
Ok(Self { Ok(Self {
address, address,
server_directory_path, server_directory_path,
@ -162,6 +169,12 @@ impl Display for Server {
} }
} }
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub enum RelativeLocalPathAnker {
Home,
CurrentDirectory,
}
#[derive(Debug, Clone, Eq, PartialEq, Hash)] #[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub enum ServerAddress { pub enum ServerAddress {
Ssh { ssh_address: String }, Ssh { ssh_address: String },
@ -201,6 +214,7 @@ impl ServerAddress {
#[derive(Debug)] #[derive(Debug)]
pub enum ServerParseError { pub enum ServerParseError {
MissingServerDirectory, MissingServerDirectory,
ServerDirectoryNonExistent,
HomeDirectoryRequired { detail_message: String }, HomeDirectoryRequired { detail_message: String },
} }
@ -218,6 +232,9 @@ impl Display for ServerParseError {
f, f,
"localhost requires home directory, but: {detail_message}" "localhost requires home directory, but: {detail_message}"
), ),
ServerParseError::ServerDirectoryNonExistent => {
write!(f, "The specified server directory doesn't exist")
}
} }
} }
} }