Add a way to import ssh host names from the ssh config (#30926)
Closes https://github.com/zed-industries/zed/issues/20016 Use `"read_ssh_config": false` to disable the new behavior. Release Notes: - Added a way to import ssh host names from the ssh config --------- Co-authored-by: Cole Miller <m@cole-miller.net>
This commit is contained in:
parent
e468f9d2da
commit
83afe56a61
6 changed files with 419 additions and 78 deletions
96
crates/recent_projects/src/ssh_config.rs
Normal file
96
crates/recent_projects/src/ssh_config.rs
Normal file
|
@ -0,0 +1,96 @@
|
|||
use std::collections::BTreeSet;
|
||||
|
||||
pub fn parse_ssh_config_hosts(config: &str) -> BTreeSet<String> {
|
||||
let mut hosts = BTreeSet::new();
|
||||
let mut needs_another_line = false;
|
||||
for line in config.lines() {
|
||||
let line = line.trim_start();
|
||||
if let Some(line) = line.strip_prefix("Host") {
|
||||
match line.chars().next() {
|
||||
Some('\\') => {
|
||||
needs_another_line = true;
|
||||
}
|
||||
Some('\n' | '\r') => {
|
||||
needs_another_line = false;
|
||||
}
|
||||
Some(c) if c.is_whitespace() => {
|
||||
parse_hosts_from(line, &mut hosts);
|
||||
}
|
||||
Some(_) | None => {
|
||||
needs_another_line = false;
|
||||
}
|
||||
};
|
||||
|
||||
if needs_another_line {
|
||||
parse_hosts_from(line, &mut hosts);
|
||||
needs_another_line = line.trim_end().ends_with('\\');
|
||||
} else {
|
||||
needs_another_line = false;
|
||||
}
|
||||
} else if needs_another_line {
|
||||
needs_another_line = line.trim_end().ends_with('\\');
|
||||
parse_hosts_from(line, &mut hosts);
|
||||
} else {
|
||||
needs_another_line = false;
|
||||
}
|
||||
}
|
||||
|
||||
hosts
|
||||
}
|
||||
|
||||
fn parse_hosts_from(line: &str, hosts: &mut BTreeSet<String>) {
|
||||
hosts.extend(
|
||||
line.split_whitespace()
|
||||
.filter(|field| !field.starts_with("!"))
|
||||
.filter(|field| !field.contains("*"))
|
||||
.filter(|field| !field.is_empty())
|
||||
.map(|field| field.to_owned()),
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_thank_you_bjorn3() {
|
||||
let hosts = "
|
||||
Host *
|
||||
AddKeysToAgent yes
|
||||
UseKeychain yes
|
||||
IdentityFile ~/.ssh/id_ed25519
|
||||
|
||||
Host whatever.*
|
||||
User another
|
||||
|
||||
Host !not_this
|
||||
User not_me
|
||||
|
||||
Host something
|
||||
HostName whatever.tld
|
||||
|
||||
Host linux bsd host3
|
||||
User bjorn
|
||||
|
||||
Host rpi
|
||||
user rpi
|
||||
hostname rpi.local
|
||||
|
||||
Host \
|
||||
somehost \
|
||||
anotherhost
|
||||
Hostname 192.168.3.3";
|
||||
|
||||
let expected_hosts = BTreeSet::from_iter([
|
||||
"something".to_owned(),
|
||||
"linux".to_owned(),
|
||||
"host3".to_owned(),
|
||||
"bsd".to_owned(),
|
||||
"rpi".to_owned(),
|
||||
"somehost".to_owned(),
|
||||
"anotherhost".to_owned(),
|
||||
]);
|
||||
|
||||
assert_eq!(expected_hosts, parse_ssh_config_hosts(hosts));
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue