Skip to main content

git_claw/workflow/
shell.rs

1//! Shell integration workflow (`git claw shell-hook`).
2//!
3//! Emits shell wrapper functions for bash and zsh enabling automatic directory
4//! navigation (`cd`) upon worktree creation and switching.
5
6use crate::workflow::error::WorkflowError;
7
8/// Options for shell hook generation.
9pub struct ShellHookOptions<'a> {
10    pub shell: &'a str,
11}
12
13/// Generates the shell hook script for the specified shell.
14///
15/// # Example
16///
17/// ```
18/// use git_claw::workflow::shell::generate_shell_hook;
19///
20/// let script = generate_shell_hook("bash");
21/// assert!(script.contains("claw()"));
22/// assert!(script.contains("command git-claw"));
23/// ```
24pub fn generate_shell_hook(_shell: &str) -> String {
25    r#"# git-claw shell integration for bash and zsh
26# Usage: eval "$(git claw shell-hook)" or eval "$(git-claw shell-hook)"
27
28claw() {
29    if [ "$1" = "cd" ]; then
30        local dest
31        dest="$(command git-claw cd "$2")" || return $?
32        if [ -n "$dest" ]; then
33            cd "$dest" || return $?
34        fi
35    elif [ "$2" = "start" ] && { [ "$1" = "feature" ] || [ "$1" = "bugfix" ] || [ "$1" = "hotfix" ] || [ "$1" = "spike" ]; }; then
36        local target_name="$3"
37        for arg in "$@"; do
38            case "$arg" in
39                feature|bugfix|hotfix|spike|start|--*) ;;
40                *) target_name="$arg"; break ;;
41            esac
42        done
43        command git-claw "$@" || return $?
44        if [ -n "$target_name" ]; then
45            local dest
46            dest="$(command git-claw cd "$target_name")" || return $?
47            if [ -n "$dest" ]; then
48                cd "$dest" || return $?
49            fi
50        fi
51    else
52        command git-claw "$@"
53    fi
54}
55
56git() {
57    if [ "$1" = "claw" ]; then
58        shift
59        claw "$@"
60    else
61        command git "$@"
62    fi
63}
64"#
65    .to_string()
66}
67
68/// Runs the shell hook workflow, outputting the wrapper script to stdout.
69///
70/// # Example
71///
72/// ```
73/// use git_claw::workflow::shell::{run_shell_hook, ShellHookOptions};
74///
75/// let res = run_shell_hook(ShellHookOptions { shell: "bash" });
76/// assert!(res.is_ok());
77/// ```
78pub fn run_shell_hook(options: ShellHookOptions) -> Result<(), WorkflowError> {
79    let script = generate_shell_hook(options.shell);
80    print!("{}", script);
81    Ok(())
82}