Skip to content

Commit

Permalink
DSL: depends_on :arch functionality/tests/doc
Browse files Browse the repository at this point in the history
* fill in functionality for the `depends_on :arch` stub
* de-document `caveats` method `arch_only`
  • Loading branch information
rolandwalker committed Dec 4, 2014
1 parent e554202 commit 7f5e512
Show file tree
Hide file tree
Showing 12 changed files with 167 additions and 20 deletions.
37 changes: 35 additions & 2 deletions doc/CASK_LANGUAGE_REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,6 @@ The following methods may be called to generate standard warning messages:
| `reboot` | users should reboot to complete installation
| `assistive_devices` | users should grant the application access to assistive devices
| `files_in_usr_local` | the Cask installs files to `/usr/local`, which may confuse Homebrew
| `arch_only(list)` | the Cask only supports certain architectures. Currently valid elements of `list` are `intel-32` and `intel-64`
| `x11_required` | the Cask requires X11 to run

Example:
Expand Down Expand Up @@ -586,6 +585,40 @@ depends_on :macos => '>= :mavericks'
depends_on :macos => '>= 10.9'
```

### Depends_on :arch

The value for `depends_on :arch` may be a symbol or an array of symbols,
listing the hardware compatibility requirements for a Cask. The requirement
is satisfied at install time if any one of multiple `:arch` value matches
the user's hardware.

The available symbols for hardware are:

| symbol | meaning |
| ---------- | -------------- |
| `:i386` | 32-bit Intel |
| `:x86_64` | 64-bit Intel |
| `:ppc_7400`| 32-bit PowerPC |
| `:ppc_64` | 64-bit PowerPC |
| `:intel` | Any Intel |
| `:ppc` | Any PowerPC |

The following are all valid expressions:

```ruby
depends_on :arch => :x86_64
depends_on :arch => [:x86_64] # same meaning as above
depends_on :arch => :intel
depends_on :arch => [:i386, :x86_64] # same meaning as above
```

Since PowerPC hardware is no longer common, the expression most
frequently needed will be:

```ruby
depends_on :arch => :x86_64
```

### All Depends_on Keys

Several other keys are accepted by `depends_on`, in anticipation of future
Expand All @@ -596,7 +629,7 @@ functionality:
| `:formula` | a Homebrew Formula
| `:cask` | *stub - not yet functional*
| `:macos` | a string, symbol, array, or expression defining OS X version requirements.
| `:arch` | *stub - not yet functional*
| `:arch` | a symbol or array defining hardware requirements.
| `:x11` | *stub - not yet functional*
| `:java` | *stub - not yet functional*

Expand Down
4 changes: 1 addition & 3 deletions doc/cask_language_deltas.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ features which are available for the current Cask.
* [`artifact`](CASK_LANGUAGE_REFERENCE.md#at-least-one-artifact-stanza-is-also-required)
* [`depends_on :cask`](CASK_LANGUAGE_REFERENCE.md#depends_on-stanza-details)
* *stub* - not yet functional
* [`depends_on :arch`](CASK_LANGUAGE_REFERENCE.md#depends_on-stanza-details)
* *stub* - not yet functional
* [`depends_on :x11`](CASK_LANGUAGE_REFERENCE.md#depends_on-stanza-details)
* *stub* - not yet functional
* [`depends_on :java`](CASK_LANGUAGE_REFERENCE.md#depends_on-stanza-details)
Expand Down Expand Up @@ -94,6 +92,7 @@ features which are available for the current Cask.
| `title` (in interpolations) | [`token`](CASK_LANGUAGE_REFERENCE.md#caveats-as-a-string)
| `uninstall :files` | [`uninstall :delete`](CASK_LANGUAGE_REFERENCE.md#uninstall-stanza-details)
| `version 'latest'` | [`version :latest`](CASK_LANGUAGE_REFERENCE.md#required-stanzas)
| `arch_only` (within `caveats`) | [`depends_on :arch`](CASK_LANGUAGE_REFERENCE.md#depends_on-stanza-details)


## All Supported Stanzas (1.0)
Expand Down Expand Up @@ -145,7 +144,6 @@ For use in *eg* interpolation:

## Caveats Mini-DSL (1.0)

* [`arch_only(list)`](CASK_LANGUAGE_REFERENCE.md#caveats-mini-dsl)
* [`assistive_devices`](CASK_LANGUAGE_REFERENCE.md#caveats-mini-dsl)
* [`files_in_usr_local`](CASK_LANGUAGE_REFERENCE.md#caveats-mini-dsl)
* [`logout`](CASK_LANGUAGE_REFERENCE.md#caveats-mini-dsl)
Expand Down
47 changes: 46 additions & 1 deletion lib/cask/dsl/depends_on.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,35 @@ class Cask::DSL::DependsOn
:java,
]

attr_accessor :formula, :cask, :arch, :x11, :java
VALID_ARCHES = Set.new [
# category
:intel,
:ppc,
# specific
:i386,
:x86_64,
:ppc_7400,
:ppc_64,
]

# Intentionally undocumented: catch variant spellings.
ARCH_SYNONYMS = {
:x86_32 => :i386,
:x8632 => :i386,
:x8664 => :x86_64,
:intel_32 => :i386,
:intel32 => :i386,
:intel_64 => :x86_64,
:intel64 => :x86_64,
:amd_64 => :x86_64,
:amd64 => :x86_64,
:ppc7400 => :ppc_7400,
:ppc_32 => :ppc_7400,
:ppc32 => :ppc_7400,
:ppc64 => :ppc_64,
}

attr_accessor :formula, :cask, :x11, :java
attr_accessor :pairs

def initialize(pairs={})
Expand Down Expand Up @@ -69,6 +97,23 @@ def macos=(arg)
@pairs[:macos] = @macos
end

def arch
@arch
end

def arch=(arg)
@arch = Array(arg).map do |elt|
elt = elt.to_s.downcase.sub(%r{^:},'').gsub('-','_').to_sym
ARCH_SYNONYMS.key?(elt) ? ARCH_SYNONYMS[elt] : elt
end
@arch.each do |elt|
unless VALID_ARCHES.include?(elt)
raise "invalid 'depends_on :arch' value: #{arg.inspect}"
end
end
@pairs[:arch] = @arch
end

def to_yaml
@pairs.to_yaml
end
Expand Down
16 changes: 16 additions & 0 deletions lib/cask/installer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ def install_artifacts
# override dependencies with --force or perhaps --force-deps
def satisfy_dependencies
macos_dependencies
arch_dependencies
formula_dependencies
end

Expand Down Expand Up @@ -133,6 +134,21 @@ def macos_dependencies
end
end

def arch_dependencies
if @cask.depends_on and
@cask.depends_on.arch
@current_arch ||= [
Hardware::CPU.type,
Hardware::CPU.is_32_bit? ?
(Hardware::CPU.intel? ? :i386 : :ppc_7400) :
(Hardware::CPU.intel? ? :x86_64 : :ppc_64)
]
if Array(@cask.depends_on.arch & @current_arch).count == 0
raise CaskError.new "Cask #{@cask} depends on hardware architecture being one of #{@cask.depends_on.arch.inspect}, but you are running #{@current_arch.inspect}"
end
end
end

def formula_dependencies
# todo The Cask::DependsOn object needs to be more friendly.
# Currently @cask.depends_on.formula raises an exception
Expand Down
18 changes: 18 additions & 0 deletions test/cask/depends_on_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,22 @@
}.must_raise(CaskError)
end
end

describe "depends_on :arch" do
it "succeeds when depends_on :arch is satisfied" do
arch_cask = Cask.load('with-depends-on-arch')
shutup do
Cask::Installer.new(arch_cask).install
end
end

it "raises an exception when depends_on :arch is not satisfied" do
arch_cask = Cask.load('with-depends-on-arch-failure')
lambda {
shutup do
Cask::Installer.new(arch_cask).install
end
}.must_raise(CaskError)
end
end
end
12 changes: 12 additions & 0 deletions test/cask/dsl_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,18 @@ def caveats; <<-EOS.undent
end
end

describe "depends_on :arch" do
it "allows depends_on :arch to be specified" do
cask = Cask.load('with-depends-on-arch')
cask.depends_on.arch.wont_be_nil
end
it "refuses to load with an invalid depends_on :arch value" do
err = lambda {
invalid_cask = Cask.load('invalid/invalid-depends-on-arch-value')
}.must_raise(CaskInvalidError)
end
end

describe "conflicts_with stanza" do
it "allows conflicts_with stanza to be specified" do
cask = Cask.load('with-conflicts-with')
Expand Down
8 changes: 4 additions & 4 deletions test/cask/installer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
it "works with cab-based Casks" do
skip unless HOMEBREW_PREFIX.join('bin/cabextract').exist?
cab_container = Cask.load('cab-container')
empty = stub(:formula => [], :macos => nil)
empty = stub(:formula => [], :macos => nil, :arch => nil)
cab_container.stubs(:depends_on).returns(empty)

shutup do
Expand Down Expand Up @@ -72,7 +72,7 @@
it "works with 7z-based Casks" do
skip unless HOMEBREW_PREFIX.join('bin/unar').exist?
sevenzip_container = Cask.load('sevenzip-container')
empty = stub(:formula => [], :macos => nil)
empty = stub(:formula => [], :macos => nil, :arch => nil)
sevenzip_container.stubs(:depends_on).returns(empty)

shutup do
Expand Down Expand Up @@ -101,7 +101,7 @@
it "works with Stuffit-based Casks" do
skip unless HOMEBREW_PREFIX.join('bin/unar').exist?
stuffit_container = Cask.load('stuffit-container')
empty = stub(:formula => [], :macos => nil)
empty = stub(:formula => [], :macos => nil, :arch => nil)
stuffit_container.stubs(:depends_on).returns(empty)

shutup do
Expand All @@ -117,7 +117,7 @@
it "works with RAR-based Casks" do
skip unless HOMEBREW_PREFIX.join('bin/unar').exist?
rar_container = Cask.load('rar-container')
empty = stub(:formula => [], :macos => nil)
empty = stub(:formula => [], :macos => nil, :arch => nil)
rar_container.stubs(:depends_on).returns(empty)

shutup do
Expand Down
11 changes: 11 additions & 0 deletions test/support/Casks/invalid/invalid-depends-on-arch-value.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
cask :v1test => 'invalid-depends-on-arch-value' do
version '1.2.3'
sha256 '9203c30951f9aab41ac294bbeb1dcef7bed401ff0b353dcb34d68af32ea51853'

url TestHelper.local_binary_url('caffeine.zip')
homepage 'http://example.com/invalid-depends-on-arch-value'

depends_on :arch => :no_such_arch

app 'Caffeine.app'
end
5 changes: 0 additions & 5 deletions test/support/Casks/with-caveats.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,4 @@
puts 'Custom text via puts followed by DSL-generated text:'
path_environment_variable('/custom/path/bin')
end
caveats do
# since both valid arches are specified, no output should be
# generated here during the test
arch_only('intel-32', 'intel-64')
end
end
5 changes: 0 additions & 5 deletions test/support/Casks/with-conditional-caveats.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,4 @@
caveats do
puts 'This caveat is conditional' if false
end
caveats do
# since both valid arches are specified, no output should be
# generated here during the test
arch_only('intel-32', 'intel-64')
end
end
12 changes: 12 additions & 0 deletions test/support/Casks/with-depends-on-arch-failure.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
cask :v1test => 'with-depends-on-arch-failure' do
version '1.2.3'
sha256 '9203c30951f9aab41ac294bbeb1dcef7bed401ff0b353dcb34d68af32ea51853'

url TestHelper.local_binary_url('caffeine.zip')
homepage 'http://example.com/with-depends-on-arch-failure'

# guarantee mismatched hardware
depends_on :arch => Hardware::CPU.intel? ? :ppc : :intel

app 'Caffeine.app'
end
12 changes: 12 additions & 0 deletions test/support/Casks/with-depends-on-arch.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
cask :v1test => 'with-depends-on-arch' do
version '1.2.3'
sha256 '9203c30951f9aab41ac294bbeb1dcef7bed401ff0b353dcb34d68af32ea51853'

url TestHelper.local_binary_url('caffeine.zip')
homepage 'http://example.com/with-depends-on-arch'

# covers all known hardware; always succeeds
depends_on :arch => [:ppc, :intel]

app 'Caffeine.app'
end

0 comments on commit 7f5e512

Please sign in to comment.