Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Brew Cask Check Versions

Homebrew Cask doesn’t yet check for new versions. Below is a hacked together script that does just that. This is very rough and is only intended as a stop-gap until the Cask developers complete the real functionality.

Updated Sep 19, 2014: Found and fixed some errors and added command-line parameters (-v for verbose checking and you can pass a cask name to check one specific cask).

#!/usr/bin/env ruby
require 'nokogiri'
require 'open-uri'
require 'optparse'

CASK_DIR = '/usr/local/Library/Taps/caskroom/homebrew-cask/Casks'

# Force one version to be treated as another. Used when the local version and appcast version don't match up.
VERSION_MAPPING = {
	'alfred' => [['2.4_279', '2.4']]
}

def extract_version(content)
	content.split(/\n/).find {|line| line.strip =~ /^[0-9].*/}
end

options = {}
OptionParser.new do |opts|
  opts.banner = "Usage: check_versions.rb [options] [cask-name]"

  opts.on("-v", "--verbose", "Run verbosely") do |v|
    options[:verbose] = v
  end
end.parse!

target_cask_name = ARGV[0] if ARGV.size > 0

# if a cask name was given on the command line, just check that one cask
if target_cask_name.nil?
	cask_list = `brew cask list -1`.split(/\n/)
else
	cask_list = [target_cask_name]
end

cask_list.each do |cask_name|
	puts "Checking app #{cask_name}" if options[:verbose]

	# get the cask version and app location from the cask formula
	results = `brew cask info #{cask_name}`.split(/\n/)
	cask_version = results[0].split(':')[1].strip
	puts "    Cask version #{cask_version}" if options[:verbose]
	app_line = results.find {|line| line =~ /\.app \(/ }

	if app_line
    	cask_location = "#{CASK_DIR}/#{cask_name}.rb"
		app_location = app_line.gsub(/\(link\)/, '').split(/\//)[-1].strip

		# check for the installed app version in two places, prefer the short version string to the long
		short_local_version = extract_version(`defaults read "/Applications/#{app_location}/Contents/Info.plist" CFBundleShortVersionString 2>/dev/null`)
		long_local_version = extract_version(`defaults read "/Applications/#{app_location}/Contents/Info.plist" CFBundleVersion 2>/dev/null`)
		local_version = short_local_version || long_local_version

		puts "    Installed app version #{local_version}" if options[:verbose]

		if File.exists?(cask_location)
			# since the appcast stanza doesn't show up in 'brew cask info', parse it from the formula file
			appcast_line = File.open(cask_location).find {|line| line =~ /[\w]*appcast .*/}
			if appcast_line
				appcast_url = appcast_line.split("'")[1]
				puts "    Checking for sparkle info at #{appcast_url}" if options[:verbose]
				# download the sparkle xml and parse it
				doc = Nokogiri::HTML(open(appcast_url))
				# attempt to locate the newest version in the xml
				cur_version = '0'
				appcast_version = nil
				doc.xpath('//rss/channel/item/enclosure').each do |ele|
					# spark:version _should_ be comparable
					item_version = ele['sparkle:version']
					begin
						if Gem::Version.new(item_version) > Gem::Version.new(cur_version)
							cur_version = item_version
							appcast_version = ele['sparkle:shortversionstring'] || item_version
						end
					rescue
						# if the spark:version isn't comparable, just assume this item is newer then the previous
						cur_version = item_version
					end
				end
				puts "    Appcast version #{appcast_version}" if options[:verbose]
			else
				puts "    No appcast entry for app" if options[:verbose]
			end
		end

		# the latest version is the sparkle version if present, otherwise it's the cask formula version
		latest_version = appcast_version || cask_version

		# check for a version override in the VERSION_MAPPING entries
		mapping = VERSION_MAPPING[cask_name]
		compare_version = latest_version
		if mapping
			match_version = mapping.find {|entry| entry[0] == latest_version}
			if match_version
				compare_version = match_version[1]
			end
		end

		# it all comes down to this, try to determine if there's a newer version. if the version numbers can't be
		# parsed, just do a straight comparison.
		begin
			if (latest_version != 'latest') && (Gem::Version.new(compare_version) > Gem::Version.new(local_version))
				puts "#{cask_name} : latest version #{latest_version}, local version #{local_version}"
			end
		rescue
			if (latest_version != 'latest') && (compare_version.strip != local_version.strip)
				puts "#{cask_name} : latest version #{latest_version}, local version #{local_version}"
			end
		end
	end
end


This post first appeared on Ted Wise, please read the originial post: here

Share the post

Brew Cask Check Versions

×

Subscribe to Ted Wise

Get updates delivered right to your inbox!

Thank you for your subscription

×