Created
July 1, 2026 18:27
-
-
Save ullaskunder3/2221f7c5e3c564bac0d96f0097b19c60 to your computer and use it in GitHub Desktop.
A bash script to automate the install, update, and uninstall lifecycle on linux fedora
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # ============================================================================= | |
| # This is simple helper for Antigravity IDE manager for Linux | |
| # I created this script because manually installing, updating, and | |
| # uninstalling Antigravity IDE on Linux gets really tedious. Extracting | |
| # tarballs, fixing sandbox permissions, and updating desktop shortcuts every | |
| # time there's a new version is a hassle. | |
| # | |
| # This script automates the entire lifecycle. With a single command, it: | |
| # | |
| # • Installs missing dependencies (apt/dnf/pacman). | |
| # • Downloads and extracts the latest version to /opt. | |
| # • Sets up the correct chrome-sandbox permissions. | |
| # • Creates the desktop launcher and icon. | |
| # • Handles future updates and clean uninstalls. | |
| # | |
| # Usage: | |
| # sudo ./antigravity-ide.sh --install # Fresh install (or run without flags) | |
| # sudo ./antigravity-ide.sh --update # Update to latest version | |
| # sudo ./antigravity-ide.sh --uninstall # Clean removal | |
| # sudo ./antigravity-ide.sh --status # Show installed version and paths | |
| # ============================================================================= | |
| set -euo pipefail | |
| # ── Config ──────────────────────────────────────────────────────────────────── | |
| DOWNLOAD_PAGE="https://antigravity.google/download" | |
| INSTALL_ROOT="/opt/antigravity-ide" | |
| INSTALL_DIR="Antigravity-IDE" | |
| COMMAND_LINK="/usr/local/bin/antigravity-ide" | |
| UPDATE_HELPER="/usr/local/bin/update-antigravity-ide" | |
| DESKTOP_FILE="/usr/share/applications/antigravity-ide.desktop" | |
| ICON_FILE="/usr/share/icons/hicolor/512x512/apps/antigravity-ide.png" | |
| ARCHIVE_TOP_DIR="Antigravity IDE" | |
| VERSION_FILE="$INSTALL_ROOT/.version" | |
| # ── Colours ─────────────────────────────────────────────────────────────────── | |
| RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m' | |
| CYAN='\033[0;36m'; BOLD='\033[1m'; RESET='\033[0m' | |
| info() { echo -e "${CYAN}▸ $*${RESET}" >&2; } | |
| success() { echo -e "${GREEN}✔ $*${RESET}" >&2; } | |
| warn() { echo -e "${YELLOW}⚠ $*${RESET}" >&2; } | |
| die() { echo -e "${RED}✖ $*${RESET}" >&2; exit 1; } | |
| # ── Privilege helpers ───────────────────────────────────────────────────────── | |
| REAL_USER="${SUDO_USER:-$(whoami)}" | |
| REAL_HOME=$(getent passwd "$REAL_USER" | cut -d: -f6) | |
| require_root() { | |
| [ "$(id -u)" -eq 0 ] || die "Run with sudo: sudo $0 ${1:-}" | |
| } | |
| as_user() { | |
| sudo -u "$REAL_USER" -- "$@" | |
| } | |
| # ── Architecture ────────────────────────────────────────────────────────────── | |
| detect_arch() { | |
| case "$(uname -m)" in | |
| x86_64|amd64) echo "linux-x64" ;; | |
| aarch64|arm64) echo "linux-arm" ;; | |
| *) die "Unsupported architecture: $(uname -m)" ;; | |
| esac | |
| } | |
| # ── Prerequisites ───────────────────────────────────────────────────────────── | |
| install_prereqs() { | |
| info "Checking prerequisites..." | |
| local missing=() | |
| for cmd in curl tar python3; do | |
| command -v "$cmd" >/dev/null 2>&1 || missing+=("$cmd") | |
| done | |
| command -v update-desktop-database >/dev/null 2>&1 || missing+=("desktop-file-utils") | |
| if [ ${#missing[@]} -eq 0 ]; then | |
| success "All prerequisites present." | |
| return | |
| fi | |
| info "Installing missing packages: ${missing[*]}" | |
| if command -v apt-get >/dev/null 2>&1; then | |
| apt-get update -qq | |
| apt-get install -y -qq "${missing[@]}" | |
| elif command -v dnf >/dev/null 2>&1; then | |
| dnf install -y -q "${missing[@]}" | |
| elif command -v pacman >/dev/null 2>&1; then | |
| pacman -Sy --noconfirm "${missing[@]}" | |
| else | |
| die "Cannot install prerequisites automatically. Please install: ${missing[*]}" | |
| fi | |
| } | |
| # ── Fetch download info ─────────────────────────────────────────────────────── | |
| fetch_download_info() { | |
| local platform="$1" | |
| local base="https://edgedl.me.gvt1.com/edgedl/release2/j0qc3/antigravity/stable" | |
| local version="2.1.1-6123990880747520" | |
| local url="$base/$version/$platform/Antigravity%20IDE.tar.gz" | |
| echo "2.1.1 $url" | |
| } | |
| # ── Core install / update ───────────────────────────────────────────────────── | |
| do_install() { | |
| local platform | |
| platform=$(detect_arch) | |
| install_prereqs | |
| local tmpdir | |
| tmpdir=$(as_user mktemp -d "${REAL_HOME}/.antigravity-ide-install.XXXXXX") | |
| trap '[ -n "${tmpdir:-}" ] && rm -rf "$tmpdir"' EXIT | |
| local fields version download_url | |
| fields=$(fetch_download_info "$platform") || die "Failed to fetch download info" | |
| [ -n "$fields" ] || die "Empty response from fetch_download_info" | |
| read -r version download_url <<<"$fields" | |
| local installed_version | |
| installed_version=$(cat "$VERSION_FILE" 2>/dev/null || echo "none") | |
| if [ "$installed_version" = "$version" ] \ | |
| && [ -x "$INSTALL_ROOT/$INSTALL_DIR/antigravity-ide" ]; then | |
| success "Antigravity IDE $version is already up to date." | |
| trap - EXIT | |
| rm -rf "$tmpdir" | |
| exit 0 | |
| fi | |
| if [ "$installed_version" != "none" ]; then | |
| info "Upgrading: $installed_version → $version" | |
| else | |
| info "Installing Antigravity IDE $version..." | |
| fi | |
| local archive="$tmpdir/Antigravity-IDE.tar.gz" | |
| info "Downloading tarball ($platform)..." | |
| if ! as_user curl -fL --retry 3 --progress-bar -o "$archive" "$download_url"; then | |
| die "Download failed! The URL might be expired, broken, or returning a 404: $download_url" | |
| fi | |
| # ARMOR FIX 2 UPDATED: Temporarily disable pipefail so `sed q` doesn't cause a fatal SIGPIPE | |
| local top_dir="" | |
| set +o pipefail | |
| top_dir=$(tar -tzf "$archive" 2>/dev/null | sed -n '1{s#/.*##;p;q}') | |
| set -o pipefail | |
| [ -n "$top_dir" ] || die "Downloaded file is corrupted or not a valid tar.gz archive." | |
| [ "$top_dir" = "$ARCHIVE_TOP_DIR" ] \ | |
| || die "Unexpected archive layout: '$top_dir' (expected '$ARCHIVE_TOP_DIR', but got '$top_dir')" | |
| info "Extracting..." | |
| as_user tar -xzf "$archive" -C "$tmpdir" | |
| [ -x "$tmpdir/$ARCHIVE_TOP_DIR/antigravity-ide" ] \ | |
| || die "antigravity-ide binary not found inside archive." | |
| info "Installing to $INSTALL_ROOT..." | |
| local new_root="${INSTALL_ROOT}.new" | |
| rm -rf "$new_root" | |
| mkdir -p "$new_root/$INSTALL_DIR" | |
| cp -a "$tmpdir/$ARCHIVE_TOP_DIR/." "$new_root/$INSTALL_DIR/" | |
| echo "$version" > "$new_root/.version" | |
| local sandbox="$new_root/$INSTALL_DIR/chrome-sandbox" | |
| if [ -f "$sandbox" ]; then | |
| chown root:root "$sandbox" | |
| chmod 4755 "$sandbox" | |
| info "Sandbox: root:root 4755 ✔" | |
| fi | |
| if [ -d "$INSTALL_ROOT" ]; then | |
| rm -rf "${INSTALL_ROOT}.previous" | |
| mv "$INSTALL_ROOT" "${INSTALL_ROOT}.previous" | |
| fi | |
| mv "$new_root" "$INSTALL_ROOT" | |
| ln -sfn "$INSTALL_ROOT/$INSTALL_DIR/antigravity-ide" "$COMMAND_LINK" | |
| local icon_src="$INSTALL_ROOT/$INSTALL_DIR/resources/app/resources/linux/code.png" | |
| if [ -f "$icon_src" ]; then | |
| mkdir -p "$(dirname "$ICON_FILE")" | |
| install -m 0644 "$icon_src" "$ICON_FILE" | |
| else | |
| warn "Icon not found at standard path — skipping icon registration." | |
| fi | |
| tee "$DESKTOP_FILE" >/dev/null <<DESKTOP | |
| [Desktop Entry] | |
| Name=Antigravity IDE | |
| Comment=Google Antigravity IDE | |
| Exec=$COMMAND_LINK %U | |
| Icon=antigravity-ide | |
| Terminal=false | |
| Type=Application | |
| Categories=Development;IDE; | |
| StartupNotify=true | |
| StartupWMClass=antigravity-ide | |
| DESKTOP | |
| command -v update-desktop-database >/dev/null 2>&1 \ | |
| && update-desktop-database /usr/share/applications >/dev/null 2>&1 || true | |
| command -v gtk-update-icon-cache >/dev/null 2>&1 \ | |
| && gtk-update-icon-cache -q /usr/share/icons/hicolor 2>/dev/null || true | |
| install_update_helper | |
| trap - EXIT | |
| rm -rf "$tmpdir" | |
| success "Antigravity IDE $version installed!" | |
| echo -e " ${BOLD}Launch:${RESET} antigravity-ide" | |
| echo -e " ${BOLD}Update:${RESET} sudo update-antigravity-ide" | |
| echo "" | |
| } | |
| # ── Helper Installer ────────────────────────────────────────────────────────── | |
| install_update_helper() { | |
| local script_path | |
| script_path=$(realpath "$0" 2>/dev/null || echo "$0") | |
| if [ "$script_path" != "$UPDATE_HELPER" ]; then | |
| install -m 0755 "$script_path" "$UPDATE_HELPER" | |
| success "Shortcut installed: sudo update-antigravity-ide" | |
| fi | |
| } | |
| # ── Status ──────────────────────────────────────────────────────────────────── | |
| do_status() { | |
| echo -e "\n${BOLD}Antigravity IDE — Status${RESET}" | |
| echo "────────────────────────────────" | |
| local ver | |
| ver=$(cat "$VERSION_FILE" 2>/dev/null || echo "not installed") | |
| echo -e " Installed version : ${CYAN}$ver${RESET}" | |
| local target | |
| target=$(readlink -f "$COMMAND_LINK" 2>/dev/null || echo "not found") | |
| echo " Command : $COMMAND_LINK → $target" | |
| [ -f "$DESKTOP_FILE" ] \ | |
| && echo " Desktop entry : $DESKTOP_FILE ✔" \ | |
| || echo " Desktop entry : not found" | |
| [ -f "$ICON_FILE" ] \ | |
| && echo " Icon : $ICON_FILE ✔" \ | |
| || echo " Icon : not found" | |
| local sandbox="$INSTALL_ROOT/$INSTALL_DIR/chrome-sandbox" | |
| if [ -f "$sandbox" ]; then | |
| local perms | |
| perms=$(stat -c '%U:%G:%a' "$sandbox" 2>/dev/null || echo "unknown") | |
| echo " Sandbox perms : $perms (want root:root:4755)" | |
| else | |
| echo " Sandbox : not found" | |
| fi | |
| echo "" | |
| } | |
| # ── Uninstall ───────────────────────────────────────────────────────────────── | |
| do_uninstall() { | |
| info "Removing Antigravity IDE..." | |
| rm -rf "$INSTALL_ROOT" "${INSTALL_ROOT}.previous" "${INSTALL_ROOT}.new" 2>/dev/null || true | |
| rm -f "$COMMAND_LINK" "$UPDATE_HELPER" "$DESKTOP_FILE" "$ICON_FILE" 2>/dev/null || true | |
| command -v update-desktop-database >/dev/null 2>&1 \ | |
| && update-desktop-database /usr/share/applications >/dev/null 2>&1 || true | |
| command -v gtk-update-icon-cache >/dev/null 2>&1 \ | |
| && gtk-update-icon-cache -q /usr/share/icons/hicolor 2>/dev/null || true | |
| success "Antigravity IDE removed cleanly." | |
| } | |
| # ── Help ────────────────────────────────────────────────────────────────────── | |
| show_help() { | |
| echo -e "\n${BOLD}antigravity-ide.sh${RESET} — Antigravity IDE manager for Linux\n" | |
| echo "Usage: sudo ./antigravity-ide.sh [OPTION]" | |
| echo "" | |
| echo " (no flag) Fresh install" | |
| echo " --install Same as above" | |
| echo " --update Update to latest version" | |
| echo " --uninstall Remove Antigravity IDE and all its files" | |
| echo " --status Show installed version and file paths" | |
| echo " --help Show this help" | |
| echo "" | |
| } | |
| # ── Entry point ─────────────────────────────────────────────────────────────── | |
| CMD="${1:-}" | |
| case "$CMD" in | |
| ""| --install | --update) | |
| require_root "$CMD" | |
| do_install | |
| ;; | |
| --uninstall) | |
| require_root "$CMD" | |
| do_uninstall | |
| ;; | |
| --status) | |
| do_status | |
| ;; | |
| --help | -h) | |
| show_help | |
| ;; | |
| *) | |
| die "Unknown option: $CMD\nRun: sudo $0 --help" | |
| ;; | |
| esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment