sync_rs/
sync.rs

1use anyhow::{Context, Result};
2use std::process::Command;
3
4pub fn get_remote_home(remote_host: &str) -> Result<String> {
5    let output = Command::new("ssh")
6        .arg(remote_host)
7        .arg("echo $HOME")
8        .output()
9        .context("Failed to get remote home directory")?;
10
11    if !output.status.success() {
12        anyhow::bail!(
13            "SSH command failed: {}",
14            String::from_utf8_lossy(&output.stderr)
15        );
16    }
17
18    let home = String::from_utf8(output.stdout)?.trim().to_string();
19
20    if home.is_empty() {
21        anyhow::bail!("Remote home directory is empty");
22    }
23
24    Ok(home)
25}
26
27pub fn sync_directory(
28    source: &str,
29    destination: &str,
30    filter: Option<&str>,
31    delete: bool,
32) -> Result<()> {
33    let mut cmd = Command::new("rsync");
34    cmd.args(["-azP"]);
35
36    if delete {
37        cmd.args(["--delete"]);
38    }
39
40    if let Some(f) = filter {
41        // Handle multiple filters separated by commas
42        for filter_rule in f.split(',') {
43            cmd.args(["--filter", filter_rule.trim()]);
44        }
45    }
46
47    cmd.args([source, destination]);
48
49    let status = cmd.status().context("Failed to execute rsync command")?;
50
51    if !status.success() {
52        anyhow::bail!("rsync failed with exit code: {:?}", status.code());
53    }
54
55    Ok(())
56}
57
58pub fn execute_ssh_command(host: &str, command: &str) -> Result<()> {
59    let status = Command::new("ssh")
60        .arg(host)
61        .arg(command)
62        .status()
63        .context("Failed to execute SSH command")?;
64
65    if !status.success() {
66        anyhow::bail!("SSH command failed with exit code: {:?}", status.code());
67    }
68
69    Ok(())
70}
71
72pub fn open_remote_shell(host: &str, directory: &str) -> Result<()> {
73    let status = Command::new("ssh")
74        .arg("-t") // Force pseudo-terminal allocation for interactive shell
75        .arg(host)
76        .arg(format!("cd {} && exec $SHELL -l", directory))
77        .status()
78        .context("Failed to open remote shell")?;
79
80    if !status.success() {
81        anyhow::bail!("Remote shell exited with code: {:?}", status.code());
82    }
83
84    Ok(())
85}