#![allow(clippy::print_stdout)]
use crate::cli::AliasCommand;
use crate::config;
use anyhow::Context;
pub fn run(cmd: AliasCommand) -> anyhow::Result<()> {
match cmd {
AliasCommand::List { hostname: _ } => list(),
AliasCommand::Set {
name,
command,
hostname: _,
} => set(&name, &command),
AliasCommand::Delete { name, hostname: _ } => delete(&name),
}
}
fn list() -> anyhow::Result<()> {
let config = config::load().context("failed to load config")?;
let aliases = config.global.get("aliases");
let Some(alias_map) = aliases.and_then(|v| v.as_mapping()) else {
println!("No aliases configured.");
return Ok(());
};
let name_width = 20;
println!("{:<name_width$} COMMAND", "ALIAS");
for (name, command) in alias_map {
let name_str = name.as_str().unwrap_or("?");
let cmd_str = command.as_str().unwrap_or("?");
let name_truncated = crate::cmd::util::truncate(name_str, name_width);
println!("{name_truncated:<name_width$} {cmd_str}");
}
Ok(())
}
fn set(name: &str, command: &[String]) -> anyhow::Result<()> {
if command.is_empty() {
anyhow::bail!("alias command is required");
}
let mut config = config::load().context("failed to load config")?;
let cmd_str = command.join(" ");
let mut aliases = config
.global
.get("aliases")
.and_then(|v| v.as_mapping().cloned())
.unwrap_or_default();
aliases.insert(
serde_yaml_ng::Value::String(name.to_string()),
serde_yaml_ng::Value::String(cmd_str.clone()),
);
config.global.insert(
"aliases".to_string(),
serde_yaml_ng::Value::Mapping(aliases),
);
config::save(&config).context("failed to save config")?;
println!("Alias '{name}' set to '{cmd_str}'");
Ok(())
}
fn delete(name: &str) -> anyhow::Result<()> {
let mut config = config::load().context("failed to load config")?;
let aliases = config
.global
.get("aliases")
.and_then(|v| v.as_mapping().cloned());
let Some(mut aliases) = aliases else {
println!("Alias '{name}' not found.");
return Ok(());
};
let key = serde_yaml_ng::Value::String(name.to_string());
if !aliases.contains_key(&key) {
println!("Alias '{name}' not found.");
return Ok(());
}
aliases.remove(&key);
config.global.insert(
"aliases".to_string(),
serde_yaml_ng::Value::Mapping(aliases),
);
config::save(&config).context("failed to save config")?;
println!("Alias '{name}' deleted.");
Ok(())
}
#[cfg(test)]
#[allow(clippy::expect_used)]
mod tests {
use super::*;
#[test]
fn set_requires_command() {
let result = std::panic::catch_unwind(|| {
let _ = set("test", &[]);
});
assert!(result.is_ok());
}
#[test]
fn delete_nonexistent_is_noop() {
let result = std::panic::catch_unwind(|| {
let _ = delete("nonexistent");
});
assert!(result.is_ok());
}
}