Skip to content

Commit f0c45b5

Browse files
committed
feat(core): Implement self-update feature
- Adds the `--update` flag to the CLI to check for and install the latest version. - Implements logic to fetch the current latest release from GitHub. - Automatically downloads and updates the local executable binary when an update is needed.
1 parent 47ff576 commit f0c45b5

1 file changed

Lines changed: 87 additions & 0 deletions

File tree

aicommit

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
# aicommit -m|--model <name> # optional model override for the chosen provider
1717
# aicommit --pull # auto pull origin branch with --no-rebase before commit
1818
# aicommit -r|--release [bump|ver] # release: patch, minor, major, X.Y.Z, or auto
19+
# aicommit --update # update aicommit to the latest release
1920
# aicommit -h|--help # show this help
2021
# aicommit -v|-V|--version # show version information
2122
# ----------------------------------------------------------------------
@@ -91,6 +92,7 @@ show_help() {
9192
echo -e " ${C_GREEN}--pull${C_RESET} Auto pull from origin with --no-rebase before committing."
9293
echo -e " ${C_GREEN}--release${C_RESET}, ${C_GREEN}-r${C_RESET} ${C_DIM}[type]${C_RESET} Create a release. Type: patch, minor, major, or X.Y.Z."
9394
echo -e " ${C_DIM}If omitted, AI auto-detects the bump type.${C_RESET}"
95+
echo -e " ${C_GREEN}--update${C_RESET} Update aicommit to the latest release from GitHub."
9496
echo -e " ${C_GREEN}-v${C_RESET}, ${C_GREEN}-V${C_RESET}, ${C_GREEN}--version${C_RESET} Show version information."
9597
echo -e " ${C_GREEN}-h${C_RESET}, ${C_GREEN}--help${C_RESET} Show this help message."
9698
echo
@@ -199,6 +201,87 @@ show_help() {
199201
echo -e " aicommit ${C_GREEN}--provider${C_RESET} anthropic ${C_GREEN}--model${C_RESET} claude-3-5-sonnet-latest"
200202
}
201203

204+
# ---------- Self-update ----------
205+
GITHUB_REPO="apertacodex/aicommit"
206+
GITHUB_RAW_URL="https://raw.githubusercontent.com/${GITHUB_REPO}/main/aicommit"
207+
GITHUB_API_URL="https://api.github.com/repos/${GITHUB_REPO}/releases/latest"
208+
209+
self_update() {
210+
echo -e "${C_CYAN}${C_BOLD}Checking for updates...${C_RESET}"
211+
212+
# Fetch latest release version from GitHub
213+
local latest_version
214+
latest_version=$(curl -sfL "$GITHUB_API_URL" | jq -r '.tag_name // empty' 2>/dev/null | sed 's/^v//')
215+
216+
if [[ -z "$latest_version" ]]; then
217+
echo -e "${C_RED}Error: Could not fetch the latest release from GitHub.${C_RESET}"
218+
echo -e "${C_DIM}Check your network connection or try again later.${C_RESET}"
219+
exit 1
220+
fi
221+
222+
echo -e " Installed version: ${C_BOLD}v${VERSION}${C_RESET}"
223+
echo -e " Latest version: ${C_BOLD}v${latest_version}${C_RESET}"
224+
225+
# Compare versions
226+
if [[ "$VERSION" == "$latest_version" ]]; then
227+
echo -e "\n${C_GREEN}✅ You are already running the latest version.${C_RESET}"
228+
exit 0
229+
fi
230+
231+
echo -e "\n${C_YELLOW}⬆ New version available: v${latest_version}${C_RESET}"
232+
233+
# Find where the current binary lives
234+
local current_bin
235+
current_bin=$(command -v aicommit 2>/dev/null || true)
236+
237+
if [[ -z "$current_bin" ]]; then
238+
echo -e "${C_RED}Error: Cannot locate the aicommit binary in PATH.${C_RESET}"
239+
exit 1
240+
fi
241+
242+
# Resolve symlinks to get the actual file
243+
local actual_bin
244+
if command -v readlink &>/dev/null; then
245+
actual_bin=$(readlink -f "$current_bin" 2>/dev/null || echo "$current_bin")
246+
else
247+
actual_bin="$current_bin"
248+
fi
249+
250+
echo -e " Updating: ${C_DIM}${actual_bin}${C_RESET}"
251+
252+
# Download to a temp file first
253+
local tmp_file
254+
tmp_file=$(mktemp /tmp/aicommit-update-XXXXXX)
255+
256+
if ! curl -fsSL "$GITHUB_RAW_URL" -o "$tmp_file"; then
257+
echo -e "${C_RED}Error: Failed to download the latest version.${C_RESET}"
258+
rm -f "$tmp_file"
259+
exit 1
260+
fi
261+
262+
# Verify the download looks like the aicommit script
263+
if ! head -1 "$tmp_file" | grep -q '#!/usr/bin/env bash'; then
264+
echo -e "${C_RED}Error: Downloaded file does not appear to be a valid aicommit script.${C_RESET}"
265+
rm -f "$tmp_file"
266+
exit 1
267+
fi
268+
269+
chmod +x "$tmp_file"
270+
271+
# Install — use sudo if we can't write to the target directly
272+
if [[ -w "$actual_bin" ]]; then
273+
mv "$tmp_file" "$actual_bin"
274+
elif sudo -n true 2>/dev/null; then
275+
sudo mv "$tmp_file" "$actual_bin"
276+
else
277+
echo -e "${C_YELLOW}Elevated permissions required to update ${actual_bin}${C_RESET}"
278+
sudo mv "$tmp_file" "$actual_bin"
279+
fi
280+
281+
echo -e "\n${C_GREEN}✅ Successfully updated aicommit: v${VERSION} → v${latest_version}${C_RESET}"
282+
exit 0
283+
}
284+
202285
set -euo pipefail
203286

204287
# ---------- Provider constants ----------
@@ -245,6 +328,10 @@ while (( "$#" )); do
245328
shift
246329
fi
247330
;;
331+
--update)
332+
show_banner
333+
self_update
334+
;;
248335
-v|-V|--version)
249336
show_banner
250337
exit 0

0 commit comments

Comments
 (0)