#!/usr/bin/env ruby # A workaround to upgrade installed casks # Update Homebrew Cask and verify installed applications versions with Casks to perform an upgrade # The app prompts you to update only if the Cask contain a version number and the installed app version can be retrieved. # Therefore casks that use "latest" will not be updated # # NOTE: THIS SCRIPT COMPLETELY REMOVES OUT-OF-DATE CASKS & ADDS THE LATEST VERSION. require 'optparse' options = {} OptionParser.new do |opts| opts.banner = "Usage: #{opts.program_name()} " opts.on("-y", "Assume yes") do |y| options[:auto] = y end end.parse! options[:package] = ARGV[0] # UPGRADE SPECIFIC APP if options[:package] app = options[:package] if system("brew cask info #{app} &>/dev/null") print "Do you want to reinstall #{app}? " + '[y/N]' if options[:auto] update = 'y' else update = STDIN.gets.strip end if update =~ /[yY]/ puts "Closing any open instances of #{app}" system("osascript -e \'quit app \"#{app}\"\' && sleep 1") puts "Upgrading #{app}".green system("brew cask uninstall #{app} --force && sleep 1 && brew cask install #{app} --force") else puts 'Cancelling update...' end else puts 'Unknown app to update' end exit! end # UPDATE HOMEBREW puts 'Updating homebrew cask, please wait...' system('brew cask update') if $CHILD_STATUS == 1 puts 'Cask update failed'.red exit! end # BREW CASK LIST IO.popen('brew cask list') do |apps| apps.each do |app| app.chomp! infosstr = app infos = `brew cask info #{app}` if vmatch = /: ([A-z0-9\._]+)/.match(infos.lines.first) version, build = vmatch[1].split(/[_-]/) infosstr += " version: #{version}" infosstr += " (#{build})" if build print infosstr.to_s column1length = 80 - infosstr.gsub(/\e\[[0-9;]+[m]?/, '').length if appname = /(.+) \(app\)/.match(infos) # APPLICATION FILENAME appname = appname[1].strip fullpath = `mdfind -onlyin /opt/homebrew-cask/Caskroom -onlyin /Applications -onlyin ~/Applications "#{appname}" | grep "#{appname}"`.strip if File.exist?(fullpath) # GET APPLICATION VERSION WITH SPOTLIGHT if currentmatch = /([A-z0-9\.]+)/.match(`mdls "#{fullpath}" -name kMDItemVersion -raw`) current = currentmatch[1].chomp # COMPARE INSTALLED VERSION WITH CASK VERSION begin if Gem::Version.new(version) <= Gem::Version.new(current) puts 'Up-to-date'.rjust(column1length) elsif current != '(null)' && version != 'latest' puts 'Update available'.rjust(column1length) print "Do you want to update #{app} to version #{version.green} (current #{current.green})? " + '[y/N] ' if options[:auto] update = 'y' else update = STDIN.gets.strip end # UPDATE CURRENT APPLICAION if update =~ /[yY]/ puts "Updating #{app} to version #{version}" puts "Closing any open instances of #{app}" system("osascript -e \'quit app \"#{app}\"\' && sleep 1") system("brew cask uninstall #{app} --force && sleep 1 && brew cask install #{app} --force") else puts 'Cancelling update' end else puts 'Update undefined'.rjust(column1length) end rescue puts 'Cannot determine latest version'.rjust(column1length) end else puts 'Unknown installed version'.rjust(column1length) end else puts 'Not found'.rjust(column1length) end else puts 'Unknown app'.rjust(column1length) end else print infosstr.to_s column1length = 80 - infosstr.length puts 'Unknown version'.rjust(column1length) end end end