From 6e0072f029552ea9d5c0f9c0873518e7ab9dc3c7 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 11 May 2026 21:05:54 +0530 Subject: [PATCH 1/3] feat: detect existing install and skip completion prompt on rerun --- install.sh | 91 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 19 deletions(-) diff --git a/install.sh b/install.sh index deb242a..02330d5 100755 --- a/install.sh +++ b/install.sh @@ -68,6 +68,22 @@ esac step "Detected ${os}/${arch}" +# --------------------------------------------------------------------------- +# Detect existing install +# --------------------------------------------------------------------------- +existing_path="$INSTALL_DIR/$BINARY" +existing_version="" +if [ -x "$existing_path" ]; then + existing_version=$("$existing_path" --version 2>/dev/null | head -n1 | tr -d '[:space:]' || true) + case "$existing_version" in + v*|dev|"") ;; + *) existing_version="v$existing_version" ;; + esac + if [ -n "$existing_version" ]; then + step "Found existing ${BINARY} ${C_BOLD}${existing_version}${C_RESET}" + fi +fi + # --------------------------------------------------------------------------- # Resolve version (latest by default) # --------------------------------------------------------------------------- @@ -84,7 +100,16 @@ case "$VERSION" in esac ver_clean="${VERSION#v}" -step "Resolved version ${C_BOLD}${VERSION}${C_RESET}" +if [ -z "$existing_version" ]; then + install_mode=install + step "Resolved version ${C_BOLD}${VERSION}${C_RESET}" +elif [ "$existing_version" = "$VERSION" ]; then + install_mode=reinstall + step "Resolved version ${C_BOLD}${VERSION}${C_RESET} (already up to date — reinstalling)" +else + install_mode=update + step "Updating ${C_BOLD}${existing_version}${C_RESET} → ${C_BOLD}${VERSION}${C_RESET}" +fi # --------------------------------------------------------------------------- # Build URLs and download @@ -136,7 +161,11 @@ mkdir -p "$INSTALL_DIR" mv "$tmp/$BINARY" "$INSTALL_DIR/$BINARY" chmod +x "$INSTALL_DIR/$BINARY" -ok "Installed ${C_BOLD}${BINARY} ${VERSION}${C_RESET} to ${INSTALL_DIR}/${BINARY}" +case "$install_mode" in + reinstall) ok "Reinstalled ${C_BOLD}${BINARY} ${VERSION}${C_RESET} to ${INSTALL_DIR}/${BINARY}" ;; + update) ok "Updated ${C_BOLD}${BINARY}${C_RESET} ${existing_version} → ${C_BOLD}${VERSION}${C_RESET} at ${INSTALL_DIR}/${BINARY}" ;; + *) ok "Installed ${C_BOLD}${BINARY} ${VERSION}${C_RESET} to ${INSTALL_DIR}/${BINARY}" ;; +esac # --------------------------------------------------------------------------- # PATH hint @@ -160,7 +189,9 @@ esac # to the curl pipe — we read input from /dev/tty instead. print_next_steps() { printf '\n %sNext steps%s\n' "$C_BOLD" "$C_RESET" - printf ' %schatwoot auth login%s log in to your Chatwoot instance\n' "$C_CYAN" "$C_RESET" + if [ ! -f "$HOME/.chatwoot/config.yaml" ]; then + printf ' %schatwoot auth login%s log in to your Chatwoot instance\n' "$C_CYAN" "$C_RESET" + fi printf ' %schatwoot --help%s see all commands\n\n' "$C_CYAN" "$C_RESET" } @@ -180,6 +211,36 @@ case "${SHELL##*/}" in ;; esac +# Skip the prompt entirely if completion is already configured. +completion_configured=false +case "$shell_kind" in + bash) + completion_dir="${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion/completions" + completion_path="$completion_dir/$BINARY" + [ -f "$completion_path" ] && completion_configured=true + ;; + fish) + completion_dir="${XDG_CONFIG_HOME:-$HOME/.config}/fish/completions" + completion_path="$completion_dir/$BINARY.fish" + [ -f "$completion_path" ] && completion_configured=true + ;; + zsh) + rc="${ZDOTDIR:-$HOME}/.zshrc" + completion_path="$rc" + zsh_line="source <(\"$INSTALL_DIR/$BINARY\" completion zsh -c)" + if [ -f "$rc" ] && grep -Fq "$zsh_line" "$rc"; then + completion_configured=true + fi + ;; +esac + +if [ "$completion_configured" = true ]; then + printf '\n' + step "${shell_kind} completion already configured in ${completion_path} — skipping" + print_next_steps + exit 0 +fi + printf '\n %sSet up tab completion for %s?%s [Y/n] ' "$C_BOLD" "$shell_kind" "$C_RESET" if ! read -r response < /dev/tty; then echo @@ -196,26 +257,18 @@ esac case "$shell_kind" in bash) - dir="${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion/completions" - mkdir -p "$dir" - "$INSTALL_DIR/$BINARY" completion bash -c > "$dir/$BINARY" - ok "Added bash completion to ${dir}/${BINARY} — restart your shell to enable" + mkdir -p "$completion_dir" + "$INSTALL_DIR/$BINARY" completion bash -c > "$completion_path" + ok "Added bash completion to ${completion_path} — restart your shell to enable" ;; fish) - dir="${XDG_CONFIG_HOME:-$HOME/.config}/fish/completions" - mkdir -p "$dir" - "$INSTALL_DIR/$BINARY" completion fish -c > "$dir/$BINARY.fish" - ok "Added fish completion to ${dir}/${BINARY}.fish" + mkdir -p "$completion_dir" + "$INSTALL_DIR/$BINARY" completion fish -c > "$completion_path" + ok "Added fish completion to ${completion_path}" ;; zsh) - rc="${ZDOTDIR:-$HOME}/.zshrc" - line="source <(\"$INSTALL_DIR/$BINARY\" completion zsh -c)" - if [ -f "$rc" ] && grep -Fq "$line" "$rc"; then - step "zsh completion already present in ${rc}" - else - printf '\n# chatwoot CLI completion\n%s\n' "$line" >> "$rc" - ok "Added zsh completion to ${rc} — restart your shell to enable" - fi + printf '\n# chatwoot CLI completion\n%s\n' "$zsh_line" >> "$rc" + ok "Added zsh completion to ${rc} — restart your shell to enable" ;; esac From b37a3e3a5933ad36e2d1c65dbd2c8e31c9384689 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 11 May 2026 21:12:15 +0530 Subject: [PATCH 2/3] refactor: add a has command --- install.sh | 94 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 66 insertions(+), 28 deletions(-) diff --git a/install.sh b/install.sh index 02330d5..477eac2 100755 --- a/install.sh +++ b/install.sh @@ -36,6 +36,7 @@ step() { printf ' %s→%s %s\n' "$C_CYAN" "$C_RESET" "$*"; } ok() { printf ' %s✓%s %s\n' "$C_GREEN" "$C_RESET" "$*"; } warn() { printf ' %s!%s %s\n' "$C_YELLOW" "$C_RESET" "$*"; } err() { printf ' %s✗%s %s\n' "$C_RED" "$C_RESET" "$*" >&2; exit 1; } +has() { command -v "$1" >/dev/null 2>&1; } banner() { [ -t 1 ] || return 0 @@ -132,9 +133,9 @@ fi if curl -fsSL "$checksum_url" -o "$tmp/checksums.txt" 2>/dev/null; then expected=$(grep " ${asset}\$" "$tmp/checksums.txt" | awk '{print $1}') if [ -n "$expected" ]; then - if command -v sha256sum >/dev/null 2>&1; then + if has sha256sum; then actual=$(sha256sum "$tmp/$asset" | awk '{print $1}') - elif command -v shasum >/dev/null 2>&1; then + elif has shasum; then actual=$(shasum -a 256 "$tmp/$asset" | awk '{print $1}') else warn "no sha256 tool found — skipping checksum verification" @@ -237,39 +238,76 @@ esac if [ "$completion_configured" = true ]; then printf '\n' step "${shell_kind} completion already configured in ${completion_path} — skipping" - print_next_steps - exit 0 -fi - -printf '\n %sSet up tab completion for %s?%s [Y/n] ' "$C_BOLD" "$shell_kind" "$C_RESET" -if ! read -r response < /dev/tty; then - echo - print_next_steps - exit 0 +else + printf '\n %sSet up tab completion for %s?%s [Y/n] ' "$C_BOLD" "$shell_kind" "$C_RESET" + if ! read -r response < /dev/tty; then + echo + response=n + fi + case "$response" in + n|N|no|NO|No) + step "Skipped completion setup" + ;; + *) + case "$shell_kind" in + bash) + mkdir -p "$completion_dir" + "$INSTALL_DIR/$BINARY" completion bash -c > "$completion_path" + ok "Added bash completion to ${completion_path} — restart your shell to enable" + ;; + fish) + mkdir -p "$completion_dir" + "$INSTALL_DIR/$BINARY" completion fish -c > "$completion_path" + ok "Added fish completion to ${completion_path}" + ;; + zsh) + printf '\n# chatwoot CLI completion\n%s\n' "$zsh_line" >> "$rc" + ok "Added zsh completion to ${rc} — restart your shell to enable" + ;; + esac + ;; + esac fi -case "$response" in - n|N|no|NO|No) - step "Skipped completion setup" - print_next_steps - exit 0 - ;; -esac +# --------------------------------------------------------------------------- +# Optional: 'cw' alias +# --------------------------------------------------------------------------- case "$shell_kind" in bash) - mkdir -p "$completion_dir" - "$INSTALL_DIR/$BINARY" completion bash -c > "$completion_path" - ok "Added bash completion to ${completion_path} — restart your shell to enable" - ;; - fish) - mkdir -p "$completion_dir" - "$INSTALL_DIR/$BINARY" completion fish -c > "$completion_path" - ok "Added fish completion to ${completion_path}" + alias_rc="$HOME/.bashrc" + alias_line="alias cw='$BINARY'" ;; zsh) - printf '\n# chatwoot CLI completion\n%s\n' "$zsh_line" >> "$rc" - ok "Added zsh completion to ${rc} — restart your shell to enable" + alias_rc="${ZDOTDIR:-$HOME}/.zshrc" + alias_line="alias cw='$BINARY'" + ;; + fish) + alias_rc="${XDG_CONFIG_HOME:-$HOME/.config}/fish/config.fish" + alias_line="alias cw '$BINARY'" ;; esac +alias_configured=false +[ -f "$alias_rc" ] && grep -Fq "$alias_line" "$alias_rc" && alias_configured=true + +if [ "$alias_configured" = true ]; then + step "'cw' alias already configured in ${alias_rc} — skipping" +else + printf "\n %sCreate 'cw' alias for %s?%s [Y/n] " "$C_BOLD" "$BINARY" "$C_RESET" + if ! read -r response < /dev/tty; then + echo + response=n + fi + case "$response" in + n|N|no|NO|No) + step "Skipped 'cw' alias setup" + ;; + *) + mkdir -p "$(dirname "$alias_rc")" + printf '\n# chatwoot CLI alias\n%s\n' "$alias_line" >> "$alias_rc" + ok "Added 'cw' alias to ${alias_rc} — restart your shell to enable" + ;; + esac +fi + print_next_steps From e3616db25a387b73cd0aaac01f82f884d869a799 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 11 May 2026 21:13:40 +0530 Subject: [PATCH 3/3] feat: use isntall command if available --- install.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/install.sh b/install.sh index 477eac2..9cb2e83 100755 --- a/install.sh +++ b/install.sh @@ -159,8 +159,12 @@ tar -xzf "$tmp/$asset" -C "$tmp" [ -f "$tmp/$BINARY" ] || err "archive did not contain a '$BINARY' binary" mkdir -p "$INSTALL_DIR" -mv "$tmp/$BINARY" "$INSTALL_DIR/$BINARY" -chmod +x "$INSTALL_DIR/$BINARY" +if has install; then + install -m 0755 "$tmp/$BINARY" "$INSTALL_DIR/$BINARY" +else + mv "$tmp/$BINARY" "$INSTALL_DIR/$BINARY" + chmod +x "$INSTALL_DIR/$BINARY" +fi case "$install_mode" in reinstall) ok "Reinstalled ${C_BOLD}${BINARY} ${VERSION}${C_RESET} to ${INSTALL_DIR}/${BINARY}" ;;