Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 130 additions & 35 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -68,6 +69,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)
# ---------------------------------------------------------------------------
Expand All @@ -84,7 +101,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
Expand All @@ -107,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"
Expand All @@ -133,10 +159,18 @@ 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

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
Expand All @@ -160,7 +194,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"
}

Expand All @@ -180,43 +216,102 @@ case "${SHELL##*/}" in
;;
esac

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
fi
case "$response" in
n|N|no|NO|No)
step "Skipped completion setup"
print_next_steps
exit 0
;;
esac

# Skip the prompt entirely if completion is already configured.
completion_configured=false
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"
completion_dir="${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion/completions"
completion_path="$completion_dir/$BINARY"
[ -f "$completion_path" ] && completion_configured=true
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Regenerate static completions after upgrades

When a bash completion file already exists, this now treats mere presence as current and skips writing a new one; during a normal latest upgrade or CHATWOOT_VERSION change, users keep the old static completion script, so new/renamed commands and flags from the installed binary are not completed. The same pattern is used for fish just below, while zsh’s sourced command is dynamic.

Useful? React with 👍 / 👎.

;;
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"
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"
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"
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"
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

# ---------------------------------------------------------------------------
# Optional: 'cw' alias
# ---------------------------------------------------------------------------
case "$shell_kind" in
bash)
alias_rc="$HOME/.bashrc"
alias_line="alias cw='$BINARY'"
;;
zsh)
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
Loading