mirror of
https://github.com/donl/homebrew-cask-versions.git
synced 2026-07-16 14:26:53 -06:00
Hbc is the namespace, Hbc::Cask is the object representing a Cask One step on the path to reducing the surface area of the God-object we've grown over the years. :)
102 lines
3.3 KiB
Ruby
102 lines
3.3 KiB
Ruby
require 'rubygems'
|
|
|
|
class Hbc::Source::PathBase
|
|
|
|
# derived classes must define method self.me?
|
|
|
|
def self.path_for_query(query)
|
|
path_string = "#{query}"
|
|
path_string.concat('.rb') unless path_string.match(%r{\.rb\Z}i)
|
|
Pathname.new(path_string)
|
|
end
|
|
|
|
attr_reader :path
|
|
|
|
def initialize(path)
|
|
@path = Pathname(path).expand_path
|
|
end
|
|
|
|
def load
|
|
raise Hbc::CaskError.new "File '#{path}' does not exist" unless path.exist?
|
|
raise Hbc::CaskError.new "File '#{path}' is not readable" unless path.readable?
|
|
raise Hbc::CaskError.new "File '#{path}' is not a plain file" unless path.file?
|
|
begin
|
|
|
|
# transitional hack: convert first lines of the new form
|
|
#
|
|
# cask :v1 => 'google-chrome' do
|
|
#
|
|
# to the old form
|
|
#
|
|
# class GoogleChrome < Hbc (class GoogleChrome < Cask)
|
|
#
|
|
# limitation: does not support Ruby extended quoting such as %Q{}
|
|
#
|
|
# todo: in the future, this can be pared down to an "eval"
|
|
|
|
# read Cask
|
|
cask_contents = File.open(path, 'rb') do |handle|
|
|
contents = handle.read
|
|
if defined?(Encoding)
|
|
contents.force_encoding('UTF-8')
|
|
else
|
|
contents
|
|
end
|
|
end
|
|
|
|
# munge text
|
|
cask_contents.sub!(%r{\A(\s*\#[^\n]*\n)+}, '');
|
|
if %r{\A\s*cask\s+:v([\d_]+)(test)?\s+=>\s+([\'\"])(\S+?)\3(?:\s*,\s*|\s+)do\s*\n}.match(cask_contents)
|
|
dsl_version_string = $1
|
|
is_test = ! $2.nil?
|
|
header_token = $4
|
|
dsl_version = Gem::Version.new(dsl_version_string.gsub('_','.'))
|
|
superclass_name = is_test ? 'Hbc::TestCask' : 'Hbc::Cask'
|
|
cask_contents.sub!(%r{\A[^\n]+\n}, "class #{cask_class_name} < #{superclass_name}\n")
|
|
# todo the minimum DSL version should be defined globally elsewhere
|
|
minimum_dsl_version = Gem::Version.new('1.0')
|
|
unless dsl_version >= minimum_dsl_version
|
|
raise Hbc::CaskInvalidError.new(cask_token, "Bad header line: 'v#{dsl_version_string}' is less than required minimum version '#{minimum_dsl_version}'")
|
|
end
|
|
if header_token != cask_token
|
|
raise Hbc::CaskInvalidError.new(cask_token, "Bad header line: '#{header_token}' does not match file name")
|
|
end
|
|
else
|
|
raise Hbc::CaskInvalidError.new(cask_token, "Bad header line: parse failed")
|
|
end
|
|
|
|
# simulate "require"
|
|
begin
|
|
Object.const_get(cask_class_name)
|
|
rescue NameError
|
|
eval(cask_contents, TOPLEVEL_BINDING)
|
|
end
|
|
|
|
rescue Hbc::CaskError, StandardError, ScriptError => e
|
|
# bug: e.message.concat doesn't work with Hbc::CaskError exceptions
|
|
e.message.concat(" while loading '#{path}'")
|
|
raise e
|
|
end
|
|
begin
|
|
Object.const_get(cask_class_name).new(path)
|
|
rescue Hbc::CaskError, StandardError, ScriptError => e
|
|
# bug: e.message.concat doesn't work with Hbc::CaskError exceptions
|
|
e.message.concat(" while instantiating '#{cask_class_name}' from '#{path}'")
|
|
raise e
|
|
end
|
|
end
|
|
|
|
def cask_token
|
|
path.basename.to_s.sub(/\.rb/, '')
|
|
end
|
|
|
|
def cask_class_name
|
|
# todo removeme: prepending KlassPrefix is transitional as we move away from representing Casks as classes
|
|
'KlassPrefix'.concat cask_token.split('-').map(&:capitalize).join
|
|
end
|
|
|
|
def to_s
|
|
# stringify to fully-resolved location
|
|
path.to_s
|
|
end
|
|
end
|