diff --git a/lib/capistrano/configuration.rb b/lib/capistrano/configuration.rb index d5254e67..37adb06c 100644 --- a/lib/capistrano/configuration.rb +++ b/lib/capistrano/configuration.rb @@ -37,8 +37,19 @@ module Capistrano servers.add_host(name, properties) end - def roles_for(names) - servers.fetch_roles(names) + def roles_for(names, options = {}) + servers.fetch_roles(names).tap do |list| + if filter = options.delete(:filter) || options.delete(:select) + if filter.respond_to?(:call) + list.select!(&filter) + else + list.select! { |s| s.properties.send(filter) } + end + if list.empty? + raise "Your filter #{filter} would remove all matching servers!" + end + end + end end def primary(role) diff --git a/spec/lib/capistrano/dsl/env_spec.rb b/spec/lib/capistrano/dsl/env_spec.rb index 60a86f4e..5822b686 100644 --- a/spec/lib/capistrano/dsl/env_spec.rb +++ b/spec/lib/capistrano/dsl/env_spec.rb @@ -39,12 +39,35 @@ module Capistrano describe '#roles' do - before do + let(:env) { Configuration.env } + before do + env.server('example.com', roles: :app, active: true) + env.server('example.org', roles: :app) end - it 'can filter hosts by properties on the host object' do - 1+1 + it 'raises if the filter would remove all matching hosts' do + pending + env.server('example.org', active: true) + lambda do + env.roles_for(:app, filter: lambda { |s| !s.properties.active }) + end.should raise_error + end + + it 'can filter hosts by properties on the host object using symbol as shorthand' do + env.roles_for(:app, filter: :active).length.should == 1 + end + + it 'can select hosts by properties on the host object using symbol as shorthand' do + env.roles_for(:app, select: :active).length.should == 1 + end + + it 'can filter hosts by properties on the host using a regular proc' do + env.roles_for(:app, filter: lambda { |h| h.properties.active } ).length.should == 1 + end + + it 'can select hosts by properties on the host using a regular proc' do + env.roles_for(:app, select: lambda { |h| h.properties.active } ).length.should == 1 end end