use anyhow::Result;
use std::path::PathBuf;
use crate::node::Node;
use crate::pty::should_allocate_pty;
use super::types::InteractiveCommand;
impl InteractiveCommand {
pub(super) fn should_use_pty(&self) -> Result<bool> {
match self.use_pty {
Some(true) => Ok(true), Some(false) => Ok(false), None => {
let mut pty_config = self.pty_config.clone();
pty_config.force_pty = self.use_pty == Some(true);
pty_config.disable_pty = self.use_pty == Some(false);
should_allocate_pty(&pty_config)
}
}
}
pub(super) fn format_prompt(&self, node: &Node, working_dir: &str) -> String {
self.prompt_format
.replace("{node}", &format!("{}@{}", node.username, node.host))
.replace("{user}", &node.username)
.replace("{host}", &node.host)
.replace("{pwd}", working_dir)
}
pub(super) fn expand_path(&self, path: &std::path::Path) -> Result<PathBuf> {
if let Some(path_str) = path.to_str() {
if path_str.starts_with('~') {
if let Some(home) = dirs::home_dir() {
if path_str == "~" {
return Ok(home);
} else if let Some(rest) = path_str.strip_prefix("~/") {
return Ok(home.join(rest));
}
}
}
}
Ok(path.to_path_buf())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::config::{Config, InteractiveConfig};
use crate::pty::PtyConfig;
use crate::ssh::known_hosts::StrictHostKeyChecking;
#[test]
fn test_expand_path_with_tilde() {
let cmd = InteractiveCommand {
single_node: false,
multiplex: true,
prompt_format: String::from(""),
history_file: PathBuf::from("~/.bssh_history"),
work_dir: None,
nodes: vec![],
config: Config::default(),
interactive_config: InteractiveConfig::default(),
cluster_name: None,
key_path: None,
use_agent: false,
use_password: false,
#[cfg(target_os = "macos")]
use_keychain: false,
strict_mode: StrictHostKeyChecking::AcceptNew,
jump_hosts: None,
pty_config: PtyConfig::default(),
use_pty: None,
};
let path = PathBuf::from("~/test/file.txt");
let expanded = cmd.expand_path(&path).unwrap();
if let Some(home) = dirs::home_dir() {
assert!(expanded.starts_with(&home));
assert!(expanded.to_str().unwrap().ends_with("test/file.txt"));
}
}
#[test]
fn test_format_prompt() {
let cmd = InteractiveCommand {
single_node: false,
multiplex: true,
prompt_format: String::from("[{node}:{user}@{host}:{pwd}]$ "),
history_file: PathBuf::from("~/.bssh_history"),
work_dir: None,
nodes: vec![],
config: Config::default(),
interactive_config: InteractiveConfig::default(),
cluster_name: None,
key_path: None,
use_agent: false,
use_password: false,
#[cfg(target_os = "macos")]
use_keychain: false,
strict_mode: StrictHostKeyChecking::AcceptNew,
jump_hosts: None,
pty_config: PtyConfig::default(),
use_pty: None,
};
let node = Node::new(String::from("example.com"), 22, String::from("alice"));
let prompt = cmd.format_prompt(&node, "/home/alice");
assert_eq!(
prompt,
"[alice@example.com:alice@example.com:/home/alice]$ "
);
}
}