use std::path::{Path, PathBuf};
use crate::config::Position;
use crate::context::SystemContext;
use crate::shell::{Shell, ShellKind};
pub struct Fish;
impl Shell for Fish {
fn kind(&self) -> ShellKind {
ShellKind::Fish
}
fn env_extension(&self) -> &'static str {
".fish"
}
fn env_script(&self, dir: &Path, position: Position) -> String {
let dir = dir.display();
let flag = match position {
Position::Prepend => "--prepend",
Position::Append => "--append",
};
format!(
r#"# Generated by onpath. Do not edit.
if not contains "{dir}" $PATH
fish_add_path {flag} "{dir}"
end
"#
)
}
fn source_line(&self, env_script_path: &Path) -> String {
format!("source \"{}\"", env_script_path.display())
}
fn rc_candidates(&self, ctx: &SystemContext) -> Vec<PathBuf> {
let config = ctx.xdg_config_home();
vec![
config.join("fish").join("conf.d"), config.join("fish").join("config.fish"),
]
}
fn primary_rc(&self, ctx: &SystemContext) -> PathBuf {
ctx.xdg_config_home().join("fish").join("config.fish")
}
}
#[cfg(any(not(windows), test))]
pub fn conf_d_path(ctx: &SystemContext, tool_name: &str) -> PathBuf {
ctx.xdg_config_home()
.join("fish")
.join("conf.d")
.join(format!("onpath-{tool_name}.fish"))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn env_script_uses_fish_add_path() {
let script = Fish.env_script(Path::new("/app/bin"), Position::Prepend);
assert!(script.contains("fish_add_path --prepend"));
assert!(script.contains("/app/bin"));
}
#[test]
fn env_script_append() {
let script = Fish.env_script(Path::new("/app/bin"), Position::Append);
assert!(script.contains("fish_add_path --append"));
}
#[test]
fn env_script_contains_guard() {
let script = Fish.env_script(Path::new("/app/bin"), Position::Prepend);
assert!(script.contains("if not contains"));
}
#[test]
fn source_line_uses_source_keyword() {
let line = Fish.source_line(Path::new("/home/user/.myapp/env.fish"));
assert_eq!(line, "source \"/home/user/.myapp/env.fish\"");
}
#[test]
fn conf_d_path_includes_tool_name() {
let ctx = SystemContext::with_home(PathBuf::from("/home/user"));
let path = conf_d_path(&ctx, "myapp");
assert_eq!(
path,
PathBuf::from("/home/user/.config/fish/conf.d/onpath-myapp.fish")
);
}
}