Skip to content

Instantly share code, notes, and snippets.

@MohamedElashri
Last active September 29, 2024 22:05
Show Gist options
  • Save MohamedElashri/b8dabacb67d56f158dd043d5718d83fd to your computer and use it in GitHub Desktop.
Save MohamedElashri/b8dabacb67d56f158dd043d5718d83fd to your computer and use it in GitHub Desktop.
Update script for Cursor AI IDE on linux

Cursor IDE Update Script

This Python script automates the process of downloading, installing, and updating the Cursor IDE on Linux. It checks if a new version is available, updates the AppImage, and refreshes the desktop entry and icon.

Prerequisites

  • Python 3.x
  • urllib and hashlib modules (standard with Python 3)

Usage

  1. download the script:
wget https://gist.githubusercontent.com/MohamedElashri/b8dabacb67d56f158dd043d5718d83fd/raw/77f134ecf31fda96d4874458cc9c99ff5d15e1e1/update_cursor_linux.py
  1. Run the script with sudo to allow installation into /opt and update the system-wide .desktop entry:
    sudo python3 update_cursor_linux.py

The script will check for the latest version of Cursor IDE and update it if necessary.

# -*- coding: utf-8 -*-
import os
import hashlib
import urllib.request
def calculate_file_hash(file_path, hash_algo='sha256'):
"""Calculate the hash of a file."""
hash_func = hashlib.new(hash_algo)
with open(file_path, 'rb') as f:
while chunk := f.read(8192):
hash_func.update(chunk)
return hash_func.hexdigest()
def download_file(url, target_path, headers=None):
"""Download file from URL."""
req = urllib.request.Request(url, headers=headers or {})
with urllib.request.urlopen(req) as response:
file_size = int(response.info().get('Content-Length', -1))
downloaded = 0
block_size = 8192
with open(target_path, 'wb') as out_file:
while True:
buffer = response.read(block_size)
if not buffer:
break
downloaded += len(buffer)
out_file.write(buffer)
if file_size > 0:
percent = downloaded * 100 / file_size
print(f"\rDownload progress: {percent:.2f}%", end='', flush=True)
print("\nDownload complete!")
# Define the directory where the Cursor AppImage will be placed
target_dir = "/opt/cursor"
# Ensure the target directory exists
os.makedirs(target_dir, exist_ok=True)
# Cursor download URL
url = "https://downloader.cursor.sh/linux/appImage/x64"
headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'}
# Path to the current AppImage (symlink)
current_appimage_path = os.path.join(target_dir, "cursor.AppImage")
# Check if the AppImage file exists and calculate its hash
if os.path.exists(current_appimage_path):
print("Checking for Cursor updates...")
current_hash = calculate_file_hash(current_appimage_path)
else:
print("Installing Cursor for the first time...")
current_hash = None
# Download the new AppImage to a temporary file
new_appimage_path = os.path.join(target_dir, "cursor_new.AppImage")
print("Downloading the latest version of Cursor...")
download_file(url, new_appimage_path, headers)
# Calculate the hash of the newly downloaded AppImage
new_hash = calculate_file_hash(new_appimage_path)
# Compare the hashes to determine if an update is needed
if current_hash == new_hash:
print(f"You are already using the latest version. No update is necessary.")
os.remove(new_appimage_path) # Clean up the new download if it's the same
else:
print(f"New version detected. Updating Cursor...")
# Set executable permissions on the new AppImage
os.chmod(new_appimage_path, 0o755)
# Remove old AppImage if it exists
if os.path.exists(current_appimage_path):
os.remove(current_appimage_path)
# Move the new AppImage into place
os.rename(new_appimage_path, current_appimage_path)
print(f"Cursor has been updated to the latest version: {current_appimage_path}")
# Download and replace the icon in /opt
icon_url = "https://avatars.githubusercontent.com/u/126759922?v=4" # GitHub logo
icon_path = "/opt/cursor/cursor.jpg"
try:
urllib.request.urlretrieve(icon_url, icon_path)
print(f"Icon downloaded and saved to: {icon_path}")
except Exception as e:
print(f"Failed to download icon: {str(e)}")
# Create or update the .desktop file in /usr/share/applications (system-wide)
desktop_file_path = "/usr/share/applications/cursor.desktop"
desktop_content = f"""[Desktop Entry]
Name=Cursor
Exec={current_appimage_path}
Terminal=false
Type=Application
Icon={icon_path}
StartupWMClass=Cursor
X-AppImage-Version=latest
Comment=Cursor is an AI-first coding environment.
MimeType=x-scheme-handler/cursor;
Categories=Utility;Development;
"""
with open(desktop_file_path, 'w') as f:
f.write(desktop_content)
os.chmod(desktop_file_path, 0o755)
print(f".desktop file updated: {desktop_file_path}")
# Create a symbolic link to the .desktop file in the target directory (optional)
desktop_symlink_path = os.path.join(target_dir, "cursor.desktop")
if os.path.exists(desktop_symlink_path):
os.remove(desktop_symlink_path)
os.symlink(desktop_file_path, desktop_symlink_path)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment