2018-09-03 19:39:07 +01:00
|
|
|
require "cask/cask"
|
2018-03-07 16:14:55 +00:00
|
|
|
require "uri"
|
|
|
|
|
2018-09-06 08:29:14 +02:00
|
|
|
module Cask
|
2017-03-12 19:18:41 +01:00
|
|
|
module CaskLoader
|
|
|
|
class FromContentLoader
|
2017-06-28 09:25:14 +02:00
|
|
|
attr_reader :content
|
|
|
|
|
2017-10-08 15:20:58 +02:00
|
|
|
def self.can_load?(ref)
|
|
|
|
return false unless ref.respond_to?(:to_str)
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2017-10-08 15:20:58 +02:00
|
|
|
content = ref.to_str
|
|
|
|
|
|
|
|
token = /(?:"[^"]*"|'[^']*')/
|
|
|
|
curly = /\(\s*#{token}\s*\)\s*\{.*\}/
|
|
|
|
do_end = /\s+#{token}\s+do(?:\s*;\s*|\s+).*end/
|
|
|
|
regex = /\A\s*cask(?:#{curly.source}|#{do_end.source})\s*\Z/m
|
|
|
|
|
|
|
|
content.match?(regex)
|
|
|
|
end
|
|
|
|
|
2017-03-12 19:18:41 +01:00
|
|
|
def initialize(content)
|
2018-02-13 17:23:49 +01:00
|
|
|
@content = content.force_encoding("UTF-8")
|
2017-03-12 19:18:41 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def load
|
2018-02-13 17:23:49 +01:00
|
|
|
instance_eval(content, __FILE__, __LINE__)
|
2017-03-12 19:18:41 +01:00
|
|
|
end
|
2016-10-08 13:25:38 +02:00
|
|
|
|
2017-03-12 19:18:41 +01:00
|
|
|
private
|
2016-10-08 13:25:38 +02:00
|
|
|
|
2017-07-29 16:27:54 +02:00
|
|
|
def cask(header_token, **options, &block)
|
|
|
|
Cask.new(header_token, **options, &block)
|
2017-03-12 19:18:41 +01:00
|
|
|
end
|
2016-10-08 13:25:38 +02:00
|
|
|
end
|
|
|
|
|
2017-03-12 19:18:41 +01:00
|
|
|
class FromPathLoader < FromContentLoader
|
|
|
|
def self.can_load?(ref)
|
2017-06-28 09:25:14 +02:00
|
|
|
path = Pathname(ref)
|
2017-03-12 19:18:41 +01:00
|
|
|
path.extname == ".rb" && path.expand_path.exist?
|
|
|
|
end
|
|
|
|
|
|
|
|
attr_reader :token, :path
|
|
|
|
|
|
|
|
def initialize(path)
|
2017-06-28 09:25:14 +02:00
|
|
|
path = Pathname(path).expand_path
|
2017-03-12 19:18:41 +01:00
|
|
|
|
|
|
|
@token = path.basename(".rb").to_s
|
|
|
|
@path = path
|
|
|
|
end
|
|
|
|
|
|
|
|
def load
|
2017-06-28 09:25:14 +02:00
|
|
|
raise CaskUnavailableError.new(token, "'#{path}' does not exist.") unless path.exist?
|
|
|
|
raise CaskUnavailableError.new(token, "'#{path}' is not readable.") unless path.readable?
|
|
|
|
raise CaskUnavailableError.new(token, "'#{path}' is not a file.") unless path.file?
|
2017-03-12 19:18:41 +01:00
|
|
|
|
2017-06-28 09:25:14 +02:00
|
|
|
@content = IO.read(path)
|
2017-03-12 19:18:41 +01:00
|
|
|
|
2018-07-29 11:05:23 +02:00
|
|
|
begin
|
|
|
|
instance_eval(content, path).tap do |cask|
|
2019-02-19 13:11:32 +00:00
|
|
|
raise CaskUnreadableError.new(token, "'#{path}' does not contain a cask.") unless cask.is_a?(Cask)
|
2018-07-29 11:05:23 +02:00
|
|
|
end
|
|
|
|
rescue NameError, ArgumentError, ScriptError => e
|
|
|
|
raise CaskUnreadableError.new(token, e.message)
|
|
|
|
end
|
2017-03-12 19:18:41 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2017-07-29 16:27:54 +02:00
|
|
|
def cask(header_token, **options, &block)
|
2019-02-19 13:11:32 +00:00
|
|
|
raise CaskTokenMismatchError.new(token, header_token) if token != header_token
|
2017-03-12 19:18:41 +01:00
|
|
|
|
2017-07-29 16:27:54 +02:00
|
|
|
super(header_token, **options, sourcefile_path: path, &block)
|
2017-03-12 19:18:41 +01:00
|
|
|
end
|
2016-10-08 13:25:38 +02:00
|
|
|
end
|
|
|
|
|
2017-03-12 19:18:41 +01:00
|
|
|
class FromURILoader < FromPathLoader
|
|
|
|
def self.can_load?(ref)
|
2017-10-08 15:20:58 +02:00
|
|
|
uri_regex = ::URI::DEFAULT_PARSER.make_regexp
|
|
|
|
ref.to_s.match?(Regexp.new('\A' + uri_regex.source + '\Z', uri_regex.options))
|
2017-03-12 19:18:41 +01:00
|
|
|
end
|
|
|
|
|
2017-06-11 02:00:59 +02:00
|
|
|
attr_reader :url
|
|
|
|
|
2017-03-12 19:18:41 +01:00
|
|
|
def initialize(url)
|
2017-06-11 02:00:59 +02:00
|
|
|
@url = URI(url)
|
2018-06-09 09:42:49 +02:00
|
|
|
super Cache.path/File.basename(@url.path)
|
2017-03-12 19:18:41 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def load
|
2017-06-28 09:25:14 +02:00
|
|
|
path.dirname.mkpath
|
2017-03-12 19:18:41 +01:00
|
|
|
|
|
|
|
begin
|
2017-06-28 09:25:14 +02:00
|
|
|
ohai "Downloading #{url}."
|
2017-08-08 18:10:13 +02:00
|
|
|
curl_download url, to: path
|
2017-03-12 19:18:41 +01:00
|
|
|
rescue ErrorDuringExecution
|
2017-06-28 09:25:14 +02:00
|
|
|
raise CaskUnavailableError.new(token, "Failed to download #{Formatter.url(url)}.")
|
2017-03-12 19:18:41 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
super
|
|
|
|
end
|
2016-10-08 13:25:38 +02:00
|
|
|
end
|
|
|
|
|
2017-07-29 16:27:54 +02:00
|
|
|
class FromTapPathLoader < FromPathLoader
|
2017-03-12 19:18:41 +01:00
|
|
|
def self.can_load?(ref)
|
2018-03-29 22:05:02 +02:00
|
|
|
super && !Tap.from_path(ref).nil?
|
2017-03-12 19:18:41 +01:00
|
|
|
end
|
|
|
|
|
2017-06-28 09:25:14 +02:00
|
|
|
attr_reader :tap
|
|
|
|
|
2018-03-29 22:05:02 +02:00
|
|
|
def initialize(path)
|
|
|
|
@tap = Tap.from_path(path)
|
|
|
|
super(path)
|
2017-07-29 16:27:54 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def cask(*args, &block)
|
|
|
|
super(*args, tap: tap, &block)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class FromTapLoader < FromTapPathLoader
|
|
|
|
def self.can_load?(ref)
|
|
|
|
ref.to_s.match?(HOMEBREW_TAP_CASK_REGEX)
|
|
|
|
end
|
|
|
|
|
2017-03-12 19:18:41 +01:00
|
|
|
def initialize(tapped_name)
|
2017-06-28 09:25:14 +02:00
|
|
|
user, repo, token = tapped_name.split("/", 3)
|
2017-07-29 16:27:54 +02:00
|
|
|
super Tap.fetch(user, repo).cask_dir/"#{token}.rb"
|
2017-03-12 19:18:41 +01:00
|
|
|
end
|
2016-10-08 13:25:38 +02:00
|
|
|
|
2017-03-12 19:18:41 +01:00
|
|
|
def load
|
2017-06-28 09:25:14 +02:00
|
|
|
tap.install unless tap.installed?
|
2017-03-12 19:18:41 +01:00
|
|
|
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-09-11 08:37:15 +02:00
|
|
|
class FromInstanceLoader
|
|
|
|
attr_reader :cask
|
|
|
|
|
|
|
|
def self.can_load?(ref)
|
|
|
|
ref.is_a?(Cask)
|
|
|
|
end
|
|
|
|
|
|
|
|
def initialize(cask)
|
|
|
|
@cask = cask
|
|
|
|
end
|
|
|
|
|
|
|
|
def load
|
|
|
|
cask
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-03-12 19:18:41 +01:00
|
|
|
class NullLoader < FromPathLoader
|
|
|
|
def self.can_load?(*)
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
|
|
|
def initialize(ref)
|
2017-06-28 09:25:14 +02:00
|
|
|
token = File.basename(ref, ".rb")
|
|
|
|
super CaskLoader.default_path(token)
|
2017-03-12 19:18:41 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def load
|
2017-06-28 09:25:14 +02:00
|
|
|
raise CaskUnavailableError.new(token, "No Cask with this name exists.")
|
2017-03-12 19:18:41 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.path(ref)
|
|
|
|
self.for(ref).path
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.load(ref)
|
|
|
|
self.for(ref).load
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.for(ref)
|
|
|
|
[
|
2017-09-11 08:37:15 +02:00
|
|
|
FromInstanceLoader,
|
2017-10-08 15:20:58 +02:00
|
|
|
FromContentLoader,
|
2017-03-12 19:18:41 +01:00
|
|
|
FromURILoader,
|
|
|
|
FromTapLoader,
|
2017-07-29 16:27:54 +02:00
|
|
|
FromTapPathLoader,
|
2017-03-12 19:18:41 +01:00
|
|
|
FromPathLoader,
|
|
|
|
].each do |loader_class|
|
|
|
|
return loader_class.new(ref) if loader_class.can_load?(ref)
|
|
|
|
end
|
|
|
|
|
2019-02-19 13:11:32 +00:00
|
|
|
return FromTapPathLoader.new(default_path(ref)) if FromTapPathLoader.can_load?(default_path(ref))
|
2016-10-08 13:25:38 +02:00
|
|
|
|
2017-07-29 16:27:54 +02:00
|
|
|
case (possible_tap_casks = tap_paths(ref)).count
|
|
|
|
when 1
|
|
|
|
return FromTapPathLoader.new(possible_tap_casks.first)
|
|
|
|
when 2..Float::INFINITY
|
|
|
|
loaders = possible_tap_casks.map(&FromTapPathLoader.method(:new))
|
|
|
|
|
2017-10-15 02:28:32 +02:00
|
|
|
raise CaskError, <<~EOS
|
2017-07-29 16:27:54 +02:00
|
|
|
Cask #{ref} exists in multiple taps:
|
|
|
|
#{loaders.map { |loader| " #{loader.tap}/#{loader.token}" }.join("\n")}
|
|
|
|
EOS
|
2016-10-08 13:25:38 +02:00
|
|
|
end
|
2017-03-12 19:18:41 +01:00
|
|
|
|
|
|
|
possible_installed_cask = Cask.new(ref)
|
2019-02-19 13:11:32 +00:00
|
|
|
return FromPathLoader.new(possible_installed_cask.installed_caskfile) if possible_installed_cask.installed?
|
2017-03-12 19:18:41 +01:00
|
|
|
|
|
|
|
NullLoader.new(ref)
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.default_path(token)
|
2018-06-09 10:13:28 +02:00
|
|
|
Tap.default_cask_tap.cask_dir/"#{token.to_s.downcase}.rb"
|
2017-03-12 19:18:41 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.tap_paths(token)
|
|
|
|
Tap.map { |t| t.cask_dir/"#{token.to_s.downcase}.rb" }
|
|
|
|
.select(&:exist?)
|
2016-10-08 13:25:38 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|