Skip to content

Instantly share code, notes, and snippets.

@ullaskunder3
Created July 1, 2026 18:27
Show Gist options
  • Select an option

  • Save ullaskunder3/2221f7c5e3c564bac0d96f0097b19c60 to your computer and use it in GitHub Desktop.

Select an option

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
#!/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