Files
cursor-nixos-flake/update-cursor.sh
T
2025-12-24 16:38:33 -04:00

192 lines
5.6 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# Script to manually update Cursor version/hashes used by the flake
# Usage: ./update-cursor.sh [version]
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
RELEASE_FILE="$SCRIPT_DIR/cursor-release.nix"
CHANNEL_FOR_SYSTEM_x86_64_linux="linux-x64"
CHANNEL_FOR_SYSTEM_aarch64_linux="linux-arm64"
# Function to get latest version from API redirect
get_latest_version() {
# Get the redirect URL and extract version from the AppImage filename
local redirect_url
redirect_url=$(curl -s -I "https://api2.cursor.sh/updates/download/golden/linux-x64/cursor/latest" | grep -i location | cut -d' ' -f2 | tr -d '\r\n')
if [[ -n "$redirect_url" ]]; then
# Extract version from URL like: .../Cursor-1.7.39-x86_64.AppImage
echo "$redirect_url" | grep -o 'Cursor-[0-9]\+\.[0-9]\+\.[0-9]\+' | sed 's/Cursor-//'
else
echo "Error: Could not get redirect URL"
return 1
fi
}
# Function to get current version from cursor-release.nix
get_current_version() {
grep -o 'version = "[^"]*"' "$RELEASE_FILE" | head -1 | cut -d'"' -f2
}
# Function to compute sha256 for a given system+version
prefetch_sha256() {
local system="$1"
local version="$2"
local channel=""
case "$system" in
x86_64-linux) channel="$CHANNEL_FOR_SYSTEM_x86_64_linux" ;;
aarch64-linux) channel="$CHANNEL_FOR_SYSTEM_aarch64_linux" ;;
*) echo "Error: Unsupported system: $system" >&2; return 1 ;;
esac
local url="https://api2.cursor.sh/updates/download/golden/${channel}/cursor/${version}"
if ! command -v nix-prefetch-url >/dev/null 2>&1; then
echo "Error: nix-prefetch-url not found. Please install Nix (or nix-prefetch-url) and retry." >&2
return 1
fi
# IMPORTANT: this function is captured by command substitution. Keep stdout as the hash only.
echo "Prefetching ($system) from: $url" >&2
local out hash
out="$(nix-prefetch-url --type sha256 "$url" 2>&1)"
echo "$out" >&2
# Extract the Nix base32 sha256 hash (52 chars, Nix alphabet).
hash="$(echo "$out" | grep -Eo '[0-9abcdfghijklmnpqrsvwxyz]{52}' | tail -n1 || true)"
if [[ -z "$hash" ]]; then
echo "Error: Could not parse sha256 from nix-prefetch-url output for $system" >&2
return 1
fi
echo "$hash"
}
# Function to update cursor-release.nix
update_release() {
local version="$1"
echo "Computing hashes for version: $version"
local sha_x86 sha_aarch64
sha_x86="$(prefetch_sha256 x86_64-linux "$version")"
sha_aarch64="$(prefetch_sha256 aarch64-linux "$version")"
echo "x86_64-linux sha256: $sha_x86"
echo "aarch64-linux sha256: $sha_aarch64"
# Create backup
cp "$RELEASE_FILE" "$RELEASE_FILE.backup"
cat > "$RELEASE_FILE" <<EOF
{
# Managed by ./update-cursor.sh
#
# Notes:
# - \`sha256\` values are Nix base32 hashes (as used by \`fetchurl { sha256 = "..."; }\`).
version = "$version";
sha256 = {
x86_64-linux = "$sha_x86";
aarch64-linux = "$sha_aarch64";
};
}
EOF
echo "Updated cursor-release.nix with version $version"
}
# Function to test the flake
test_flake() {
echo "Testing flake..."
if command -v nix >/dev/null 2>&1; then
nix flake check --no-build
echo "Flake check passed!"
else
echo "Warning: nix command not found. Skipping flake check."
fi
}
# Main logic
main() {
local target_version="${1:-}"
echo "Cursor Flake Updater"
echo "==================="
# Get current version
local current_version
current_version=$(get_current_version)
echo "Current version: $current_version"
# Determine target version
if [[ -n "$target_version" ]]; then
echo "Target version: $target_version"
else
echo "Fetching latest version..."
target_version=$(get_latest_version)
echo "Latest version: $target_version"
fi
# Check if update is needed
if [[ "$target_version" == "$current_version" ]]; then
echo "No update needed. Current version is up to date."
if [[ -n "${GITHUB_OUTPUT:-}" ]]; then
echo "CURSOR_VERSION_INFO=no_update" >> "$GITHUB_OUTPUT"
fi
exit 0
fi
echo "Update needed: $current_version -> $target_version"
# Check if running in CI/GitHub Actions (auto-confirm)
if [[ -n "${CI:-}" ]] || [[ -n "${GITHUB_ACTIONS:-}" ]]; then
echo "Running in CI mode, auto-confirming update..."
REPLY="y"
else
read -p "Do you want to proceed with the update? (y/N): " -n 1 -r
echo
fi
if [[ $REPLY =~ ^[Yy]$ ]]; then
update_release "$target_version"
test_flake
echo "Update completed successfully!"
if [[ -n "${GITHUB_OUTPUT:-}" ]]; then
echo "CURSOR_VERSION_INFO=completed:$current_version:$target_version" >> "$GITHUB_OUTPUT"
fi
echo "You can now commit the changes:"
echo " git add flake.nix cursor-release.nix"
echo " git commit -m \"Update Cursor to version $target_version\""
else
echo "Update cancelled."
exit 1
fi
}
# Check dependencies
check_dependencies() {
local missing_deps=()
if ! command -v curl >/dev/null 2>&1; then
missing_deps+=("curl")
fi
if [[ ! -f "$RELEASE_FILE" ]]; then
missing_deps+=("cursor-release.nix (missing file)")
fi
if [[ ${#missing_deps[@]} -gt 0 ]]; then
echo "Error: Missing required dependencies: ${missing_deps[*]}"
echo "Please install them and try again."
exit 1
fi
}
# Run main function
check_dependencies
main "$@"