Add OsStringBuilder and remove debug usages
This commit is contained in:
parent
28bdcb41aa
commit
435c87c958
62
src/main.rs
62
src/main.rs
@ -1,5 +1,6 @@
|
|||||||
mod action;
|
mod action;
|
||||||
mod file;
|
mod file;
|
||||||
|
mod os_string_builder;
|
||||||
mod server;
|
mod server;
|
||||||
|
|
||||||
use crate::action::{Action, FileAction, ServerActions};
|
use crate::action::{Action, FileAction, ServerActions};
|
||||||
@ -9,7 +10,6 @@ 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::env;
|
use std::env;
|
||||||
use std::ffi::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;
|
||||||
@ -119,13 +119,9 @@ fn main() -> Result<(), String> {
|
|||||||
Ok(ServerActions {
|
Ok(ServerActions {
|
||||||
server,
|
server,
|
||||||
actions: {
|
actions: {
|
||||||
//TODO don't use debug values here, use joiner
|
|
||||||
let output = ShellCmd::new("ssh")
|
let output = ShellCmd::new("ssh")
|
||||||
.arg(&server.ssh_name)
|
.arg(&server.ssh_name)
|
||||||
.arg(format!(
|
.arg(osf!("ls ") + server.server_directory_path.join(&upload_directory))
|
||||||
"cd {:?}; ls {:?}",
|
|
||||||
server.server_directory_path, upload_directory
|
|
||||||
))
|
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.output()
|
.output()
|
||||||
.map_err(|e| format!("failed to query files via ssh: {e}"))?;
|
.map_err(|e| format!("failed to query files via ssh: {e}"))?;
|
||||||
@ -206,47 +202,43 @@ fn main() -> Result<(), String> {
|
|||||||
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 => {
|
||||||
//TODO replace with joiner
|
|
||||||
let mut destination = OsString::from(&server.ssh_name);
|
|
||||||
destination.push(":");
|
|
||||||
destination.push(&server.server_directory_path);
|
|
||||||
if !server
|
|
||||||
.server_directory_path
|
|
||||||
.to_string_lossy()
|
|
||||||
.ends_with("/")
|
|
||||||
{
|
|
||||||
destination.push("/");
|
|
||||||
}
|
|
||||||
destination.push(&upload_directory);
|
|
||||||
ShellCmd::new("scp")
|
ShellCmd::new("scp")
|
||||||
.arg(file.clone())
|
.arg(file.clone())
|
||||||
.arg(destination)
|
.arg(
|
||||||
|
osf!(&server.ssh_name)
|
||||||
|
+ ":"
|
||||||
|
+ server.server_directory_path.join(&upload_directory),
|
||||||
|
)
|
||||||
.spawn()
|
.spawn()
|
||||||
.map_err(|e| format!("failed to upload file: {e}"))?
|
.map_err(|e| format!("failed to upload file: {e}"))?
|
||||||
.wait()
|
.wait()
|
||||||
.map_err(|e| format!("failed to wait for upload: {e}"))?;
|
.map_err(|e| format!("failed to wait for upload: {e}"))?;
|
||||||
}
|
}
|
||||||
Action::Delete => {
|
Action::Delete => {
|
||||||
//TODO don't use debug values here, use joiner
|
|
||||||
ShellCmd::new("ssh")
|
ShellCmd::new("ssh")
|
||||||
.arg(&server.ssh_name)
|
.arg(&server.ssh_name)
|
||||||
.arg(format!(
|
.arg(
|
||||||
"cd {:?}; cd {upload_directory:?}; rm {:?}",
|
osf!("cd ")
|
||||||
server.server_directory_path, file_action.file
|
+ server.server_directory_path.join(&upload_directory)
|
||||||
))
|
+ "; rm "
|
||||||
|
+ &file_action.file,
|
||||||
|
)
|
||||||
.spawn()
|
.spawn()
|
||||||
.map_err(|e| format!("failed to send delete command: {e}"))?
|
.map_err(|e| format!("failed to send delete command: {e}"))?
|
||||||
.wait()
|
.wait()
|
||||||
.map_err(|e| format!("failed to wait for delete command: {e}"))?;
|
.map_err(|e| format!("failed to wait for delete command: {e}"))?;
|
||||||
}
|
}
|
||||||
Action::Rename { new_name } => {
|
Action::Rename { new_name } => {
|
||||||
//TODO don't use debug values, use joiner
|
|
||||||
ShellCmd::new("ssh")
|
ShellCmd::new("ssh")
|
||||||
.arg(&server.ssh_name)
|
.arg(&server.ssh_name)
|
||||||
.arg(format!(
|
.arg(
|
||||||
"cd {:?}; cd {upload_directory:?}; mv {:?} {new_name:?}",
|
osf!("cd ")
|
||||||
server.server_directory_path, file_action.file
|
+ server.server_directory_path.join(&upload_directory)
|
||||||
))
|
+ "; mv "
|
||||||
|
+ &file_action.file
|
||||||
|
+ " "
|
||||||
|
+ new_name,
|
||||||
|
)
|
||||||
.spawn()
|
.spawn()
|
||||||
.map_err(|e| format!("failed to send rename command: {e}"))?
|
.map_err(|e| format!("failed to send rename command: {e}"))?
|
||||||
.wait()
|
.wait()
|
||||||
@ -262,10 +254,9 @@ fn main() -> Result<(), String> {
|
|||||||
start_ssh_agent()?;
|
start_ssh_agent()?;
|
||||||
for server in servers {
|
for server in servers {
|
||||||
println!("Running command on '{}'...", server.ssh_name);
|
println!("Running command on '{}'...", server.ssh_name);
|
||||||
//TODO don't use debug values, use joiner
|
|
||||||
ShellCmd::new("ssh")
|
ShellCmd::new("ssh")
|
||||||
.arg(server.ssh_name)
|
.arg(server.ssh_name)
|
||||||
.arg(format!("cd {:?}; {command}", server.server_directory_path))
|
.arg(osf!("cd ") + server.server_directory_path + "; " + &command)
|
||||||
.spawn()
|
.spawn()
|
||||||
.map_err(|_| "failed to start ssh command".to_string())?
|
.map_err(|_| "failed to start ssh command".to_string())?
|
||||||
.wait()
|
.wait()
|
||||||
@ -343,4 +334,13 @@ mod test {
|
|||||||
servers
|
servers
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn path_experiment() {
|
||||||
|
let server_dir = PathBuf::from("steptech");
|
||||||
|
let upload_dir = PathBuf::from("/home"); //absolute path
|
||||||
|
|
||||||
|
let joined = server_dir.join(upload_dir);
|
||||||
|
assert_eq!(PathBuf::from("/home"), joined);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
121
src/os_string_builder.rs
Normal file
121
src/os_string_builder.rs
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
use std::ffi::{OsStr, OsString};
|
||||||
|
use std::fmt::{Debug, Formatter};
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
|
use std::ops::{Add, AddAssign};
|
||||||
|
use std::os::unix::ffi::OsStrExt;
|
||||||
|
|
||||||
|
#[derive(Clone, Default, Eq)]
|
||||||
|
pub struct OsStringBuilder {
|
||||||
|
result: OsString,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OsStringBuilder {
|
||||||
|
pub fn from(s: impl AsRef<OsStr>) -> Self {
|
||||||
|
Self {
|
||||||
|
result: s.as_ref().to_os_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build(&self) -> OsString {
|
||||||
|
self.result.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<OsStringBuilder> for OsString {
|
||||||
|
fn from(value: OsStringBuilder) -> Self {
|
||||||
|
value.result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for OsStringBuilder {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
Debug::fmt(&self.result, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRef<OsStr> for OsStringBuilder {
|
||||||
|
fn as_ref(&self) -> &OsStr {
|
||||||
|
self.result.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P> Add<P> for OsStringBuilder
|
||||||
|
where
|
||||||
|
P: AsRef<OsStr>,
|
||||||
|
{
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn add(mut self, rhs: P) -> Self::Output {
|
||||||
|
self.result.push(rhs);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P> AddAssign<P> for OsStringBuilder
|
||||||
|
where
|
||||||
|
P: AsRef<OsStr>,
|
||||||
|
{
|
||||||
|
fn add_assign(&mut self, rhs: P) {
|
||||||
|
self.result.push(rhs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P> PartialEq<P> for OsStringBuilder
|
||||||
|
where
|
||||||
|
P: AsRef<OsStr>,
|
||||||
|
{
|
||||||
|
fn eq(&self, other: &P) -> bool {
|
||||||
|
self.result == other.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hash for OsStringBuilder {
|
||||||
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
|
self.result.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ensure_trailing_slash(path: impl AsRef<OsStr>) -> OsString {
|
||||||
|
let mut str = path.as_ref().to_os_string();
|
||||||
|
if !str.as_bytes().ends_with(b"/") {
|
||||||
|
str.push("/")
|
||||||
|
}
|
||||||
|
str
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! dir {
|
||||||
|
($path:expr) => {{
|
||||||
|
use $crate::os_string_builder::ensure_trailing_slash;
|
||||||
|
ensure_trailing_slash($path)
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! osf {
|
||||||
|
() => {{
|
||||||
|
use $crate::os_string_builder::OsStringBuilder;
|
||||||
|
OsStringBuilder::default()
|
||||||
|
}};
|
||||||
|
($s:expr) => {
|
||||||
|
osf!() + $s
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_build() {
|
||||||
|
assert_eq!(osf!("foo") + "Bar", "fooBar");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_add_dir() {
|
||||||
|
let foo = PathBuf::from("foo");
|
||||||
|
let bar = PathBuf::from("bar");
|
||||||
|
|
||||||
|
assert_eq!(osf!("cd ") + dir!(foo) + dir!(bar), "cd foo/bar/");
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user