diff --git a/lib/cask/dsl.rb b/lib/cask/dsl.rb index 14d6d63b81..426413f188 100644 --- a/lib/cask/dsl.rb +++ b/lib/cask/dsl.rb @@ -22,16 +22,25 @@ module Cask::DSL module ClassMethods def homepage(homepage=nil) + if @homepage and !homepage.nil? + raise CaskInvalidError.new(self.title, "'homepage' stanza may only appear once") + end @homepage ||= homepage end def url(*args) + if @url and !args.empty? + raise CaskInvalidError.new(self.title, "'url' stanza may only appear once") + end @url ||= begin Cask::URL.new(*args) unless args.empty? end end def version(version=nil) + if @version and !version.nil? + raise CaskInvalidError.new(self.title, "'version' stanza may only appear once") + end @version ||= version end @@ -100,22 +109,38 @@ module Cask::DSL attr_reader :sums + def hash_name(hash_type) + hash_type.to_s == 'sha2' ? 'sha256' : hash_type.to_s + end + def md5(md5=nil) + if @sums == 0 + raise CaskInvalidError.new(self.title, "'no_checksum' stanza conflicts with 'md5'") + end @sums ||= [] @sums << Checksum.new(:md5, md5) unless md5.nil? end def sha1(sha1=nil) + if @sums == 0 + raise CaskInvalidError.new(self.title, "'no_checksum' stanza conflicts with 'sha1'") + end @sums ||= [] @sums << Checksum.new(:sha1, sha1) unless sha1.nil? end def sha256(sha2=nil) + if @sums == 0 + raise CaskInvalidError.new(self.title, "'no_checksum' stanza conflicts with 'sha256'") + end @sums ||= [] @sums << Checksum.new(:sha2, sha2) unless sha2.nil? end def no_checksum + unless @sums.nil? or @sums.empty? + raise CaskInvalidError.new(self.title, "'no_checksum' stanza conflicts with '#{hash_name(@sums.first.hash_type)}'") + end @sums = 0 end diff --git a/lib/cask/exceptions.rb b/lib/cask/exceptions.rb index 12f4f028e3..ff19c265d1 100644 --- a/lib/cask/exceptions.rb +++ b/lib/cask/exceptions.rb @@ -68,3 +68,15 @@ class CaskUnspecifiedError < CaskError "This command requires a cask's name" end end + +class CaskInvalidError < CaskError + attr_reader :name, :submsg + def initialize(name, *submsg) + @name = name + @submsg = submsg.join(' ') + end + + def to_s + "Cask '#{name}' definition is invalid" + (submsg.length > 0 ? ": #{submsg}" : '') + end +end diff --git a/test/cask/dsl_test.rb b/test/cask/dsl_test.rb index 1883e01a5a..4be0adcd84 100644 --- a/test/cask/dsl_test.rb +++ b/test/cask/dsl_test.rb @@ -92,4 +92,39 @@ describe Cask::DSL do instance = CaskWithInstallables.new Array(instance.artifacts[:install]).sort.must_equal %w[Bar.pkg Foo.pkg] end + + it "prevents defining multiple urls" do + err = lambda { + invalid_cask = Cask.load('invalid/invalid-two-url') + }.must_raise(CaskInvalidError) + err.message.must_include "'url' stanza may only appear once" + end + + it "prevents defining multiple homepages" do + err = lambda { + invalid_cask = Cask.load('invalid/invalid-two-homepage') + }.must_raise(CaskInvalidError) + err.message.must_include "'homepage' stanza may only appear once" + end + + it "prevents defining multiple versions" do + err = lambda { + invalid_cask = Cask.load('invalid/invalid-two-version') + }.must_raise(CaskInvalidError) + err.message.must_include "'version' stanza may only appear once" + end + + it "prevents defining conflicting checksums (first order)" do + err = lambda { + invalid_cask = Cask.load('invalid/invalid-checksum-conflict1') + }.must_raise(CaskInvalidError) + err.message.must_include "'no_checksum' stanza conflicts with" + end + + it "prevents defining conflicting checksums (second order)" do + err = lambda { + invalid_cask = Cask.load('invalid/invalid-checksum-conflict2') + }.must_raise(CaskInvalidError) + err.message.must_include "'no_checksum' stanza conflicts with" + end end diff --git a/test/cask_test.rb b/test/cask_test.rb index 35fc014038..1c8e192125 100644 --- a/test/cask_test.rb +++ b/test/cask_test.rb @@ -9,6 +9,9 @@ describe "Cask" do end it "returns an instance of the cask from a specific file location" do + if Object.constants.include?(:Dia) + Object.send(:remove_const, :Dia) + end location = File.expand_path('./Casks/dia.rb') c = Cask.load(location) c.must_be_kind_of(Cask) @@ -16,6 +19,9 @@ describe "Cask" do end it "returns an instance of the cask from a url" do + if Object.constants.include?(:Dia) + Object.send(:remove_const, :Dia) + end url = "file://" + File.expand_path('./Casks/dia.rb') c = shutup do Cask.load(url) @@ -34,9 +40,12 @@ describe "Cask" do end it "returns an instance of the cask from a relative file location" do - c = Cask.load("./Casks/dia.rb") + if Object.constants.include?(:Bbedit) + Object.send(:remove_const, :Bbedit) + end + c = Cask.load("./Casks/bbedit.rb") c.must_be_kind_of(Cask) - c.must_be_instance_of(Dia) + c.must_be_instance_of(Bbedit) end it "uses exact match when loading by name" do diff --git a/test/support/Casks/invalid/invalid-checksum-conflict1.rb b/test/support/Casks/invalid/invalid-checksum-conflict1.rb new file mode 100644 index 0000000000..541aacb7c5 --- /dev/null +++ b/test/support/Casks/invalid/invalid-checksum-conflict1.rb @@ -0,0 +1,8 @@ +class InvalidChecksumConflict1 < TestCask + url TestHelper.local_binary('caffeine.zip') + homepage 'http://example.com/local-caffeine' + version '1.2.3' + sha1 'd2fbdad1619934313026fc831e6c6e3dd97ac030' + no_checksum + link 'Caffeine.app' +end diff --git a/test/support/Casks/invalid/invalid-checksum-conflict2.rb b/test/support/Casks/invalid/invalid-checksum-conflict2.rb new file mode 100644 index 0000000000..bc4c8ff2de --- /dev/null +++ b/test/support/Casks/invalid/invalid-checksum-conflict2.rb @@ -0,0 +1,8 @@ +class InvalidChecksumConflict2 < TestCask + url TestHelper.local_binary('caffeine.zip') + homepage 'http://example.com/local-caffeine' + version '1.2.3' + no_checksum + sha1 'd2fbdad1619934313026fc831e6c6e3dd97ac030' + link 'Caffeine.app' +end diff --git a/test/support/Casks/invalid/invalid-two-homepage.rb b/test/support/Casks/invalid/invalid-two-homepage.rb new file mode 100644 index 0000000000..cd43c1d8f0 --- /dev/null +++ b/test/support/Casks/invalid/invalid-two-homepage.rb @@ -0,0 +1,9 @@ +class InvalidTwoHomepage < TestCask + url TestHelper.local_binary('caffeine.zip') + homepage 'http://example.com/local-caffeine' + homepage 'http://www.example.com/local-caffeine' + version '1.2.3' + sha1 'd2fbdad1619934313026fc831e6c6e3dd97ac030' + + link 'Caffeine.app' +end diff --git a/test/support/Casks/invalid/invalid-two-url.rb b/test/support/Casks/invalid/invalid-two-url.rb new file mode 100644 index 0000000000..e3e0db2e63 --- /dev/null +++ b/test/support/Casks/invalid/invalid-two-url.rb @@ -0,0 +1,9 @@ +class InvalidTwoUrl < TestCask + url TestHelper.local_binary('caffeine.zip') + url 'http://example.com/caffeine.zip' + homepage 'http://example.com/local-caffeine' + version '1.2.3' + sha1 'd2fbdad1619934313026fc831e6c6e3dd97ac030' + + link 'Caffeine.app' +end diff --git a/test/support/Casks/invalid/invalid-two-version.rb b/test/support/Casks/invalid/invalid-two-version.rb new file mode 100644 index 0000000000..00f1aa0d6b --- /dev/null +++ b/test/support/Casks/invalid/invalid-two-version.rb @@ -0,0 +1,9 @@ +class InvalidTwoVersion < TestCask + url TestHelper.local_binary('caffeine.zip') + homepage 'http://example.com/local-caffeine' + version '1.2.3' + version '2.0' + sha1 'd2fbdad1619934313026fc831e6c6e3dd97ac030' + + link 'Caffeine.app' +end