Skip to content

Instantly share code, notes, and snippets.

@MohamedElashri
Created July 18, 2024 13:42
Show Gist options
  • Save MohamedElashri/b71c447cfcf539b5daafb124982088c3 to your computer and use it in GitHub Desktop.
Save MohamedElashri/b71c447cfcf539b5daafb124982088c3 to your computer and use it in GitHub Desktop.
MacOS positron update script. Script checks beta version from github releases and compare with current installed one
#!/usr/bin/env bash
set -e
# Function to log errors
log_error() {
echo "ERROR: $1" >&2
}
# Function to log info
log_info() {
echo "INFO: $1"
}
# Function to check if a command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Function to install jq if it's not present
install_jq() {
if ! command_exists brew; then
log_error "Homebrew is not installed. Please install Homebrew or jq manually."
exit 1
fi
log_info "Attempting to install the 'jq' command-line tool..."
if ! brew install jq; then
log_error "Unable to install the 'jq' command-line tool. Please install 'jq' manually and try again."
exit 1
fi
}
# Function to get the current installed version of Positron
get_installed_version() {
if [ -e "/Applications/Positron.app/Contents/Info.plist" ]; then
version=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "/Applications/Positron.app/Contents/Info.plist")
echo "$version"
else
echo ""
fi
}
# Function to compare versions
version_gt() {
test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"
}
# Check for jq
if ! command_exists jq; then
install_jq
fi
log_info "Checking for Positron installation and updates."
# Check if Positron is installed
installed_version=$(get_installed_version)
if [ -z "$installed_version" ]; then
log_info "Positron is not currently installed. Proceeding with installation of the latest version."
else
log_info "Current installed version: $installed_version"
fi
# Fetch release information
response=$(curl -s "https://api.github.com/repos/posit-dev/positron/releases")
if [ $? -ne 0 ]; then
log_error "Unable to fetch data from GitHub API."
exit 1
fi
# Check if the response is valid JSON and contains the expected fields
if ! echo "$response" | jq -e '.[0].tag_name' > /dev/null 2>&1; then
log_error "Invalid or unexpected response from GitHub API. Response: $response"
exit 1
fi
latest_tag=$(echo "$response" | jq -r '.[0].tag_name')
latest_version=${latest_tag#v} # Remove 'v' prefix if present
if [ -n "$installed_version" ] && ! version_gt "$latest_version" "$installed_version"; then
log_info "You already have the latest version ($installed_version) installed."
exit 0
fi
# Check if Positron is running
if pgrep -x "Positron" > /dev/null; then
read -p "Positron is currently running. Close it before updating? (y/n): " answer
if [[ $answer != [Yy]* ]]; then
log_info "Update cancelled. Please close Positron and run the script again."
exit 0
fi
killall Positron
fi
# Prepare for download and installation
tempdir=$(mktemp -d)
trap 'rm -rf "$tempdir"' EXIT
asset_url=$(echo "$response" | jq -r '.[0].assets[] | select(.name|test("dmg$")) | .browser_download_url')
if [ -z "$asset_url" ]; then
log_error "Unable to find a DMG download URL in the GitHub API response."
exit 1
fi
filename=$(basename "$asset_url")
destination="${tempdir}/${filename}"
log_info "Downloading ${filename}..."
if ! curl -L -o "$destination" "$asset_url"; then
log_error "Unable to download Positron from GitHub."
exit 1
fi
log_info "Installing ${filename}..."
volume_name=$(basename "$filename" .dmg)
volume_mount="/Volumes/${volume_name}"
if ! hdiutil attach -quiet "$destination"; then
log_error "Failed to mount the disk image."
exit 1
fi
log_info "Contents of mounted volume:"
ls -l "${volume_mount}"
if [ -d "${volume_mount}/Positron.app" ]; then
log_info "Copying Positron.app to /Applications..."
if ! sudo rsync -a --delete --info=progress2 "${volume_mount}/Positron.app" /Applications/; then
log_error "Failed to copy Positron to /Applications. Checking permissions..."
ls -l /Applications
hdiutil detach -quiet "$volume_mount"
exit 1
fi
log_info "Copy successful"
else
log_error "Positron.app not found in mounted volume"
hdiutil detach -quiet "$volume_mount"
exit 1
fi
if ! hdiutil detach -quiet "$volume_mount"; then
log_error "Failed to unmount the disk image."
exit 1
fi
if [ ! -e "/Applications/Positron.app" ]; then
log_error "Positron.app not found in /Applications after installation. Contents of /Applications:"
ls -l /Applications
exit 1
fi
# Set correct permissions for the Positron.app
sudo chown -R root:wheel /Applications/Positron.app
sudo chmod -R 755 /Applications/Positron.app
log_info "Successfully installed Positron ${latest_version}."
log_info "Positron.app should now be located in /Applications."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment