Skip to content

Commit

Permalink
Introduce a new DSL and deprecate the old one
Browse files Browse the repository at this point in the history
  • Loading branch information
njonsson committed Mar 7, 2013
1 parent aff7772 commit bd5a6aa
Show file tree
Hide file tree
Showing 51 changed files with 3,357 additions and 153 deletions.
47 changes: 38 additions & 9 deletions README.markdown
Expand Up @@ -166,23 +166,47 @@ Cape lets you filter the Rake tasks to be mirrored. Note that Cape statements mu
mirror_rake_tasks :foo mirror_rake_tasks :foo
end end


### Mirror Rake tasks that require Capistrano recipe options and/or environment variables ### Mirror Rake tasks that require renaming, Capistrano recipe options, path switching, and/or environment variables


Cape lets you specify options used for defining Capistrano recipes. You can also specify remote environment variables to be set when executing Rake tasks. Note that Cape statements must be contained in a `Cape` block. Cape lets you customize mirrored Rake tasks to suit your needs. Note that Cape statements must be contained in a `Cape` block, and references to Capistrano variables such as `rails_env` and `release_path` must be contained in an inner block, lambda, or other callable object.


# config/deploy.rb # config/deploy.rb


require 'cape' require 'cape'


Cape do Cape do
# Display defined Rails routes on application server remote machines only. # Display defined Rails routes on application server remote machines only.
mirror_rake_tasks :routes, :roles => :app mirror_rake_tasks :routes do |recipes|
recipes.options[:roles] = :app
end


# Execute database migration on application server remote machines only, # Execute database migration on application server remote machines only,
# and set the 'RAILS_ENV' environment variable to the value of the # and set the 'RAILS_ENV' environment variable to the value of the
# Capistrano variable 'rails_env'. # Capistrano variable 'rails_env'.
mirror_rake_tasks 'db:migrate', :roles => :app do |env| mirror_rake_tasks 'db:migrate' do |recipes|
env['RAILS_ENV'] = rails_env recipes.options[:roles] = :app
recipes.env['RAILS_ENV'] = lambda { rails_env }
end

# Support a Rake task that must be run on application server remote
# machines only, and in the remote directory 'release_path' instead of the
# default, 'current_path'.
before 'deploy:symlink', :spec
mirror_rake_tasks :spec do |recipes|
recipes.cd { release_path }
recipes.options[:roles] = :app
end

# Avoid collisions with the existing Ruby method #test, run tests on
# application server remote machines only, and set the 'RAILS_ENV'
# environment variable to the value of the Capistrano variable
# 'rails_env'.
mirror_rake_tasks :test do |recipes|
recipes.rename do |rake_task_name|
"#{rake_task_name}_task"
end
recipes.options[:roles] = :app
recipes.env['RAILS_ENV'] = lambda { rails_env }
end end
end end


Expand Down Expand Up @@ -215,6 +239,15 @@ The above is equivalent to the following manually-defined Capistrano recipes.
end end
end end


before 'deploy:symlink', :spec
task :spec, :roles => :app do
run "cd #{release_path} && #{RAKE} routes"
end

task :test_task, :roles => :app do
run "cd #{current_path} && #{RAKE} test RAILS_ENV=#{rails_env}"
end

### Mirror Rake tasks into a Capistrano namespace ### Mirror Rake tasks into a Capistrano namespace


Cape plays friendly with the Capistrano DSL for organizing Rake tasks in Capistrano namespaces. Note that Cape statements must be contained in a `Cape` block. Cape plays friendly with the Capistrano DSL for organizing Rake tasks in Capistrano namespaces. Note that Cape statements must be contained in a `Cape` block.
Expand Down Expand Up @@ -286,10 +319,6 @@ Note that Cape statements must be contained in a `Cape` block.


gem 'rake', '>= 0.9.3' gem 'rake', '>= 0.9.3'


