1
0
Fork 0
mirror of https://github.com/capistrano/capistrano synced 2023-03-27 23:21:18 -04:00

Correctly filter literal hostnames in on() block

When a literal hostname was supplied instead of a server object created
by the DSL 'server' keyword, on-filtering would not work.

Now host filtering works as expected, and role filtering causes no
servers to be returned (as literally defined servers have no roles)
This commit is contained in:
Nick Townsend 2015-03-04 15:25:27 -08:00
parent 89be250d07
commit b998303f70
4 changed files with 81 additions and 46 deletions

View file

@ -8,6 +8,9 @@ https://github.com/capistrano/capistrano/compare/v3.4.0...HEAD
* Removed the post-install message (@Kriechi) * Removed the post-install message (@Kriechi)
* Minor changes
* Fix filtering behaviour when using literal hostnames in on() block (@townsen)
## `3.4.0` ## `3.4.0`
https://github.com/capistrano/capistrano/compare/v3.3.5...v3.4.0 https://github.com/capistrano/capistrano/compare/v3.3.5...v3.4.0

View file

@ -99,7 +99,7 @@ module Capistrano
@filters = cmdline_filters.clone @filters = cmdline_filters.clone
@filters << Filter.new(:role, ENV['ROLES']) if ENV['ROLES'] @filters << Filter.new(:role, ENV['ROLES']) if ENV['ROLES']
@filters << Filter.new(:host, ENV['HOSTS']) if ENV['HOSTS'] @filters << Filter.new(:host, ENV['HOSTS']) if ENV['HOSTS']
fh = fetch_for(:filter,{}) fh = fetch_for(:filter,{}) || {}
@filters << Filter.new(:host, fh[:host]) if fh[:host] @filters << Filter.new(:host, fh[:host]) if fh[:host]
@filters << Filter.new(:role, fh[:role]) if fh[:role] @filters << Filter.new(:role, fh[:role]) if fh[:role]
end end

View file

@ -46,9 +46,9 @@ module Capistrano
when :none then return [] when :none then return []
when :all then return servers when :all then return servers
when :host when :host
as.select {|s| @rex.match s.hostname} as.select {|s| @rex.match s.to_s}
when :role when :role
as.select {|s| s.roles.any? {|r| @rex.match r} } as.select { |s| s.is_a?(String) ? false : s.roles.any? {|r| @rex.match r} }
end end
end end
end end

View file

@ -467,56 +467,88 @@ describe Capistrano::DSL do
describe 'on()' do describe 'on()' do
before do describe "when passed server objects" do
dsl.server 'example1.com', roles: %w{web}, active: true
dsl.server 'example2.com', roles: %w{web} before do
dsl.server 'example3.com', roles: %w{app web}, active: true dsl.server 'example1.com', roles: %w{web}, active: true
dsl.server 'example4.com', roles: %w{app}, primary: true dsl.server 'example2.com', roles: %w{web}
dsl.server 'example5.com', roles: %w{db}, no_release: true dsl.server 'example3.com', roles: %w{app web}, active: true
@coordinator = mock('coordinator') dsl.server 'example4.com', roles: %w{app}, primary: true
@coordinator.expects(:each).returns(nil) dsl.server 'example5.com', roles: %w{db}, no_release: true
ENV.delete 'ROLES' @coordinator = mock('coordinator')
ENV.delete 'HOSTS' @coordinator.expects(:each).returns(nil)
ENV.delete 'ROLES'
ENV.delete 'HOSTS'
end
it 'filters by role from the :filter variable' do
hosts = dsl.roles(:web)
all = dsl.roles(:all)
SSHKit::Coordinator.expects(:new).with(hosts).returns(@coordinator)
dsl.set :filter, { role: 'web' }
dsl.on(all)
end
it 'filters by host and role from the :filter variable' do
all = dsl.roles(:all)
SSHKit::Coordinator.expects(:new).with([]).returns(@coordinator)
dsl.set :filter, { role: 'db', host: 'example3.com' }
dsl.on(all)
end
it 'filters from ENV[ROLES]' do
hosts = dsl.roles(:db)
all = dsl.roles(:all)
SSHKit::Coordinator.expects(:new).with(hosts).returns(@coordinator)
ENV['ROLES'] = 'db'
dsl.on(all)
end
it 'filters from ENV[HOSTS]' do
hosts = dsl.roles(:db)
all = dsl.roles(:all)
SSHKit::Coordinator.expects(:new).with(hosts).returns(@coordinator)
ENV['HOSTS'] = 'example5.com'
dsl.on(all)
end
it 'filters by ENV[HOSTS] && ENV[ROLES]' do
all = dsl.roles(:all)
SSHKit::Coordinator.expects(:new).with([]).returns(@coordinator)
ENV['HOSTS'] = 'example5.com'
ENV['ROLES'] = 'web'
dsl.on(all)
end
end end
it 'filters by role from the :filter variable' do describe "when passed server literal names" do
hosts = dsl.roles(:web)
all = dsl.roles(:all)
SSHKit::Coordinator.expects(:new).with(hosts).returns(@coordinator)
dsl.set :filter, { role: 'web' }
dsl.on(all)
end
it 'filters by host and role from the :filter variable' do before do
all = dsl.roles(:all) ENV.delete 'ROLES'
SSHKit::Coordinator.expects(:new).with([]).returns(@coordinator) ENV.delete 'HOSTS'
dsl.set :filter, { role: 'db', host: 'example3.com' } @coordinator = mock('coordinator')
dsl.on(all) @coordinator.expects(:each).returns(nil)
end end
it 'filters from ENV[ROLES]' do it "selects nothing when a role filter is present" do
hosts = dsl.roles(:db) dsl.set :filter, { role: 'web' }
all = dsl.roles(:all) SSHKit::Coordinator.expects(:new).with([]).returns(@coordinator)
SSHKit::Coordinator.expects(:new).with(hosts).returns(@coordinator) dsl.on('my.server')
ENV['ROLES'] = 'db' end
dsl.on(all)
end
it 'filters from ENV[HOSTS]' do it "selects using the string when a host filter is present" do
hosts = dsl.roles(:db) dsl.set :filter, { host: 'server.local' }
all = dsl.roles(:all) SSHKit::Coordinator.expects(:new).with(['server.local']).returns(@coordinator)
SSHKit::Coordinator.expects(:new).with(hosts).returns(@coordinator) dsl.on('server.local')
ENV['HOSTS'] = 'example5.com' end
dsl.on(all)
end it "doesn't select when a host filter is present that doesn't match" do
dsl.set :filter, { host: 'ruby.local' }
SSHKit::Coordinator.expects(:new).with([]).returns(@coordinator)
dsl.on('server.local')
end
it 'filters by ENV[HOSTS] && ENV[ROLES]' do
all = dsl.roles(:all)
SSHKit::Coordinator.expects(:new).with([]).returns(@coordinator)
ENV['HOSTS'] = 'example5.com'
ENV['ROLES'] = 'web'
dsl.on(all)
end end
end end