cape 1.6.2 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +7 -6
- data/Guardfile +29 -10
- data/History.markdown +4 -0
- data/README.markdown +38 -9
- data/Rakefile +35 -8
- data/features/dsl/each_rake_task/{without_arguments.feature → unqualified.feature} +16 -37
- data/features/dsl/each_rake_task/{with_defined_namespace_argument.feature → with_defined_namespace.feature} +2 -13
- data/features/dsl/each_rake_task/{with_defined_task_argument.feature → with_defined_task.feature} +2 -6
- data/features/dsl/each_rake_task/with_undefined_task_or_namespace.feature +24 -0
- data/features/dsl/mirror_rake_tasks/inside_capistrano_namespace.feature +2 -2
- data/features/dsl/mirror_rake_tasks/{without_arguments.feature → unqualified.feature} +15 -11
- data/features/dsl/mirror_rake_tasks/with_cd.feature +63 -0
- data/features/dsl/mirror_rake_tasks/with_cd_and_environment_variables.feature +27 -0
- data/features/dsl/mirror_rake_tasks/{with_defined_namespace_argument.feature → with_defined_namespace.feature} +6 -8
- data/features/dsl/mirror_rake_tasks/{with_defined_task_argument.feature → with_defined_task.feature} +4 -4
- data/features/dsl/mirror_rake_tasks/{with_defined_task_argument_and_environment_variables.feature → with_defined_task_and_cd.feature} +8 -8
- data/features/dsl/mirror_rake_tasks/with_defined_task_and_cd_and_environment_variables.feature +46 -0
- data/features/dsl/mirror_rake_tasks/with_defined_task_and_environment_variables.feature +92 -0
- data/features/dsl/mirror_rake_tasks/with_defined_task_and_rename.feature +47 -0
- data/features/dsl/mirror_rake_tasks/with_defined_task_and_rename_and_cd.feature +49 -0
- data/features/dsl/mirror_rake_tasks/with_defined_task_and_rename_and_cd_and_environment_variables.feature +52 -0
- data/features/dsl/mirror_rake_tasks/with_defined_task_and_rename_and_environment_variables.feature +50 -0
- data/features/dsl/mirror_rake_tasks/with_defined_task_and_rename_and_valid_options.feature +49 -0
- data/features/dsl/mirror_rake_tasks/with_defined_task_and_rename_and_valid_options_and_cd.feature +51 -0
- data/features/dsl/mirror_rake_tasks/with_defined_task_and_rename_and_valid_options_and_cd_and_environment_variables.feature +54 -0
- data/features/dsl/mirror_rake_tasks/with_defined_task_and_rename_and_valid_options_and_environment_variables.feature +52 -0
- data/features/dsl/mirror_rake_tasks/with_defined_task_and_valid_options.feature +53 -6
- data/features/dsl/mirror_rake_tasks/{with_defined_task_and_valid_options_arguments_and_environment_variables.feature → with_defined_task_and_valid_options_and_cd.feature} +10 -8
- data/features/dsl/mirror_rake_tasks/with_defined_task_and_valid_options_and_cd_and_environment_variables.feature +48 -0
- data/features/dsl/mirror_rake_tasks/with_defined_task_and_valid_options_and_environment_variables.feature +98 -0
- data/features/dsl/mirror_rake_tasks/with_environment_variables.feature +61 -4
- data/features/dsl/mirror_rake_tasks/with_rename.feature +27 -0
- data/features/dsl/mirror_rake_tasks/with_rename_and_cd.feature +28 -0
- data/features/dsl/mirror_rake_tasks/with_rename_and_cd_and_environment_variables.feature +30 -0
- data/features/dsl/mirror_rake_tasks/with_rename_and_environment_variables.feature +29 -0
- data/features/dsl/mirror_rake_tasks/with_rename_and_valid_options.feature +28 -0
- data/features/dsl/mirror_rake_tasks/with_rename_and_valid_options_and_cd.feature +29 -0
- data/features/dsl/mirror_rake_tasks/with_rename_and_valid_options_and_cd_and_environment_variables.feature +31 -0
- data/features/dsl/mirror_rake_tasks/with_rename_and_valid_options_and_environment_variables.feature +30 -0
- data/features/dsl/mirror_rake_tasks/{with_undefined_argument.feature → with_undefined_task_or_namespace.feature} +3 -4
- data/features/dsl/mirror_rake_tasks/with_valid_options.feature +46 -0
- data/features/dsl/mirror_rake_tasks/{with_valid_options_argument.feature → with_valid_options_and_cd.feature} +7 -5
- data/features/dsl/mirror_rake_tasks/with_valid_options_and_cd_and_environment_variables.feature +28 -0
- data/features/dsl/mirror_rake_tasks/with_valid_options_and_environment_variables.feature +51 -0
- data/features/dsl/rake_executable.feature +2 -2
- data/features/step_definitions.rb +40 -0
- data/lib/cape.rb +2 -0
- data/lib/cape/capistrano.rb +59 -32
- data/lib/cape/capistrano_deprecated.rb +165 -0
- data/lib/cape/core_ext.rb +2 -0
- data/lib/cape/deprecation.rb +12 -0
- data/lib/cape/deprecation/base.rb +59 -0
- data/lib/cape/deprecation/capistrano_deprecated_define_rake_wrapper.rb +168 -0
- data/lib/cape/deprecation/dsl_deprecated_mirror_rake_tasks.rb +145 -0
- data/lib/cape/dsl.rb +49 -60
- data/lib/cape/dsl_deprecated.rb +157 -0
- data/lib/cape/hash_list.rb +2 -0
- data/lib/cape/recipe_definition.rb +103 -0
- data/lib/cape/recipe_definition_deprecated.rb +41 -0
- data/lib/cape/util.rb +2 -0
- data/lib/cape/version.rb +1 -1
- data/lib/cape/xterm.rb +326 -0
- data/spec/cape/deprecation/base_sharedspec.rb +18 -0
- data/spec/cape/deprecation/capistrano_deprecated_define_rake_wrapper_spec.rb +157 -0
- data/spec/cape/deprecation/dsl_deprecated_mirror_rake_tasks_spec.rb +153 -0
- data/spec/cape/dsl_deprecated_spec.rb +307 -0
- data/spec/cape/dsl_spec.rb +10 -43
- data/spec/cape/recipe_definition_spec.rb +53 -0
- data/spec/cape/xterm_spec.rb +72 -0
- metadata +97 -28
- data/features/dsl/each_rake_task/with_undefined_argument.feature +0 -53
- data/features/dsl/mirror_rake_tasks/with_valid_options_arguments_and_environment_variables.feature +0 -26
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Feature: The #mirror_rake_tasks DSL method with an undefined
|
|
1
|
+
Feature: The #mirror_rake_tasks DSL method with an undefined task or namespace
|
|
2
2
|
|
|
3
3
|
In order to include Rake tasks with descriptions in my Capistrano recipes,
|
|
4
4
|
As a developer using Cape,
|
|
@@ -9,9 +9,8 @@ Feature: The #mirror_rake_tasks DSL method with an undefined argument
|
|
|
9
9
|
And a Capfile with:
|
|
10
10
|
"""
|
|
11
11
|
Cape do
|
|
12
|
-
mirror_rake_tasks
|
|
12
|
+
mirror_rake_tasks 'period'
|
|
13
13
|
end
|
|
14
14
|
"""
|
|
15
15
|
When I run `cap -vT`
|
|
16
|
-
Then the output should not contain "
|
|
17
|
-
And the output should not contain "cap with_period"
|
|
16
|
+
Then the output should not contain "period"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
Feature: The #mirror_rake_tasks DSL method with valid options
|
|
2
|
+
|
|
3
|
+
In order to include Rake tasks with descriptions in my Capistrano recipes,
|
|
4
|
+
As a developer using Cape,
|
|
5
|
+
I want to use the Cape DSL.
|
|
6
|
+
|
|
7
|
+
@deprecated
|
|
8
|
+
Scenario: mirror a Rake task with its implementation (deprecated)
|
|
9
|
+
Given a full-featured Rakefile
|
|
10
|
+
And a Capfile with:
|
|
11
|
+
"""
|
|
12
|
+
set :current_path, '/current/path'
|
|
13
|
+
|
|
14
|
+
Cape do
|
|
15
|
+
mirror_rake_tasks :roles => :app
|
|
16
|
+
end
|
|
17
|
+
"""
|
|
18
|
+
When I run `cap with_period`
|
|
19
|
+
Then the output should contain:
|
|
20
|
+
"""
|
|
21
|
+
*** DEPRECATED: `mirror_rake_tasks :roles => :app`. Use this instead: `mirror_rake_tasks { |recipes| recipes.options[:roles] = :app }`
|
|
22
|
+
* executing `with_period'
|
|
23
|
+
* 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"
|
|
24
|
+
`with_period' is only run for servers matching {:roles=>:app}, but no servers matched
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
Scenario: mirror a Rake task with its implementation
|
|
28
|
+
Given a full-featured Rakefile
|
|
29
|
+
And a Capfile with:
|
|
30
|
+
"""
|
|
31
|
+
set :current_path, '/current/path'
|
|
32
|
+
|
|
33
|
+
Cape do
|
|
34
|
+
mirror_rake_tasks do |recipes|
|
|
35
|
+
recipes.options[:roles] = :app
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
"""
|
|
39
|
+
When I run `cap with_period`
|
|
40
|
+
Then the output should contain:
|
|
41
|
+
"""
|
|
42
|
+
* executing `with_period'
|
|
43
|
+
* 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"
|
|
44
|
+
`with_period' is only run for servers matching {:roles=>:app}, but no servers matched
|
|
45
|
+
"""
|
|
46
|
+
And the output should not contain "DEPRECATED"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Feature: The #mirror_rake_tasks DSL method with
|
|
1
|
+
Feature: The #mirror_rake_tasks DSL method with valid options and a different directory
|
|
2
2
|
|
|
3
3
|
In order to include Rake tasks with descriptions in my Capistrano recipes,
|
|
4
4
|
As a developer using Cape,
|
|
@@ -8,17 +8,19 @@ Feature: The #mirror_rake_tasks DSL method with an argument of valid options
|
|
|
8
8
|
Given a full-featured Rakefile
|
|
9
9
|
And a Capfile with:
|
|
10
10
|
"""
|
|
11
|
-
set :
|
|
12
|
-
set :rails_env, 'production'
|
|
11
|
+
set :release_path, '/release/path'
|
|
13
12
|
|
|
14
13
|
Cape do
|
|
15
|
-
mirror_rake_tasks
|
|
14
|
+
mirror_rake_tasks do |recipes|
|
|
15
|
+
recipes.options[:roles] = :app
|
|
16
|
+
recipes.cd { release_path }
|
|
17
|
+
end
|
|
16
18
|
end
|
|
17
19
|
"""
|
|
18
20
|
When I run `cap with_period`
|
|
19
21
|
Then the output should contain:
|
|
20
22
|
"""
|
|
21
23
|
* executing `with_period'
|
|
22
|
-
* executing "cd /path
|
|
24
|
+
* 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"
|
|
23
25
|
`with_period' is only run for servers matching {:roles=>:app}, but no servers matched
|
|
24
26
|
"""
|
data/features/dsl/mirror_rake_tasks/with_valid_options_and_cd_and_environment_variables.feature
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Feature: The #mirror_rake_tasks DSL method with valid options, a different directory, and environment variables
|
|
2
|
+
|
|
3
|
+
In order to include Rake tasks with descriptions in my Capistrano recipes,
|
|
4
|
+
As a developer using Cape,
|
|
5
|
+
I want to use the Cape DSL.
|
|
6
|
+
|
|
7
|
+
Scenario: mirror the matching Rake task with its implementation
|
|
8
|
+
Given a full-featured Rakefile
|
|
9
|
+
And a Capfile with:
|
|
10
|
+
"""
|
|
11
|
+
set :release_path, '/release/path'
|
|
12
|
+
set :rails_env, 'rails-env'
|
|
13
|
+
|
|
14
|
+
Cape do
|
|
15
|
+
mirror_rake_tasks do |recipes|
|
|
16
|
+
recipes.options[:roles] = :app
|
|
17
|
+
recipes.cd { release_path }
|
|
18
|
+
recipes.env['RAILS_ENV'] = lambda { rails_env }
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
"""
|
|
22
|
+
When I run `cap with_period`
|
|
23
|
+
Then the output should contain:
|
|
24
|
+
"""
|
|
25
|
+
* executing `with_period'
|
|
26
|
+
* 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\""
|
|
27
|
+
`with_period' is only run for servers matching {:roles=>:app}, but no servers matched
|
|
28
|
+
"""
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
Feature: The #mirror_rake_tasks DSL method with valid options and environment variables
|
|
2
|
+
|
|
3
|
+
In order to include Rake tasks with descriptions in my Capistrano recipes,
|
|
4
|
+
As a developer using Cape,
|
|
5
|
+
I want to use the Cape DSL.
|
|
6
|
+
|
|
7
|
+
@deprecated
|
|
8
|
+
Scenario: mirror the matching Rake task with its implementation (deprecated)
|
|
9
|
+
Given a full-featured Rakefile
|
|
10
|
+
And a Capfile with:
|
|
11
|
+
"""
|
|
12
|
+
set :current_path, '/current/path'
|
|
13
|
+
set :rails_env, 'rails-env'
|
|
14
|
+
|
|
15
|
+
Cape do
|
|
16
|
+
mirror_rake_tasks :roles => :app do |env|
|
|
17
|
+
env['RAILS_ENV'] = rails_env
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
"""
|
|
21
|
+
When I run `cap with_period`
|
|
22
|
+
Then the output should contain:
|
|
23
|
+
"""
|
|
24
|
+
*** DEPRECATED: `mirror_rake_tasks(:roles => :app) { |env| env["RAILS_ENV"] = "rails-env" }`. Use this instead: `mirror_rake_tasks { |recipes| recipes.options[:roles] = :app; recipes.env["RAILS_ENV"] = "rails-env" }`
|
|
25
|
+
* executing `with_period'
|
|
26
|
+
* 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\""
|
|
27
|
+
`with_period' is only run for servers matching {:roles=>:app}, but no servers matched
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
Scenario: mirror the matching Rake task with its implementation
|
|
31
|
+
Given a full-featured Rakefile
|
|
32
|
+
And a Capfile with:
|
|
33
|
+
"""
|
|
34
|
+
set :current_path, '/current/path'
|
|
35
|
+
set :rails_env, 'rails-env'
|
|
36
|
+
|
|
37
|
+
Cape do
|
|
38
|
+
mirror_rake_tasks do |recipes|
|
|
39
|
+
recipes.options[:roles] = :app
|
|
40
|
+
recipes.env['RAILS_ENV'] = lambda { rails_env }
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
"""
|
|
44
|
+
When I run `cap with_period`
|
|
45
|
+
Then the output should contain:
|
|
46
|
+
"""
|
|
47
|
+
* executing `with_period'
|
|
48
|
+
* 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\""
|
|
49
|
+
`with_period' is only run for servers matching {:roles=>:app}, but no servers matched
|
|
50
|
+
"""
|
|
51
|
+
And the output should not contain "DEPRECATED"
|
|
@@ -44,7 +44,7 @@ Feature: The #local_rake_executable and #remote_rake_executable DSL attributes
|
|
|
44
44
|
Given a full-featured Rakefile
|
|
45
45
|
And a Capfile with:
|
|
46
46
|
"""
|
|
47
|
-
set :current_path, '/
|
|
47
|
+
set :current_path, '/current/path'
|
|
48
48
|
|
|
49
49
|
Cape.remote_rake_executable = 'echo "This comes from overridden Rake" #'
|
|
50
50
|
|
|
@@ -66,5 +66,5 @@ Feature: The #local_rake_executable and #remote_rake_executable DSL attributes
|
|
|
66
66
|
And the output should contain:
|
|
67
67
|
"""
|
|
68
68
|
* executing `with_period'
|
|
69
|
-
* executing "cd /
|
|
69
|
+
* executing "cd /current/path && echo \"This comes from overridden Rake\" # with_period"
|
|
70
70
|
"""
|
|
@@ -43,3 +43,43 @@ Given 'a full-featured Rakefile' do
|
|
|
43
43
|
task :hidden_task
|
|
44
44
|
end_step
|
|
45
45
|
end
|
|
46
|
+
|
|
47
|
+
Given 'a full-featured Rakefile defining a Ruby-method-shadowing task' do
|
|
48
|
+
step 'a file named "Rakefile" with:', <<-end_step
|
|
49
|
+
desc 'A task that shadows a Ruby method'
|
|
50
|
+
task :load
|
|
51
|
+
|
|
52
|
+
desc 'Ends with period.'
|
|
53
|
+
task :with_period
|
|
54
|
+
|
|
55
|
+
desc 'Ends without period'
|
|
56
|
+
task :without_period
|
|
57
|
+
|
|
58
|
+
desc 'My long task -- it has a very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very long description'
|
|
59
|
+
task :long
|
|
60
|
+
|
|
61
|
+
desc 'My task with one argument'
|
|
62
|
+
task :with_one_arg, [:the_arg]
|
|
63
|
+
|
|
64
|
+
desc 'A task that shadows a namespace'
|
|
65
|
+
task :my_namespace
|
|
66
|
+
|
|
67
|
+
namespace :my_namespace do
|
|
68
|
+
desc 'My task in a namespace'
|
|
69
|
+
task :in_a_namespace
|
|
70
|
+
|
|
71
|
+
namespace :my_nested_namespace do
|
|
72
|
+
desc 'My task in a nested namespace'
|
|
73
|
+
task :in_a_nested_namespace
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
desc 'My task with two arguments'
|
|
78
|
+
task :with_two_args, [:my_arg1, :my_arg2]
|
|
79
|
+
|
|
80
|
+
desc 'My task with three arguments'
|
|
81
|
+
task :with_three_args, [:an_arg1, :an_arg2, :an_arg3]
|
|
82
|
+
|
|
83
|
+
task :hidden_task
|
|
84
|
+
end_step
|
|
85
|
+
end
|
data/lib/cape.rb
CHANGED
|
@@ -6,12 +6,14 @@ end
|
|
|
6
6
|
module Cape
|
|
7
7
|
|
|
8
8
|
extend DSL
|
|
9
|
+
extend DSLDeprecated
|
|
9
10
|
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
# The method used to group Cape statements.
|
|
13
14
|
#
|
|
14
15
|
# @param [Proc] block Cape and Capistrano statements
|
|
16
|
+
#
|
|
15
17
|
# @return [Cape] the Cape module
|
|
16
18
|
#
|
|
17
19
|
# @yield [cape] a block containing Cape statements
|
data/lib/cape/capistrano.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
require 'cape/hash_list'
|
|
2
1
|
require 'cape/rake'
|
|
2
|
+
require 'cape/recipe_definition'
|
|
3
3
|
require 'cape/util'
|
|
4
4
|
|
|
5
5
|
module Cape
|
|
@@ -17,14 +17,13 @@ module Cape
|
|
|
17
17
|
attributes.each do |name, value|
|
|
18
18
|
send "#{name}=", value
|
|
19
19
|
end
|
|
20
|
-
self.rake ||=
|
|
20
|
+
self.rake ||= new_rake
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
# Defines a wrapper in Capistrano around the specified Rake _task_.
|
|
24
24
|
#
|
|
25
25
|
# @param [Hash] task metadata for a Rake task
|
|
26
|
-
# @param [Hash] named_arguments
|
|
27
|
-
# the Capistrano +task+ method
|
|
26
|
+
# @param [Hash] named_arguments
|
|
28
27
|
#
|
|
29
28
|
# @option task [String] :name the name of the Rake task
|
|
30
29
|
# @option task [Array of String, nil] :parameters the names of the Rake
|
|
@@ -32,33 +31,28 @@ module Cape
|
|
|
32
31
|
# @option task [String] :description documentation for the Rake
|
|
33
32
|
# task
|
|
34
33
|
#
|
|
35
|
-
# @option named_arguments [Binding] :binding
|
|
36
|
-
#
|
|
37
|
-
# file
|
|
34
|
+
# @option named_arguments [Binding] :binding the Binding of your Capistrano
|
|
35
|
+
# recipes file
|
|
38
36
|
#
|
|
39
|
-
# @yield [
|
|
40
|
-
#
|
|
41
|
-
# @yieldparam [
|
|
42
|
-
#
|
|
37
|
+
# @yield [recipes] a block that customizes the Capistrano recipe(s)
|
|
38
|
+
# generated for the Rake task(s); optional
|
|
39
|
+
# @yieldparam [RecipeDefinition] recipes an interface for customizing the
|
|
40
|
+
# Capistrano recipe(s) generated for
|
|
41
|
+
# the Rake task(s)
|
|
43
42
|
#
|
|
44
43
|
# @return [Capistrano] the object
|
|
45
44
|
#
|
|
46
45
|
# @raise [ArgumentError] +named_arguments[:binding]+ is missing
|
|
47
46
|
#
|
|
48
47
|
# @note Any parameters that the Rake task has are integrated via environment variables, since Capistrano does not support recipe parameters per se.
|
|
49
|
-
#
|
|
50
|
-
# @see http://github.com/capistrano/capistrano/blob/master/lib/capistrano/configuration/actions/invocation.rb#L99-L144 Valid Capistrano ‘task’ method options
|
|
51
48
|
def define_rake_wrapper(task, named_arguments, &block)
|
|
52
49
|
unless (binding = named_arguments[:binding])
|
|
53
50
|
raise ::ArgumentError, ':binding named argument is required'
|
|
54
51
|
end
|
|
55
52
|
|
|
56
53
|
capistrano_context = binding.eval('self', __FILE__, __LINE__)
|
|
57
|
-
options = named_arguments.reject do |key, value|
|
|
58
|
-
key == :binding
|
|
59
|
-
end
|
|
60
54
|
describe task, capistrano_context
|
|
61
|
-
implement(task, capistrano_context,
|
|
55
|
+
implement(task, capistrano_context, &block)
|
|
62
56
|
end
|
|
63
57
|
|
|
64
58
|
private
|
|
@@ -88,6 +82,11 @@ Set environment #{noun} #{parameters_list} if you want to pass #{noun_phrase}.
|
|
|
88
82
|
description.join
|
|
89
83
|
end
|
|
90
84
|
|
|
85
|
+
def capture_recipe_definition(recipe_definition, &recipe_definition_block)
|
|
86
|
+
recipe_definition_block.call(recipe_definition) if recipe_definition_block
|
|
87
|
+
true
|
|
88
|
+
end
|
|
89
|
+
|
|
91
90
|
def describe(task, capistrano_context)
|
|
92
91
|
if (description = build_capistrano_description(task))
|
|
93
92
|
capistrano_context.desc description
|
|
@@ -95,13 +94,18 @@ Set environment #{noun} #{parameters_list} if you want to pass #{noun_phrase}.
|
|
|
95
94
|
self
|
|
96
95
|
end
|
|
97
96
|
|
|
98
|
-
def implement(task, capistrano_context,
|
|
99
|
-
name_tokens = task
|
|
100
|
-
|
|
97
|
+
def implement(task, capistrano_context, &recipe_definition_block)
|
|
98
|
+
name_tokens = tokenize_name(task)
|
|
99
|
+
recipe_definition = new_recipe_definition
|
|
100
|
+
capture_recipe_definition(recipe_definition, &recipe_definition_block)
|
|
101
|
+
env = nil
|
|
101
102
|
rake = self.rake
|
|
102
|
-
# Define the recipe.
|
|
103
103
|
block = lambda { |context|
|
|
104
|
-
|
|
104
|
+
recipe_name = name_tokens.last
|
|
105
|
+
if recipe_definition.rename
|
|
106
|
+
recipe_name = recipe_definition.rename.call(name_tokens.last)
|
|
107
|
+
end
|
|
108
|
+
context.task recipe_name, recipe_definition.options do
|
|
105
109
|
arguments = Array(task[:parameters]).collect do |a|
|
|
106
110
|
if (value = ENV[a.upcase])
|
|
107
111
|
value = value.inspect
|
|
@@ -113,17 +117,26 @@ Set environment #{noun} #{parameters_list} if you want to pass #{noun_phrase}.
|
|
|
113
117
|
else
|
|
114
118
|
arguments = "[#{arguments.join ','}]"
|
|
115
119
|
end
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
|
|
121
|
+
unless env
|
|
122
|
+
env_strings = recipe_definition.env.collect do |var_name, var_value|
|
|
123
|
+
if var_name.nil? || var_value.nil?
|
|
124
|
+
nil
|
|
125
|
+
else
|
|
126
|
+
if var_value.is_a?(Proc)
|
|
127
|
+
var_value = context.instance_eval do
|
|
128
|
+
var_value.call
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
"#{var_name}=#{var_value.inspect}"
|
|
132
|
+
end
|
|
133
|
+
end.compact
|
|
134
|
+
env = env_strings.empty? ? nil : (' ' + env_strings.join(' '))
|
|
123
135
|
end
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
136
|
+
|
|
137
|
+
path = recipe_definition.cd || context.current_path
|
|
138
|
+
path = path.call if path.respond_to?(:call)
|
|
139
|
+
command = "cd #{path} && #{rake.remote_executable} " +
|
|
127
140
|
"#{task[:name]}#{arguments}#{env}"
|
|
128
141
|
context.run command
|
|
129
142
|
end
|
|
@@ -139,6 +152,20 @@ Set environment #{noun} #{parameters_list} if you want to pass #{noun_phrase}.
|
|
|
139
152
|
self
|
|
140
153
|
end
|
|
141
154
|
|
|
155
|
+
def new_rake(*arguments)
|
|
156
|
+
Rake.new(*arguments)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def new_recipe_definition(*arguments)
|
|
160
|
+
RecipeDefinition.new(*arguments)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def tokenize_name(task)
|
|
164
|
+
task[:name].split(':').tap do |result|
|
|
165
|
+
result << 'default' if task[:default]
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
142
169
|
end
|
|
143
170
|
|
|
144
171
|
end
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
require 'cape/capistrano'
|
|
2
|
+
require 'cape/deprecation/capistrano_deprecated_define_rake_wrapper'
|
|
3
|
+
require 'cape/recipe_definition_deprecated'
|
|
4
|
+
require 'cape/xterm'
|
|
5
|
+
|
|
6
|
+
module Cape
|
|
7
|
+
|
|
8
|
+
# Implements {Capistrano} with deprecated methods.
|
|
9
|
+
#
|
|
10
|
+
# @api private
|
|
11
|
+
class CapistranoDeprecated < Capistrano
|
|
12
|
+
|
|
13
|
+
# Defines a wrapper in Capistrano around the specified Rake _task_.
|
|
14
|
+
#
|
|
15
|
+
# @deprecated Use {Capistrano#define_rake_wrapper} instead.
|
|
16
|
+
#
|
|
17
|
+
# @param [Hash] task metadata for a Rake task
|
|
18
|
+
# @param [Hash] named_arguments named arguments, including options to pass to
|
|
19
|
+
# the Capistrano +task+ method
|
|
20
|
+
#
|
|
21
|
+
# @option task [String] :name the name of the Rake task
|
|
22
|
+
# @option task [Array of String, nil] :parameters the names of the Rake
|
|
23
|
+
# task's parameters, if any
|
|
24
|
+
# @option task [String] :description documentation for the Rake
|
|
25
|
+
# task
|
|
26
|
+
#
|
|
27
|
+
# @option named_arguments [Binding] :binding the Binding of your
|
|
28
|
+
# Capistrano recipes
|
|
29
|
+
# file
|
|
30
|
+
#
|
|
31
|
+
# @yield [env] a block that defines environment variables for the Rake task;
|
|
32
|
+
# optional
|
|
33
|
+
# @yieldparam [Hash] env the environment variables to set before executing
|
|
34
|
+
# the Rake task
|
|
35
|
+
#
|
|
36
|
+
# @return [CapistranoDeprecated] the object
|
|
37
|
+
#
|
|
38
|
+
# @raise [ArgumentError] +named_arguments[:binding]+ is missing
|
|
39
|
+
#
|
|
40
|
+
# @note Any parameters that the Rake task has are integrated via environment variables, since Capistrano does not support recipe parameters per se.
|
|
41
|
+
#
|
|
42
|
+
# @see http://github.com/capistrano/capistrano/blob/master/lib/capistrano/configuration/actions/invocation.rb#L99-L144 Valid Capistrano 'task' method options
|
|
43
|
+
#
|
|
44
|
+
# @api public
|
|
45
|
+
def define_rake_wrapper(task, named_arguments, &block)
|
|
46
|
+
unless (binding = named_arguments[:binding])
|
|
47
|
+
raise ::ArgumentError, ':binding named argument is required'
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
deprecation.task = task
|
|
51
|
+
deprecation.named_arguments = named_arguments
|
|
52
|
+
|
|
53
|
+
capistrano_context = binding.eval('self', __FILE__, __LINE__)
|
|
54
|
+
options = named_arguments.reject do |key, value|
|
|
55
|
+
key == :binding
|
|
56
|
+
end
|
|
57
|
+
describe task, capistrano_context
|
|
58
|
+
implement(task, capistrano_context, options, &block)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# The object in which deprecated API usage is recorded.
|
|
62
|
+
#
|
|
63
|
+
# @return [Deprecation::Base]
|
|
64
|
+
def deprecation
|
|
65
|
+
@deprecation ||= Deprecation::CapistranoDeprecatedDefineRakeWrapper.new
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
def capture_recipe_definition(recipe_definition, &recipe_definition_block)
|
|
71
|
+
begin
|
|
72
|
+
super
|
|
73
|
+
rescue NoMethodError
|
|
74
|
+
unless @warned
|
|
75
|
+
deprecation.stream.puts XTerm.bold_and_foreground_red('*** DEPRECATED:') +
|
|
76
|
+
' ' +
|
|
77
|
+
XTerm.bold('Referencing Capistrano variables ' +
|
|
78
|
+
'from Cape without wrapping them in ' +
|
|
79
|
+
'a block, a lambda, or another ' +
|
|
80
|
+
'callable object')
|
|
81
|
+
@warned = true
|
|
82
|
+
end
|
|
83
|
+
return false
|
|
84
|
+
end
|
|
85
|
+
true
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def implement(task, capistrano_context, options, &env_block)
|
|
89
|
+
return super(task, capistrano_context, &env_block) if options.empty?
|
|
90
|
+
|
|
91
|
+
name_tokens = tokenize_name(task)
|
|
92
|
+
recipe_definition = new_recipe_definition(deprecation)
|
|
93
|
+
env = nil
|
|
94
|
+
if capture_recipe_definition(recipe_definition, &env_block)
|
|
95
|
+
env_strings = recipe_definition.env.collect do |var_name, var_value|
|
|
96
|
+
if var_name.nil? || var_value.nil?
|
|
97
|
+
nil
|
|
98
|
+
else
|
|
99
|
+
var_value = var_value.call if var_value.is_a?(Proc)
|
|
100
|
+
"#{var_name}=#{var_value.inspect}"
|
|
101
|
+
end
|
|
102
|
+
end.compact
|
|
103
|
+
env = env_strings.empty? ? nil : (' ' + env_strings.join(' '))
|
|
104
|
+
end
|
|
105
|
+
this = env ? nil : self
|
|
106
|
+
rake = self.rake
|
|
107
|
+
block = lambda { |context|
|
|
108
|
+
recipe_name = name_tokens.last
|
|
109
|
+
if recipe_definition.rename
|
|
110
|
+
recipe_name = recipe_definition.rename.call(name_tokens.last)
|
|
111
|
+
end
|
|
112
|
+
context.task recipe_name, options do
|
|
113
|
+
arguments = Array(task[:parameters]).collect do |a|
|
|
114
|
+
if (value = ENV[a.upcase])
|
|
115
|
+
value = value.inspect
|
|
116
|
+
end
|
|
117
|
+
value
|
|
118
|
+
end
|
|
119
|
+
if arguments.empty?
|
|
120
|
+
arguments = nil
|
|
121
|
+
else
|
|
122
|
+
arguments = "[#{arguments.join ','}]"
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
unless env
|
|
126
|
+
if this.instance_eval { capture_recipe_definition(recipe_definition, &env_block) }
|
|
127
|
+
env_strings = recipe_definition.env.collect do |var_name, var_value|
|
|
128
|
+
if var_name.nil? || var_value.nil?
|
|
129
|
+
nil
|
|
130
|
+
else
|
|
131
|
+
var_value = var_value.call if var_value.is_a?(Proc)
|
|
132
|
+
"#{var_name}=#{var_value.inspect}"
|
|
133
|
+
end
|
|
134
|
+
end.compact
|
|
135
|
+
env = env_strings.empty? ? nil : (' ' + env_strings.join(' '))
|
|
136
|
+
this = nil
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
path = recipe_definition.cd || context.current_path
|
|
141
|
+
path = path.call if path.respond_to?(:call)
|
|
142
|
+
command = "cd #{path} && #{rake.remote_executable} " +
|
|
143
|
+
"#{task[:name]}#{arguments}#{env}"
|
|
144
|
+
context.run command
|
|
145
|
+
end
|
|
146
|
+
}
|
|
147
|
+
# Nest the recipe inside its containing namespaces.
|
|
148
|
+
name_tokens[0...-1].reverse.each do |namespace_token|
|
|
149
|
+
inner_block = block
|
|
150
|
+
block = lambda { |context|
|
|
151
|
+
context.namespace(namespace_token, &inner_block)
|
|
152
|
+
}
|
|
153
|
+
end
|
|
154
|
+
block.call capistrano_context
|
|
155
|
+
self
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def new_recipe_definition(*arguments)
|
|
159
|
+
arguments << deprecation if arguments.empty?
|
|
160
|
+
RecipeDefinitionDeprecated.new(*arguments)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
end
|