diff --git a/CHANGELOG b/CHANGELOG index 093e89b7..e36d2b50 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,9 +1,24 @@ *SVN* +* Changed setup, update_code, rollback_code, and symlink to work on all servers instead of only those in the :app, :web, and :db roles. A server can opt out of being part of the release deployment by setting :no_release => true [DHH] + +* Added support for :except on task declarations as the opposite of :only [DHH]. Example: + + role :app, "192.168.0.2" + role :file, "192.168.0.3", :no_release => true + + task :symlink, :except => { :no_release => true } do + on_rollback { run "ln -nfs #{previous_release} #{current_path}" } + run "ln -nfs #{current_release} #{current_path}" + end + + cap symlink # will not run on 192.168.0.3 + * Deprecate the -r/--recipe switch in favor of -f/--file (for more make/rake-like semantics) [Jamis Buck] * Fix gemspec to include a dependency on rake 0.7 [Jamis Buck] +>>>>>>> .r4040 * Added respect for ENV["HOSTS"] that'll be used instead of the roles specified in the task definition [DHH]. Example: HOSTS=192.168.0.1 cap setup # one-off setup for that server, doesn't need to be prespecified in the recipes file diff --git a/lib/capistrano/actor.rb b/lib/capistrano/actor.rb index 6690b85e..887be39c 100644 --- a/lib/capistrano/actor.rb +++ b/lib/capistrano/actor.rb @@ -85,18 +85,8 @@ module Capistrano @servers = hosts else roles = find_roles - only = @options[:only] || {} - - unless only.empty? - roles = roles.delete_if do |role| - catch(:done) do - only.keys.each do |key| - throw(:done, true) if role.options[key] != only[key] - end - false - end - end - end + apply_only!(roles) + apply_except!(roles) @servers = roles.map { |role| role.host }.uniq end @@ -122,6 +112,32 @@ module Capistrano use_symbols ? values.collect { |e| e.to_sym } : values end end + + def apply_only!(roles) + only = @options[:only] || {} + + unless only.empty? + roles = roles.delete_if do |role| + catch(:done) do + only.keys.each { |key| throw(:done, true) if role.options[key] != only[key] } + false + end + end + end + end + + def apply_except!(roles) + except = @options[:except] || {} + + unless except.empty? + roles = roles.delete_if do |role| + catch(:done) do + except.keys.each { |key| throw(:done, true) if role.options[key] == except[key] } + false + end + end + end + end end def initialize(config) #:nodoc: diff --git a/lib/capistrano/recipes/standard.rb b/lib/capistrano/recipes/standard.rb index 476f9c74..f7c49262 100644 --- a/lib/capistrano/recipes/standard.rb +++ b/lib/capistrano/recipes/standard.rb @@ -35,7 +35,7 @@ task :show_tasks do end desc "Set up the expected application directory structure on all boxes" -task :setup, :roles => [:app, :db, :web] do +task :setup, :except => { :no_release => true } do run <<-CMD mkdir -p -m 775 #{releases_path} #{shared_path}/system && mkdir -p -m 777 #{shared_path}/log @@ -64,7 +64,7 @@ desc <<-DESC Update all servers with the latest release of the source code. All this does is do a checkout (as defined by the selected scm module). DESC -task :update_code, :roles => [:app, :db, :web] do +task :update_code, :except => { :no_release => true } do on_rollback { delete release_path, :recursive => true } source.checkout(self) @@ -80,7 +80,7 @@ desc <<-DESC Rollback the latest checked-out version to the previous one by fixing the symlinks and deleting the current release from all servers. DESC -task :rollback_code, :roles => [:app, :db, :web] do +task :rollback_code, :except => { :no_release => true } do if releases.length < 2 raise "could not rollback the code because there is no prior release" else @@ -95,7 +95,7 @@ desc <<-DESC Update the 'current' symlink to point to the latest version of the application's code. DESC -task :symlink, :roles => [:app, :db, :web] do +task :symlink, :except => { :no_release => true } do on_rollback { run "ln -nfs #{previous_release} #{current_path}" } run "ln -nfs #{current_release} #{current_path}" end @@ -239,4 +239,4 @@ DESC task :invoke, :roles => Capistrano.str2roles(ENV["ROLES"] || "") do method = ENV["SUDO"] ? :sudo : :run send(method, ENV["COMMAND"]) -end +end \ No newline at end of file diff --git a/test/actor_test.rb b/test/actor_test.rb index fe519999..7194d846 100644 --- a/test/actor_test.rb +++ b/test/actor_test.rb @@ -230,6 +230,15 @@ class ActorTest < Test::Unit::TestCase assert_equal %w(01.example.com), @actor.sessions.keys.sort end + def test_run_in_task_with_except_restricts_selected_roles + @actor.define_task :foo, :roles => :db, :except => { :primary => true } do + run "do this" + end + + @actor.foo + assert_equal %w(02.example.com all.example.com), @actor.sessions.keys.sort + end + def test_run_in_task_with_single_host_selected @actor.define_task :foo, :hosts => "01.example.com" do run "do this"