**A Rake task whose name collides with a Ruby method cannot be mirrored.** For example, the name of [Rails](http://rubyonrails.org)’s _db:fixtures:load_ task collides with the Ruby Core Library’s [_Kernel::load_ method](http://ruby-doc.org/core/Kernel.html#method-i-load) because that method is mixed into all objects. If you try to mirror _db:fixtures:load_, Capistrano will raise an exception. There is [a questionable workaround](http://github.com/njonsson/cape/issues/7#issuecomment-5632718 "Comment on Cape issue #7 (“defining a task named ‘load’ would shadow an existing method with that name (ArgumentError)”)") for this.

**A Rake task is always executed in the Capistrano deployment’s _current_path_.** You may need to execute a task under _release_path_ or another remote filesystem location, but this is not possible at present. [Discuss](http://github.com/njonsson/cape/issues/9 "Cape issue #9 (“Cape Always Runs the Mirrorred Rake Tasks Under $current_path”)") this.

## Contributing ## Contributing


Report defects and feature requests on [GitHub Issues](http://github.com/njonsson/cape/issues). Report defects and feature requests on [GitHub Issues](http://github.com/njonsson/cape/issues).
Expand Down
63 changes: 63 additions & 0 deletions features/dsl/mirror_rake_tasks/with_cd.feature
@@ -0,0 +1,63 @@
Feature: The #mirror_rake_tasks DSL method with a different directory

In order to include Rake tasks with descriptions in my Capistrano recipes,
As a developer using Cape,
I want to use the Cape DSL.

Scenario: mirror a Rake task with its implementation, using a Capistrano variable inside a lambda
Given a full-featured Rakefile
And a Capfile with:
"""
set :release_path, '/release/path'
Cape do
mirror_rake_tasks do |recipes|
recipes.cd lambda { release_path }
end
end
"""
When I run `cap with_period`
Then the output should contain:
"""
* executing `with_period'
* executing "cd /release/path && /usr/bin/env `/usr/bin/env bundle check >/dev/null 2>&1; case $? in 0|1 ) echo bundle exec ;; esac` rake with_period"
`with_period' is only run for servers matching {}, but no servers matched
"""

Scenario: mirror a Rake task with its implementation, using a Capistrano variable inside a block
Given a full-featured Rakefile
And a Capfile with:
"""
set :release_path, '/release/path'
Cape do
mirror_rake_tasks do |recipes|
recipes.cd { release_path }
end
end
"""
When I run `cap with_period`
Then the output should contain:
"""
* executing `with_period'
* executing "cd /release/path && /usr/bin/env `/usr/bin/env bundle check >/dev/null 2>&1; case $? in 0|1 ) echo bundle exec ;; esac` rake with_period"
`with_period' is only run for servers matching {}, but no servers matched
"""

Scenario: mirror a Rake task with its implementation, using a string
Given a full-featured Rakefile
And a Capfile with:
"""
Cape do
mirror_rake_tasks do |recipes|
recipes.cd '/release/path'
end
end
"""
When I run `cap with_period`
Then the output should contain:
"""
* executing `with_period'
* executing "cd /release/path && /usr/bin/env `/usr/bin/env bundle check >/dev/null 2>&1; case $? in 0|1 ) echo bundle exec ;; esac` rake with_period"
`with_period' is only run for servers matching {}, but no servers matched
"""
@@ -0,0 +1,27 @@
Feature: The #mirror_rake_tasks DSL method with a different directory and environment variables

In order to include Rake tasks with descriptions in my Capistrano recipes,
As a developer using Cape,
I want to use the Cape DSL.

Scenario: mirror a Rake task with its implementation
Given a full-featured Rakefile
And a Capfile with:
"""
set :release_path, '/release/path'
set :rails_env, 'rails-env'
Cape do
mirror_rake_tasks do |recipes|
recipes.cd { release_path }
recipes.env['RAILS_ENV'] = lambda { rails_env }
end
end
"""
When I run `cap with_period`
Then the output should contain:
"""
* executing `with_period'
* executing "cd /release/path && /usr/bin/env `/usr/bin/env bundle check >/dev/null 2>&1; case $? in 0|1 ) echo bundle exec ;; esac` rake with_period RAILS_ENV=\"rails-env\""
`with_period' is only run for servers matching {}, but no servers matched
"""
43 changes: 43 additions & 0 deletions features/dsl/mirror_rake_tasks/with_defined_task_and_cd.feature
@@ -0,0 +1,43 @@
Feature: The #mirror_rake_tasks DSL method with a defined task and a different directory

In order to include Rake tasks with descriptions in my Capistrano recipes,
As a developer using Cape,
I want to use the Cape DSL.

Scenario: mirror only the matching Rake task
Given a full-featured Rakefile
And a Capfile with:
"""
Cape do
mirror_rake_tasks :with_period do |recipes|
recipes.cd { release_path }
end
end
"""
When I run `cap -vT`
Then the output should contain:
"""
cap with_period # Ends with period.
"""
And the output should not contain "without_period"
And the output should not contain "my_namespace"

Scenario: mirror the matching Rake task with its implementation
Given a full-featured Rakefile
And a Capfile with:
"""
set :release_path, '/release/path'
Cape do
mirror_rake_tasks :with_period do |recipes|
recipes.cd { release_path }
end
end
"""
When I run `cap with_period`
Then the output should contain:
"""
* executing `with_period'
* executing "cd /release/path && /usr/bin/env `/usr/bin/env bundle check >/dev/null 2>&1; case $? in 0|1 ) echo bundle exec ;; esac` rake with_period"
`with_period' is only run for servers matching {}, but no servers matched
"""
@@ -0,0 +1,46 @@
Feature: The #mirror_rake_tasks DSL method with a defined task, a different directory, and environment variables

In order to include Rake tasks with descriptions in my Capistrano recipes,
As a developer using Cape,
I want to use the Cape DSL.

Scenario: mirror only the matching Rake task
Given a full-featured Rakefile
And a Capfile with:
"""
Cape do
mirror_rake_tasks :with_period do |recipes|
recipes.cd { release_path }
recipes.env['RAILS_ENV'] = lambda { rails_env }
end
end
"""
When I run `cap -vT`
Then the output should contain:
"""
cap with_period # Ends with period.
"""
And the output should not contain "without_period"
And the output should not contain "my_namespace"

Scenario: mirror the matching Rake task with its implementation
Given a full-featured Rakefile
And a Capfile with:
"""
set :release_path, '/release/path'
set :rails_env, 'rails-env'
Cape do
mirror_rake_tasks :with_period do |recipes|
recipes.cd { release_path }
recipes.env['RAILS_ENV'] = lambda { rails_env }
end
end
"""
When I run `cap with_period`
Then the output should contain:
"""
* executing `with_period'
* executing "cd /release/path && /usr/bin/env `/usr/bin/env bundle check >/dev/null 2>&1; case $? in 0|1 ) echo bundle exec ;; esac` rake with_period RAILS_ENV=\"rails-env\""
`with_period' is only run for servers matching {}, but no servers matched
"""
Expand Up @@ -4,7 +4,8 @@ Feature: The #mirror_rake_tasks DSL method with a defined task and environment v
As a developer using Cape, As a developer using Cape,
I want to use the Cape DSL. I want to use the Cape DSL.


Scenario: mirror only the matching Rake task @deprecated
Scenario: mirror only the matching Rake task (deprecated)
Given a full-featured Rakefile Given a full-featured Rakefile
And a Capfile with: And a Capfile with:
""" """
Expand All @@ -21,8 +22,32 @@ Feature: The #mirror_rake_tasks DSL method with a defined task and environment v
""" """
And the output should not contain "without_period" And the output should not contain "without_period"
And the output should not contain "my_namespace" And the output should not contain "my_namespace"
And the output should contain:
"""
*** DEPRECATED: Referencing Capistrano variables from Cape without wrapping them in a block, a lambda, or another callable object
"""


Scenario: mirror the matching Rake task with its implementation Scenario: mirror only the matching Rake task
Given a full-featured Rakefile
And a Capfile with:
"""
Cape do
mirror_rake_tasks :with_period do |recipes|
recipes.env['RAILS_ENV'] = lambda { rails_env }
end
end
"""
When I run `cap -vT`
Then the output should contain:
"""
cap with_period # Ends with period.
"""
And the output should not contain "without_period"
And the output should not contain "my_namespace"
And the output should not contain "DEPRECATED"

@deprecated
Scenario: mirror the matching Rake task with its implementation (deprecated)
Given a full-featured Rakefile Given a full-featured Rakefile
And a Capfile with: And a Capfile with:
""" """
Expand All @@ -36,9 +61,32 @@ Feature: The #mirror_rake_tasks DSL method with a defined task and environment v
end end
""" """
When I run `cap with_period` When I run `cap with_period`
Then the output should contain:
"""
*** DEPRECATED: `mirror_rake_tasks("with_period") { |env| env["RAILS_ENV"] = "rails-env" }`. Use this instead: `mirror_rake_tasks("with_period") { |recipes| recipes.env["RAILS_ENV"] = "rails-env" }`
* executing `with_period'
* executing "cd /current/path && /usr/bin/env `/usr/bin/env bundle check >/dev/null 2>&1; case $? in 0|1 ) echo bundle exec ;; esac` rake with_period RAILS_ENV=\"rails-env\""
`with_period' is only run for servers matching {}, but no servers matched
"""

Scenario: mirror the matching Rake task with its implementation
Given a full-featured Rakefile
And a Capfile with:
"""
set :current_path, '/current/path'
set :rails_env, 'rails-env'
Cape do
mirror_rake_tasks 'with_period' do |recipes|
recipes.env['RAILS_ENV'] = lambda { rails_env }
end
end
"""
When I run `cap with_period`
Then the output should contain: Then the output should contain:
""" """
* executing `with_period' * executing `with_period'
* executing "cd /current/path && /usr/bin/env `/usr/bin/env bundle check >/dev/null 2>&1; case $? in 0|1 ) echo bundle exec ;; esac` rake with_period RAILS_ENV=\"rails-env\"" * executing "cd /current/path && /usr/bin/env `/usr/bin/env bundle check >/dev/null 2>&1; case $? in 0|1 ) echo bundle exec ;; esac` rake with_period RAILS_ENV=\"rails-env\""
`with_period' is only run for servers matching {}, but no servers matched `with_period' is only run for servers matching {}, but no servers matched
""" """
And the output should not contain "DEPRECATED"
@@ -0,0 +1,47 @@
Feature: The #mirror_rake_tasks DSL method with a defined task and renaming logic

In order to include Rake tasks with descriptions in my Capistrano recipes,
As a developer using Cape,
I want to use the Cape DSL.

Scenario: mirror only the matching Rake task
Given a full-featured Rakefile defining a Ruby-method-shadowing task
And a Capfile with:
"""
Cape do
mirror_rake_tasks :load do |recipes|
recipes.rename do |task_name|
"do_#{task_name}"
end
end
end
"""
When I run `cap -vT`
Then the output should contain:
"""
cap do_load # A task that shadows a Ruby method.
"""
And the output should not contain "period"
And the output should not contain "my_namespace"

Scenario: mirror the matching Rake task with its implementation
Given a full-featured Rakefile defining a Ruby-method-shadowing task
And a Capfile with:
"""
set :current_path, '/current/path'
Cape do
mirror_rake_tasks :load do |recipes|
recipes.rename do |task_name|
"do_#{task_name}"
end
end
end
"""
When I run `cap do_load`
Then the output should contain:
"""
* executing `do_load'
* executing "cd /current/path && /usr/bin/env `/usr/bin/env bundle check >/dev/null 2>&1; case $? in 0|1 ) echo bundle exec ;; esac` rake load"
`do_load' is only run for servers matching {}, but no servers matched
"""

0 comments on commit bd5a6aa

Please sign in to comment.