Permalink
Browse files

Adding support for $CAPISTRANO:HOSTROLES$ as a valid placeholder

substitution.  This allows communicating the assigned roles to
the servers, and then making decisions server-side.
  • Loading branch information...
1 parent cf869eb commit 73206dfff777b431f36ca1cd014849dfcb6bacbe @mkocher mkocher committed with leehambley May 14, 2011
Showing with 36 additions and 2 deletions.
  1. +4 −1 lib/capistrano/command.rb
  2. +4 −0 lib/capistrano/configuration/roles.rb
  3. +15 −1 test/command_test.rb
  4. +13 −0 test/configuration/roles_test.rb
@@ -261,7 +261,10 @@ def request_pty_if_necessary(channel)
end
def replace_placeholders(command, channel)
- command.gsub(/\$CAPISTRANO:HOST\$/, channel[:host])
+ roles = @tree.configuration && @tree.configuration.role_names_for_host(channel[:server])
+ command = command.gsub(/\$CAPISTRANO:HOST\$/, channel[:host])
+ command.gsub!(/\$CAPISTRANO:HOSTROLES\$/, roles.join(',')) if roles
+ command
end
# prepare a space-separated sequence of variables assignments
@@ -68,6 +68,10 @@ def server(host, *roles)
raise ArgumentError, "you must associate a server with at least one role" if roles.empty?
roles.each { |name| role(name, host, options) }
end
+
+ def role_names_for_host(host)
+ roles.map {|role_name, role| role_name if role.include?(host) }.compact || []
+ end
end
end
end
View
@@ -226,13 +226,27 @@ def test_process_should_instantiate_command_and_process!
Capistrano::Command.process("ls -l", %w(a b c), :foo => "bar")
end
- def test_process_with_host_placeholder_should_substitute_placeholder_with_each_host
+ def test_process_with_host_placeholder_should_substitute_host_placeholder_with_each_host
session = setup_for_extracting_channel_action do |ch|
ch.expects(:exec).with(%(sh -c 'echo capistrano'))
end
Capistrano::Command.new("echo $CAPISTRANO:HOST$", [session])
end
+ class MockConfig
+ include Capistrano::Configuration::Roles
+ end
+
+ def test_hostroles_substitution
+ @config = MockConfig.new
+ @config.server "capistrano", :db, :worker
+ server = @config.roles[:db].servers.first
+ channel = {:server => server, :host => 'capistrano'}
+ tree = Capistrano::Command::Tree.new(@config) { |t| t.else("echo $CAPISTRANO:HOSTROLES$") }
+ result = Capistrano::Command.new(tree, []).send(:replace_placeholders, "echo $CAPISTRANO:HOSTROLES$", channel)
+ assert result == "echo db,worker" || result == "echo worker,db"
+ end
+
def test_process_with_unknown_placeholder_should_not_replace_placeholder
session = setup_for_extracting_channel_action do |ch|
ch.expects(:exec).with(%(sh -c 'echo $CAPISTRANO:OTHER$'))
@@ -21,6 +21,19 @@ def test_initialize_should_initialize_roles_collection
assert @config.original_initialize_called
assert @config.roles.empty?
end
+
+ def test_roles_for_host_with_one_role
+ @config.role :app, "app1.capistrano.test"
+ @config.role :not_app, "not-app.capistrano.test"
+ app_server = @config.roles[:app].servers.first
+ assert @config.role_names_for_host(app_server)==[ :app ]
+ end
+
+ def test_roles_for_host_with_multiple_roles
+ @config.server "www.capistrano.test", :db, :worker
+ db_server = @config.roles[:db].servers.first
+ assert_equal @config.role_names_for_host(db_server).map(&:to_s).sort, [ 'db', 'worker' ]
+ end
def test_role_should_allow_empty_list
@config.role :app

0 comments on commit 73206df

Please sign in to comment.