use clap::Parser;
static AFTER_HELP_TEXT: &str = concat!(
"Copyright (C) 2023 Andreas Hartmann <hartan@7x.de>
Licensed under the GNU General Public License v3.0+
Read the docs at: https://docs.rs/",
env!("CARGO_PKG_NAME"),
"/",
env!("CARGO_PKG_VERSION"),
"/",
env!("CARGO_PKG_NAME"),
"/"
);
#[derive(clap::ValueEnum, Debug, Clone)]
pub(crate) enum Hooks {
Bash,
Zsh,
Help,
}
#[derive(Parser, Debug)]
#[doc(hidden)]
#[command(
author,
version,
about,
after_help = AFTER_HELP_TEXT,
arg_required_else_help(true),
trailing_var_arg(true)
)]
pub struct Args {
#[arg(long, requires = "alias_target_env")]
pub(crate) alias_source_env: Option<String>,
#[arg(long)]
pub(crate) alias_target_env: Option<String>,
#[arg(long, requires = "alias_target_env")]
pub(crate) alias_privileged: bool,
#[arg(long, requires = "alias_target_env")]
pub(crate) alias_interactive: bool,
#[arg(long, value_enum, exclusive = true)]
pub(crate) hooks: Option<Hooks>,
#[arg(long, short, default_value_t = false)]
pub(crate) debug: bool,
#[arg(required = true)]
pub(crate) command: Vec<String>,
}
pub(crate) fn install_hook(hook: Hooks) {
let alias_path = crate::directories::get().aliases();
if matches!(hook, Hooks::Help) {
println!(
r#"
== Installing Shell Hooks ==
cnf on its own isn't nearly half as useful as it could be. To unleash its full
potential, you will likely want to install the hooks for your current shell.
The hooks perform the following tasks:
1. Ensure `cnf` is always called when your shell doesn't find a command, and
pass the command along with all its' arguments to `cnf` instead.
2. Extend your `$PATH` with the configured location for `cnf` command aliases
so aliases created through the UI are available to your shell.
3. Create the `sual` function alias which works like `sudo` but specifically to
execute command aliases. Regular `sudo` will not have the desired effect for
command aliases, so use `sual` instead.
To get started, run this command again, giving it either 'bash' or 'zsh' as
argument, depending on your current shell. Pass the generated output to `eval`
to update your current shells configuration temporarily. Add a snippet like
this:
eval "$(cnf --hooks <SHELL>)"
to your shell configuration (`~/.bashrc`, `~/.zshrc`, ...) to automatically
apply the configuration in new shell instances."#
);
return;
}
println!(
r#"
# Added by 'cnf'
if command -v "cnf" &>/dev/null; then
# pick up aliases from configured alias path
CNF_ALIASES="{alias_path}"
[[ "$PATH" != *"$CNF_ALIASES"* ]] && export PATH="$PATH:$CNF_ALIASES"
# automatically call cnf when a command isn't found in $PATH
function {function_name} {{
cnf "$@"
}}
function sual {{
{alias_privileged_env}=1 "$@"
}}
fi"#,
function_name = match hook {
Hooks::Zsh => "command_not_found_handler",
Hooks::Bash => "command_not_found_handle",
_ => unreachable!(),
},
alias_path = alias_path.display(),
alias_privileged_env = crate::Env::AliasPrivileged
);
}