Last active
March 12, 2026 15:51
-
-
Save trueheart78/223b2874bd495b6c9d73befd3a1aa416 to your computer and use it in GitHub Desktop.
Kitty version checker πββ¬
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 ruby | |
| # frozen_string_literal: true | |
| ## | |
| # Ruby script to update the installed version of the kitty terminal and update | |
| # the default logo and icons to the custom versions I prefer. | |
| # | |
| # GIST URL: https://gist.github.com/trueheart78/223b2874bd495b6c9d73befd3a1aa416 | |
| ## | |
| CUSTOM_ICONS = true | |
| HOME_DIR = ENV.fetch('HOME', nil) | |
| CUSTOM_ICON_LOGO_PATH = "#{HOME_DIR}/dotfiles/files/kitty/icons/emoji_kitty.icns" | |
| CUSTOM_ICON_128_PATH = "#{HOME_DIR}/dotfiles/files/kitty/icons/kitty-128x128.png" | |
| CUSTOM_ICON_256_PATH = "#{HOME_DIR}/dotfiles/files/kitty/icons/kitty-256x256.png" | |
| begin | |
| require 'colorize' | |
| require 'optparse' | |
| require 'pry' | |
| rescue LoadError => e | |
| puts "=> Error: Unable to load required gem: #{e}" | |
| exit(1) | |
| end | |
| # rubocop:disable Metrics/AbcSize, Metrics/MethodLength | |
| def options | |
| return @options unless @options.nil? | |
| @options = {} | |
| OptionParser.new do |parser| | |
| parser.banner = 'Usage: kitty-update [options]' | |
| parser.on('-c', '--check', 'Check if an update is available') do |c| | |
| options[:check] = c | |
| end | |
| parser.on('-f', '--force', 'Force the install regardless if an update is available') do |f| | |
| options[:force] = f | |
| end | |
| parser.on('-d', '--dry-run', 'Perform a dry run without installing or updating anything') do |d| | |
| options[:dry_run] = d | |
| end | |
| parser.on('-i', '--icons', | |
| 'Update the app to use the custom icon files (defined in the script)') do |i| | |
| options[:icons] = i | |
| end | |
| parser.on('-h', '--help', 'Prints this help') do | |
| puts parser | |
| exit | |
| end | |
| end.parse! | |
| @options | |
| end | |
| # rubocop:enable Metrics/AbcSize, Metrics/MethodLength | |
| def check_version? | |
| options[:check] == true | |
| end | |
| def dry_run? | |
| options[:dry_run] == true | |
| end | |
| def forcing? | |
| options[:force] == true | |
| end | |
| def updating_icons? | |
| options[:icons] == true | |
| end | |
| def fresh_install? | |
| !installed? | |
| end | |
| def installed? | |
| @installed ||= system('which kitty >/dev/null 2>&1') | |
| end | |
| # => "0.44.1" | |
| def installed_version | |
| return '0.0.0' unless installed? | |
| @installed_version ||= `command kitty --version`.match(/(\d+\.\d+\.\d+)/)[1] | |
| rescue NoMethodError | |
| @installed_version = '0.0.0' | |
| end | |
| # => "0.45.0" | |
| def available_version | |
| @constants_py ||= `command curl --silent https://raw.githubusercontent.com/kovidgoyal/kitty/master/kitty/constants.py` | |
| @constants_py.match(/Version\((\d+, \d+, \d+)\)$/)[1].split(',').map(&:to_i).join('.') | |
| rescue NoMethodError | |
| '0.0.0' | |
| end | |
| def version_update? | |
| return if available_version == '0.0.0' | |
| installed_version != available_version | |
| end | |
| # rubocop:disable Metrics/MethodLength, Metrics/AbcSize | |
| def inform_user | |
| if forcing? | |
| puts '=> Reinstalling...'.blue | |
| elsif fresh_install? | |
| print '=> Fresh kitty version available!'.light_blue | |
| puts "(v#{available_version})".light_blue | |
| puts '=> Changelog: https://sw.kovidgoyal.net/kitty/changelog/'.light_blue | |
| elsif version_update? | |
| print '=> New kitty version available!'.light_blue | |
| puts "(v#{available_version}) [installed: v#{installed_version}] π".light_blue | |
| puts '=> Changelog: https://sw.kovidgoyal.net/kitty/changelog/'.light_blue | |
| else | |
| puts "=> You're on the most recent version! (v#{installed_version}) β ".green | |
| end | |
| end | |
| # rubocop:enable Metrics/MethodLength, Metrics/AbcSize | |
| def user_consents? | |
| puts | |
| if installed? | |
| print '=> Update? (Y/N) '.blue | |
| else | |
| print '=> Install? (Y/N) '.blue | |
| end | |
| answer = '' | |
| answer = gets.chomp while answer.length.zero? | |
| answer[0].upcase == 'Y' | |
| end | |
| def install_app | |
| puts "==> Downloading and installing v#{available_version}...".blue | |
| if dry_run? | |
| puts '===> Skipping install command [dry run]'.cyan | |
| else | |
| system 'command curl -L https://sw.kovidgoyal.net/kitty/installer.sh | sh /dev/stdin' | |
| end | |
| puts '==> Update complete!'.blue | |
| end | |
| def custom_icons? | |
| CUSTOM_ICONS && | |
| CUSTOM_ICON_LOGO_PATH.length.positive? && | |
| CUSTOM_ICON_128_PATH.length.positive? && | |
| CUSTOM_ICON_256_PATH.length.positive? | |
| end | |
| def check_icons_exist! | |
| return unless custom_icons? | |
| raise "File does not exist: #{CUSTOM_ICON_LOGO_PATH}" unless File.exist? CUSTOM_ICON_LOGO_PATH | |
| raise "File does not exist: #{CUSTOM_ICON_128_PATH}" unless File.exist? CUSTOM_ICON_128_PATH | |
| raise "File does not exist: #{CUSTOM_ICON_256_PATH}" unless File.exist? CUSTOM_ICON_256_PATH | |
| end | |
| # Updates the kitty app's Info.plist to point to a custom file (copied to its app install location) | |
| # | |
| # rubocop:disable Layout/LineLength | |
| def update_icons | |
| check_icons_exist! | |
| ## Backup the logo and icons | |
| puts '==> Backing up the logo and icon files...'.blue | |
| system 'mv /Applications/kitty.app/Contents/Resources/kitty.icns{,-bak.icns}' | |
| system 'mv /Applications/kitty.app/Contents/Resources/kitty/logo/kitty-128.png{,-bak.png}' | |
| system 'mv /Applications/kitty.app/Contents/Resources/kitty/logo/kitty.png{,-bak.png}' | |
| puts '==> Backup complete!'.blue | |
| ## Copy the preferred logo and icons into the expected location | |
| puts '==> Updating the logo and icons to use your custom files...'.blue | |
| system "cp #{CUSTOM_ICON_LOGO_PATH} /Applications/kitty.app/Contents/Resources/kitty.icns" | |
| system "cp #{CUSTOM_ICON_128_PATH} /Applications/kitty.app/Contents/Resources/kitty/logo/kitty-128.png" | |
| system "cp #{CUSTOM_ICON_256_PATH} /Applications/kitty.app/Contents/Resources/kitty/logo/kitty.png" | |
| puts '==> Update complete!'.blue | |
| end | |
| # rubocop:enable Layout/LineLength | |
| if updating_icons? | |
| unless custom_icons? | |
| puts '=> Custom ICONS are not currently setup (see top of file for settings)'.red | |
| exit 1 | |
| end | |
| update_icons | |
| elsif forcing? | |
| inform_user | |
| install_app | |
| elsif check_version? | |
| inform_user | |
| install_app if version_update? && user_consents? | |
| elsif version_update? || fresh_install? | |
| inform_user | |
| install_app if user_consents? | |
| else | |
| puts "=> Kitty is up to date! (v#{installed_version}) π".blue | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment