diff --git a/Library/Homebrew/cask/lib/hbc/cask.rb b/Library/Homebrew/cask/lib/hbc/cask.rb index a2f2a08787..0a68ffe92b 100644 --- a/Library/Homebrew/cask/lib/hbc/cask.rb +++ b/Library/Homebrew/cask/lib/hbc/cask.rb @@ -17,7 +17,11 @@ module Hbc return to_enum unless block_given? Tap.flat_map(&:cask_files).each do |f| - yield CaskLoader::FromTapPathLoader.new(f).load + begin + yield CaskLoader::FromTapPathLoader.new(f).load + rescue CaskUnreadableError => e + opoo e.message + end end end diff --git a/Library/Homebrew/cask/lib/hbc/cask_loader.rb b/Library/Homebrew/cask/lib/hbc/cask_loader.rb index 1c41a80691..8c42744f05 100644 --- a/Library/Homebrew/cask/lib/hbc/cask_loader.rb +++ b/Library/Homebrew/cask/lib/hbc/cask_loader.rb @@ -54,7 +54,15 @@ module Hbc @content = IO.read(path) - instance_eval(content, path) + begin + instance_eval(content, path).tap do |cask| + unless cask.is_a?(Cask) + raise CaskUnreadableError.new(token, "'#{path}' does not contain a cask.") + end + end + rescue NameError, ArgumentError, ScriptError => e + raise CaskUnreadableError.new(token, e.message) + end end private diff --git a/Library/Homebrew/cask/lib/hbc/exceptions.rb b/Library/Homebrew/cask/lib/hbc/exceptions.rb index 243dc458dd..f5e6649e0e 100644 --- a/Library/Homebrew/cask/lib/hbc/exceptions.rb +++ b/Library/Homebrew/cask/lib/hbc/exceptions.rb @@ -36,6 +36,12 @@ module Hbc end end + class CaskUnreadableError < CaskUnavailableError + def to_s + "Cask '#{token}' is unreadable" << (reason.empty? ? "." : ": #{reason}") + end + end + class CaskAlreadyCreatedError < AbstractCaskErrorWithToken def to_s %Q(Cask '#{token}' already exists. Run #{Formatter.identifier("brew cask edit #{token}")} to edit it.) diff --git a/Library/Homebrew/test/cask/cask_loader/from__path_loader_spec.rb b/Library/Homebrew/test/cask/cask_loader/from__path_loader_spec.rb new file mode 100644 index 0000000000..e1b718e5a7 --- /dev/null +++ b/Library/Homebrew/test/cask/cask_loader/from__path_loader_spec.rb @@ -0,0 +1,35 @@ +describe Hbc::CaskLoader::FromPathLoader do + describe "#load" do + context "when the file does not contain a cask" do + let(:path) { + (mktmpdir/"cask.rb").tap do |path| + path.write <<~RUBY + true + RUBY + end + } + + it "raises an error" do + expect { + described_class.new(path).load + }.to raise_error(Hbc::CaskUnreadableError, /does not contain a cask/) + end + end + + context "when the file calls a non-existent method" do + let(:path) { + (mktmpdir/"cask.rb").tap do |path| + path.write <<~RUBY + this_method_does_not_exist + RUBY + end + } + + it "raises an error" do + expect { + described_class.new(path).load + }.to raise_error(Hbc::CaskUnreadableError, /undefined local variable or method/) + end + end + end +end diff --git a/Library/Homebrew/test/cask/dsl_spec.rb b/Library/Homebrew/test/cask/dsl_spec.rb index 21684bf2c9..a40d4c972c 100644 --- a/Library/Homebrew/test/cask/dsl_spec.rb +++ b/Library/Homebrew/test/cask/dsl_spec.rb @@ -46,7 +46,7 @@ describe Hbc::DSL, :cask do let(:token) { "invalid/invalid-header-format" } it "raises an error" do - expect { cask }.to raise_error(SyntaxError) + expect { cask }.to raise_error(Hbc::CaskUnreadableError) end end