cape 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -2,8 +2,6 @@ source 'http://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'jruby-openssl', :platforms => :jruby
6
-
7
5
  group :debug do
8
6
  gem 'ruby-debug', :platforms => :mri_18
9
7
 
@@ -1,12 +1,13 @@
1
- Version history for the _Cape_ project
2
- ======================================
1
+ # Version history for the _Cape_ project
3
2
 
4
- <a name="v1.0.1"></a>v1.0.0, Tue 11/29/2011
5
- -------------------------------------------
3
+ ## <a name="v1.0.2"></a>v1.0.2, Thu 12/29/2011
4
+
5
+ * Support Rake task arguments that contain whitespace
6
+
7
+ ## <a name="v1.0.1"></a>v1.0.1, Tue 11/29/2011
6
8
 
7
9
  * Don’t run Cucumber features from `gem test cape` because they fail
8
10
 
9
- <a name="v1.0.0"></a>v1.0.0, Mon 11/28/2011
10
- -------------------------------------------
11
+ ## <a name="v1.0.0"></a>v1.0.0, Mon 11/28/2011
11
12
 
12
13
  (First release)
@@ -1,5 +1,4 @@
1
- The MIT License
2
- ===============
1
+ # The MIT License
3
2
 
4
3
  Source code for _Cape_ is Copyright © 2011 [Nils Jonsson](mailto:cape@nilsjonsson.com) and [contributors](http://github.com/njonsson/cape/contributors "Cape contributors at GitHub").
5
4
 
@@ -29,8 +29,7 @@
29
29
  <hNNBNBh=(. / \ `
30
30
  ..
31
31
 
32
- [<img align="right" src="https://secure.travis-ci.org/njonsson/cape.png?branch=master" title="Travis CI build status" />](http://travis-ci.org/njonsson/cape) Cape
33
- ==================================================================================================================================================================
32
+ # [<img align="right" src="https://secure.travis-ci.org/njonsson/cape.png?branch=master" title="Travis CI build status" />](http://travis-ci.org/njonsson/cape) Cape
34
33
 
35
34
  If
36
35
 
@@ -39,40 +38,43 @@ If
39
38
 
40
39
  Then
41
40
 
42
- * **You can invoke [Cape](http://github.com/njonsson/cape)** to dynamically add Capistrano recipes for each of your application’s Rake tasks, and
41
+ * **You can use the [Cape](http://github.com/njonsson/cape) DSL** within Capistrano recipes to dynamically add recipes for your application’s Rake tasks, and
43
42
  * **You can run your Rake tasks on your deployed servers,** friction-free, and look like a superhero. _[cue fanfare]_
44
43
 
45
- Installation
46
- ------------
44
+ ## Features
47
45
 
48
- Install [the RubyGem](http://rubygems.org/gems/cape "Cape at RubyGems.org"):
46
+ * **Mirror Rake tasks** as Capistrano recipes, optionally filtered by namespace or name
47
+ * **Embed Rake tasks** in Capistrano namespaces
48
+ * **Pass arguments** to Rake tasks by setting environment variables with the same names
49
+ * **Override the default executables** for local and remote Rake installations (`/usr/bin/env rake` is the default)
50
+ * **Enumerate Rake tasks** for your own purposes
51
+
52
+ ## Installation — get your Cape on
53
+
54
+ Install [the RubyGem](http://rubygems.org/gems/cape "Cape at RubyGems.org").
49
55
 
50
56
  $ gem install cape
51
57
 
52
58
  Or you may want to make Cape a dependency of your project by using [Bundler](http://gembundler.com).
53
59
 
54
- Features
55
- --------
60
+ # Gemfile
56
61
 
57
- * **Mirror Rake tasks** as Capistrano recipes, optionally filtered by namespace or name
58
- * **Embed Rake tasks** in a Capistrano namespace
59
- * **Pass arguments** to Rake tasks by setting environment variables with the same names
60
- * **Override the default executables** for local and remote Rake installations (`/usr/bin/env rake` is the default)
61
- * **Enumerate Rake tasks** for your own purposes
62
+ source 'http://rubygems.org'
62
63
 
63
- Examples
64
- --------
64
+ gem 'cape'
65
65
 
66
- Assume we have the following _Rakefile_.
66
+ ## Examples
67
+
68
+ Assume the following Rake tasks are defined.
67
69
 
68
70
  desc 'Rakes the leaves'
69
71
  task :leaves do
70
- # (Raking action goes here.)
72
+ $stdout.puts "Raking the leaves"
71
73
  end
72
74
 
73
75
  desc 'Rakes and bags the leaves'
74
- task :bag_leaves, [:paper_or_plastic] => :leaves do
75
- # (Bagging action goes here.)
76
+ task :bag_leaves, [:paper_or_plastic] => :leaves do |task, arguments|
77
+ $stdout.puts "Putting the leaves in a #{arguments[:paper_or_plastic]} bag"
76
78
  end
77
79
 
78
80
  Rake lists these tasks in the expected fashion.
@@ -81,7 +83,15 @@ Rake lists these tasks in the expected fashion.
81
83
  rake bag_leaves[paper_or_plastic] # Rakes and bags the leaves
82
84
  rake leaves # Rakes the leaves
83
85
 
84
- Put the following in your _config/deploy.rb_. **Note that Cape statements must be executed within a `Cape` block.**
86
+ $ rake --describe bag_leaves
87
+ rake bag_leaves[paper_or_plastic]
88
+ Rakes and bags the leaves
89
+
90
+ ### Simply mirror all Rake tasks as Capistrano recipes
91
+
92
+ Add the following to your Capistrano recipes. Note that Cape statements must be executed within a `Cape` block.
93
+
94
+ # config/deploy.rb
85
95
 
86
96
  require 'cape'
87
97
 
@@ -90,7 +100,7 @@ Put the following in your _config/deploy.rb_. **Note that Cape statements must b
90
100
  mirror_rake_tasks
91
101
  end
92
102
 
93
- Now all your Rake tasks can be invoked as Capistrano recipes. Capistrano lists the recipes in the following fashion.
103
+ Now all your Rake tasks appear alongside your Capistrano recipes.
94
104
 
95
105
  $ cap --tasks
96
106
  cap deploy # Deploys your project.
@@ -116,10 +126,35 @@ Let’s use Capistrano to view the unabbreviated description of a Rake task reci
116
126
 
117
127
  You must set environment variable PAPER_OR_PLASTIC.
118
128
 
119
- Cape lets you filter the Rake tasks to be mirrored:
129
+ Here’s how to invoke a task/recipe with arguments. On the local computer, via Rake:
130
+
131
+ $ rake bag_leaves[plastic]
132
+ (in /current/working/directory)
133
+ Raking the leaves
134
+ Putting the leaves in a plastic bag
135
+
136
+ On remote computers, via Capistrano:
137
+
138
+ $ cap bag_leaves PAPER_OR_PLASTIC=plastic
139
+ * executing `bag_leaves'
140
+ * executing "cd /path/to/currently/deployed/version/of/your/app && rake bag_leaves[plastic]"
141
+ servers: ["your.server.name"]
142
+ [your.server.name] executing command
143
+ ** [out :: your.server.name] (in /path/to/currently/deployed/version/of/your/app)
144
+ ** [out :: your.server.name] Raking the leaves
145
+ ** [out :: your.server.name] Putting the leaves in a plastic bag
146
+ command finished in 1000ms
147
+
148
+ ### Mirror some Rake tasks, but not others
149
+
150
+ Cape lets you filter the Rake tasks to be mirrored. Note that Cape statements must be executed within a `Cape` block.
151
+
152
+ # config/deploy.rb
153
+
154
+ require 'cape'
120
155
 
121
156
  Cape do
122
- # Create Capistrano recipes for the Rake task 'foo' or for the tasks in a
157
+ # Create Capistrano recipes for the Rake task 'foo' or for the tasks in the
123
158
  # 'foo' namespace.
124
159
  mirror_rake_tasks :foo
125
160
 
@@ -128,39 +163,54 @@ Cape lets you filter the Rake tasks to be mirrored:
128
163
  mirror_rake_tasks 'bar:baz'
129
164
  end
130
165
 
131
- Cape plays friendly with the Capistrano DSL for organizing Rake tasks in Capistrano namespaces.
166
+ ### Mirror Rake tasks into a Capistrano namespace
167
+
168
+ Cape plays friendly with the Capistrano DSL for organizing Rake tasks in Capistrano namespaces. Note that Cape statements must be executed within a `Cape` block.
169
+
170
+ # config/deploy.rb
171
+
172
+ require 'cape'
132
173
 
133
- # Use an argument with the Cape block, if you want to or need to.
134
174
  namespace :rake_tasks do
175
+ # Use an argument with the Cape block, if you want to or need to.
135
176
  Cape do |cape|
136
177
  cape.mirror_rake_tasks
137
178
  end
138
179
  end
139
180
 
140
- Cape lets you enumerate Rake tasks, optionally filtering them by task name or namespace.
181
+ ### Iterate over available Rake tasks
182
+
183
+ Cape lets you enumerate Rake tasks, optionally filtering them by task name or namespace. Note that Cape statements must be executed within a `Cape` block.
184
+
185
+ # config/deploy.rb
186
+
187
+ require 'cape'
141
188
 
142
189
  Cape do
190
+ # Enumerate all Rake tasks.
143
191
  each_rake_task do |t|
144
192
  # Do something interesting with this hash:
145
193
  # * t[:name] -- the full name of the task
146
194
  # * t[:parameters] -- the names of task arguments
147
195
  # * t[:description] -- documentation on the task, including parameters
148
196
  end
197
+
198
+ # Enumerate the Rake task 'foo' or the tasks in the 'foo' namespace.
199
+ each_rake_task 'foo' do |t|
200
+ # ...
201
+ end
149
202
  end
150
203
 
151
- Limitations
152
- -----------
204
+ ## Limitations
153
205
 
154
206
  For now, only Rake tasks that have descriptions can be mirrored or enumerated.
155
207
 
156
- Contributing
157
- ------------
208
+ ## Contributing
158
209
 
159
210
  Report defects and feature requests on [GitHub Issues](http://github.com/njonsson/cape/issues).
160
211
 
161
212
  Your patches are welcome, and you will receive attribution here for good stuff.
162
213
 
163
- License
164
- -------
214
+ ## License
165
215
 
166
216
  Released under the [MIT License](http://github.com/njonsson/cape/blob/master/MIT-LICENSE.markdown).
@@ -74,6 +74,25 @@ Feature: The #mirror_rake_tasks DSL method, inside a Capistrano namespace, witho
74
74
 
75
75
  """
76
76
 
77
+ Scenario: mirror Rake task 'with_period' with its implementation
78
+ Given a full-featured Rakefile
79
+ And a file named "Capfile" with:
80
+ """
81
+ require 'cape'
82
+
83
+ set :current_path, '/path/to/current/deployed/application'
84
+ namespace :ns do
85
+ Cape do |cape|
86
+ cape.mirror_rake_tasks
87
+ end
88
+ end
89
+ """
90
+ When I run `cap ns:with_period`
91
+ Then the output should contain:
92
+ """
93
+ * executing "cd /path/to/current/deployed/application && /usr/bin/env rake with_period"
94
+ """
95
+
77
96
  Scenario: mirror Rake task 'without_period' with its description
78
97
  Given a full-featured Rakefile
79
98
  And a file named "Capfile" with:
@@ -70,6 +70,23 @@ Feature: The #mirror_rake_tasks DSL method without arguments
70
70
 
71
71
  """
72
72
 
73
+ Scenario: mirror Rake task 'with_period' with its implementation
74
+ Given a full-featured Rakefile
75
+ And a file named "Capfile" with:
76
+ """
77
+ require 'cape'
78
+
79
+ set :current_path, '/path/to/current/deployed/application'
80
+ Cape do
81
+ mirror_rake_tasks
82
+ end
83
+ """
84
+ When I run `cap with_period`
85
+ Then the output should contain:
86
+ """
87
+ * executing "cd /path/to/current/deployed/application && /usr/bin/env rake with_period"
88
+ """
89
+
73
90
  Scenario: mirror Rake task 'without_period' with its description
74
91
  Given a full-featured Rakefile
75
92
  And a file named "Capfile" with:
@@ -179,6 +196,23 @@ Feature: The #mirror_rake_tasks DSL method without arguments
179
196
 
180
197
  """
181
198
 
199
+ Scenario: mirror Rake task 'my_namespace:my_nested_namespace:in_a_nested_namespace' with its implementation
200
+ Given a full-featured Rakefile
201
+ And a file named "Capfile" with:
202
+ """
203
+ require 'cape'
204
+
205
+ set :current_path, '/path/to/current/deployed/application'
206
+ Cape do
207
+ mirror_rake_tasks
208
+ end
209
+ """
210
+ When I run `cap my_namespace:my_nested_namespace:in_a_nested_namespace`
211
+ Then the output should contain:
212
+ """
213
+ * executing "cd /path/to/current/deployed/application && /usr/bin/env rake my_namespace:my_nested_namespace:in_a_nested_namespace"
214
+ """
215
+
182
216
  Scenario: mirror Rake task 'with_two_args' with its description
183
217
  Given a full-featured Rakefile
184
218
  And a file named "Capfile" with:
@@ -225,6 +259,39 @@ Feature: The #mirror_rake_tasks DSL method without arguments
225
259
 
226
260
  """
227
261
 
262
+ Scenario: mirror Rake task 'with_three_args' with its implementation enforcing arguments
263
+ Given a full-featured Rakefile
264
+ And a file named "Capfile" with:
265
+ """
266
+ require 'cape'
267
+
268
+ set :current_path, '/path/to/current/deployed/application'
269
+ Cape do
270
+ mirror_rake_tasks
271
+ end
272
+ """
273
+ When I run `cap with_three_args AN_ARG1="a value for an_arg1"`
274
+ Then the output should contain "Environment variable AN_ARG2 must be set (RuntimeError)"
275
+
276
+ Scenario: mirror Rake task 'with_three_args' with its implementation
277
+ Given a full-featured Rakefile
278
+ And a file named "Capfile" with:
279
+ """
280
+ require 'cape'
281
+
282
+ set :current_path, '/path/to/current/deployed/application'
283
+ Cape do
284
+ mirror_rake_tasks
285
+ end
286
+ """
287
+ When I run `cap with_three_args AN_ARG1="a value for an_arg1" AN_ARG2="a value for an_arg2" AN_ARG3="a value for an_arg3"`
288
+ Then the output should contain:
289
+ """
290
+ * executing `with_three_args'
291
+ * executing "cd /path/to/current/deployed/application && /usr/bin/env rake with_three_args[\"a value for an_arg1\",\"a value for an_arg2\",\"a value for an_arg3\"]"
292
+
293
+ """
294
+
228
295
  Scenario: do not mirror Rake task 'hidden_task'
229
296
  Given a full-featured Rakefile
230
297
  And a file named "Capfile" with:
@@ -0,0 +1,70 @@
1
+ Feature: The #local_rake_executable and #remote_rake_executable DSL attributes
2
+
3
+ In order to control which Rake executables are used locally and remotely,
4
+ As a developer using Cape,
5
+ I want to use the Cape DSL.
6
+
7
+ Scenario: use a different Rake executable to enumerate Rake tasks
8
+ Given a full-featured Rakefile
9
+ And a file named "Capfile" with:
10
+ """
11
+ require 'cape'
12
+
13
+ Cape do
14
+ self.local_rake_executable = 'echo "rake this-comes-from-overridden-rake # This comes from overridden Rake" #'
15
+ $stdout.puts "We changed the local Rake executable to #{self.local_rake_executable.inspect}."
16
+ $stdout.puts "We left the remote Rake executable as #{self.remote_rake_executable.inspect}."
17
+ each_rake_task do |t|
18
+ $stdout.puts '', "Name: #{t[:name].inspect}"
19
+ if t[:parameters]
20
+ $stdout.puts "Parameters: #{t[:parameters].inspect}"
21
+ end
22
+ if t[:description]
23
+ $stdout.puts "Description: #{t[:description].inspect}"
24
+ end
25
+ end
26
+ end
27
+ """
28
+ When I run `cap -T`
29
+ Then the output should contain:
30
+ """
31
+ We changed the local Rake executable to "echo \"rake this-comes-from-overridden-rake # This comes from overridden Rake\" #"
32
+ """
33
+ And the output should contain:
34
+ """
35
+ We left the remote Rake executable as "/usr/bin/env rake"
36
+ """
37
+ And the output should contain:
38
+ """
39
+
40
+ Name: "this-comes-from-overridden-rake"
41
+ Description: "This comes from overridden Rake"
42
+ """
43
+
44
+ Scenario: use a different Rake executable to execute Rake tasks
45
+ Given a full-featured Rakefile
46
+ And a file named "Capfile" with:
47
+ """
48
+ require 'cape'
49
+
50
+ set :current_path, '/path/to/current/deployed/application'
51
+ Cape do
52
+ self.remote_rake_executable = 'echo "This comes from overridden Rake" #'
53
+ $stdout.puts "We changed the remote Rake executable to #{self.remote_rake_executable.inspect}."
54
+ $stdout.puts "We left the local Rake executable as #{self.local_rake_executable.inspect}."
55
+ mirror_rake_tasks
56
+ end
57
+ """
58
+ When I run `cap with_period`
59
+ Then the output should contain:
60
+ """
61
+ We changed the remote Rake executable to "echo \"This comes from overridden Rake\" #"
62
+ """
63
+ And the output should contain:
64
+ """
65
+ We left the local Rake executable as "/usr/bin/env rake"
66
+ """
67
+ And the output should contain:
68
+ """
69
+ * executing "cd /path/to/current/deployed/application && echo \"This comes from overridden Rake\" # with_period"
70
+ """
@@ -1 +1,5 @@
1
1
  require 'aruba/cucumber'
2
+
3
+ Before do
4
+ @aruba_timeout_seconds = 10
5
+ end
@@ -1,5 +1,5 @@
1
- Dir.glob( File.expand_path( 'cape/*.rb', File.dirname( __FILE__ ))) do |f|
2
- require "cape/#{File.basename f, '.rb'}"
1
+ ::Dir.glob(::File.expand_path('../cape/*.rb', __FILE__)) do |f|
2
+ require "cape/#{::File.basename f, '.rb'}"
3
3
  end
4
4
 
5
5
  # Contains the implementation of Cape.
@@ -9,7 +9,34 @@ module Cape
9
9
 
10
10
  end
11
11
 
12
- # The method used to group Cape statements in a block.
12
+ # The method used to group Cape statements.
13
+ #
14
+ # @param [Proc] block Cape and Capistrano statements
15
+ # @return [Cape] the Cape module
16
+ #
17
+ # @yield [cape] a block containing Cape statements
18
+ # @yieldparam [Cape::DSL] cape the Cape DSL; optional
19
+ #
20
+ # @example Basic Cape usage
21
+ # # config/deploy.rb
22
+ #
23
+ # require 'cape'
24
+ #
25
+ # Cape do
26
+ # mirror_rake_tasks
27
+ # end
28
+ #
29
+ # @example Combining Cape statements with Capistrano statements
30
+ # # config/deploy.rb
31
+ #
32
+ # require 'cape'
33
+ #
34
+ # namespace :rake_tasks do
35
+ # # Use an argument with the Cape block, if you want to or need to.
36
+ # Cape do |cape|
37
+ # cape.mirror_rake_tasks
38
+ # end
39
+ # end
13
40
  def Cape(&block)
14
41
  Cape.module_eval do
15
42
  @outer_self = block.binding.eval('self', __FILE__, __LINE__)
@@ -19,4 +46,5 @@ def Cape(&block)
19
46
  module_eval(&block)
20
47
  end
21
48
  end
49
+ Cape
22
50
  end
@@ -1,21 +1,37 @@
1
- require 'cape/strings'
1
+ require 'cape/util'
2
2
 
3
3
  module Cape
4
4
 
5
5
  # An abstraction of the Capistrano installation.
6
6
  class Capistrano
7
7
 
8
- # Defines the specified _task_ as a Capistrano task, provided a Binding
9
- # named argument +:binding+ and a Cape::Rake named argument +:rake+. Any
10
- # parameters the task has are converted to environment variables, since
11
- # Capistrano does not have the concept of task parameters.
8
+ # Defines the specified _task_ as a Capistrano task.
12
9
  #
13
- # The _task_ argument must be a Hash of the form:
10
+ # @param [Hash] task metadata for a task
11
+ # @param [Hash] named_arguments named arguments
14
12
  #
15
- # {:name => <String>,
16
- # :parameters => <String Array or nil>,
17
- # :description => <String>}
18
- def define(task, named_arguments={})
13
+ # @option task [String] :name the name of the task
14
+ # @option task [Array of String, nil] :parameters the names of the task's
15
+ # parameters, if any
16
+ # @option task [String] :description documentation for the task
17
+ #
18
+ # @option named_arguments [Binding] :binding the Binding of your
19
+ # Capistrano recipes
20
+ # file
21
+ # @option named_arguments [Rake] :rake a Cape abstraction of
22
+ # the Rake installation
23
+ # @option named_arguments [[Array of] Symbol] :roles the Capistrano role(s)
24
+ # of remote computers
25
+ # that will execute
26
+ # _task_
27
+ #
28
+ # @return [Capistrano] the object
29
+ #
30
+ # @raise [ArgumentError] +named_arguments[:binding]+ is missing
31
+ # @raise [ArgumentError] +named_arguments[:rake]+ is missing
32
+ #
33
+ # @note Any parameters that the task has are integrated via environment variables, since Capistrano does not support task parameters per se.
34
+ def define(task, named_arguments)
19
35
  unless (binding = named_arguments[:binding])
20
36
  raise ::ArgumentError, ':binding named argument is required'
21
37
  end
@@ -40,8 +56,8 @@ module Cape
40
56
  description = [task[:description]]
41
57
  description << '.' unless task[:description].end_with?('.')
42
58
  unless (parameters = Array(task[:parameters])).empty?
43
- noun = Strings.pluralize('variable', parameters.length)
44
- parameters_list = Strings.to_list_phrase(parameters.collect(&:upcase))
59
+ noun = Util.pluralize('variable', parameters.length)
60
+ parameters_list = Util.to_list_phrase(parameters.collect(&:upcase))
45
61
  description << <<-end_description
46
62
 
47
63
 
@@ -60,7 +76,7 @@ You must set environment #{noun} #{parameters_list}.
60
76
  unless (value = ENV[a.upcase])
61
77
  fail "Environment variable #{a.upcase} must be set"
62
78
  end
63
- value
79
+ value.inspect
64
80
  end
65
81
  if arguments.empty?
66
82
  arguments = nil
@@ -1,5 +1,5 @@
1
- Dir.glob( File.expand_path( 'core_ext/*.rb', File.dirname( __FILE__ ))) do |f|
2
- require "cape/core_ext/#{File.basename f, '.rb'}"
1
+ ::Dir.glob(::File.expand_path('../core_ext/*.rb', __FILE__)) do |f|
2
+ require "cape/core_ext/#{::File.basename f, '.rb'}"
3
3
  end
4
4
 
5
5
  module Cape
@@ -2,11 +2,14 @@ module Cape
2
2
 
3
3
  module CoreExt
4
4
 
5
- # Contains extensions to the Hash core class.
5
+ # Adds methods missing from Ruby's Hash core class.
6
6
  module Hash
7
7
 
8
8
  # Returns a copy of the Hash containing values only for the specified
9
9
  # _keys_.
10
+ #
11
+ # @param [Array] keys zero or more hash keys
12
+ # @return [Hash] a subset of the Hash
10
13
  def slice(*keys)
11
14
  ::Hash[select { |key, value| keys.include? key }]
12
15
  end
@@ -17,8 +20,8 @@ module Cape
17
20
 
18
21
  end
19
22
 
20
- unless Hash.instance_methods.collect(&:to_s).include?('slice')
21
- Hash.class_eval do
23
+ unless ::Hash.instance_methods.collect(&:to_s).include?('slice')
24
+ ::Hash.class_eval do
22
25
  include Cape::CoreExt::Hash
23
26
  end
24
27
  end
@@ -2,12 +2,15 @@ module Cape
2
2
 
3
3
  module CoreExt
4
4
 
5
- # Contains extensions to the Symbol core class.
5
+ # Adds methods missing from Ruby's Symbol core class.
6
6
  module Symbol
7
7
 
8
- # Returns +0+ if the Symbol is equal to _other_, +-1+ if it is
9
- # alphabetically lesser than _other_, and +1+ if it is alphabetically
10
- # greater than _other_.
8
+ # Compares the String representation of the Symbol to that of another.
9
+ #
10
+ # @param [Symbol] other
11
+ # @return [0] the Symbol is equal to _other_
12
+ # @return [-1] the Symbol is lesser than _other_
13
+ # @return [1] the Symbol is greater than _other_
11
14
  def <=>(other)
12
15
  to_s <=> other.to_s
13
16
  end
@@ -18,8 +21,8 @@ module Cape
18
21
 
19
22
  end
20
23
 
21
- unless Symbol.instance_methods.collect(&:to_s).include?('<=>')
22
- Symbol.class_eval do
24
+ unless ::Symbol.instance_methods.collect(&:to_s).include?('<=>')
25
+ ::Symbol.class_eval do
23
26
  include Cape::CoreExt::Symbol
24
27
  end
25
28
  end
@@ -6,36 +6,121 @@ module Cape
6
6
  # Provides methods for integrating Capistrano and Rake.
7
7
  module DSL
8
8
 
9
- # Yields each available Rake task to a block. The optional _task_expression_
10
- # argument limits the list to a single task or a namespace containing
11
- # multiple tasks.
9
+ # Enumerates Rake tasks.
12
10
  #
13
- # Tasks are yielded as Hash objects of the form:
11
+ # @param [String, Symbol] task_expression the full name of a task or
12
+ # namespace to filter; optional
13
+ # @param [Proc] block a block that processes tasks
14
14
  #
15
- # {:name => <String>,
16
- # :parameters => <String Array or nil>,
17
- # :description => <String>}
15
+ # @yield [task] a block that processes tasks
16
+ # @yieldparam [Hash] task metadata on a task
17
+ #
18
+ # @return [DSL] the object
19
+ #
20
+ # @example Enumerating all Rake tasks
21
+ # # config/deploy.rb
22
+ #
23
+ # require 'cape'
24
+ #
25
+ # Cape do
26
+ # each_rake_task do |t|
27
+ # # Do something interesting with this hash:
28
+ # # * t[:name] -- the full name of the task
29
+ # # * t[:parameters] -- the names of task arguments
30
+ # # * t[:description] -- documentation on the task, including parameters
31
+ # end
32
+ # end
33
+ #
34
+ # @example Enumerating some Rake tasks
35
+ # # config/deploy.rb
36
+ #
37
+ # require 'cape'
38
+ #
39
+ # Cape do
40
+ # each_rake_task :foo do |t|
41
+ # # Do something interesting with this hash:
42
+ # # * t[:name] -- the full name of the task
43
+ # # * t[:parameters] -- the names of task arguments
44
+ # # * t[:description] -- documentation on the task, including parameters
45
+ # end
46
+ # end
18
47
  def each_rake_task(task_expression=nil, &block)
19
48
  rake.each_task(task_expression, &block)
20
49
  self
21
50
  end
22
51
 
23
- # Returns the command used to run Rake on the local computer. Defaults to
24
- # Rake::DEFAULT_EXECUTABLE.
52
+ # The command used to run Rake on the local computer.
53
+ #
54
+ # @return [String] the command used to run Rake on the local computer
55
+ #
56
+ # @see Rake::DEFAULT_EXECUTABLE
25
57
  def local_rake_executable
26
58
  rake.local_executable
27
59
  end
28
60
 
29
61
  # Sets the command used to run Rake on the local computer.
62
+ #
63
+ # @param [String] value the command used to run Rake on the local computer
64
+ # @return [String] _value_
65
+ #
66
+ # @example Changing the local Rake executable
67
+ # require 'cape'
68
+ #
69
+ # Cape do
70
+ # self.local_rake_executable = '/path/to/rake'
71
+ # $stdout.puts "We changed the local Rake executable to #{self.local_rake_executable.inspect}."
72
+ # end
30
73
  def local_rake_executable=(value)
31
74
  rake.local_executable = value
32
75
  end
33
76
 
34
- # Defines each available Rake task as a Capistrano task. Any
35
- # parameters the tasks have are converted to environment variables, since
36
- # Capistrano does not have the concept of task parameters. The optional
37
- # _task_expression_ argument limits the list to a single task or a namespace
38
- # containing multiple tasks.
77
+ # Makes the use of a block parameter optional by forwarding non-Cape method
78
+ # calls to the containing binding.
79
+ #
80
+ # @param [Symbol, String] method the method called
81
+ # @param [Array] args the arguments passed to _method_
82
+ # @param [Proc] block the block passed to _method_
83
+ # @return the result of the forwarded method call
84
+ def method_missing(method, *args, &block)
85
+ @outer_self.send(method, *args, &block)
86
+ end
87
+
88
+ # Defines Rake tasks as Capistrano tasks.
89
+ #
90
+ # @param [String, Symbol] task_expression the full name of a Rake task or
91
+ # namespace to filter; optional
92
+ # @return [DSL] the object
93
+ #
94
+ # @note Any parameters that the Rake tasks have are integrated via environment variables, since Capistrano does not support task parameters per se.
95
+ #
96
+ # @example Mirroring all Rake tasks
97
+ # # config/deploy.rb
98
+ #
99
+ # require 'cape'
100
+ #
101
+ # Cape do
102
+ # mirror_rake_tasks
103
+ # end
104
+ #
105
+ # @example Mirroring some Rake tasks
106
+ # # config/deploy.rb
107
+ #
108
+ # require 'cape'
109
+ #
110
+ # Cape do
111
+ # mirror_rake_tasks :foo
112
+ # end
113
+ #
114
+ # @example Mirroring Rake tasks into a Capistrano namespace
115
+ # # config/deploy.rb
116
+ #
117
+ # require 'cape'
118
+ #
119
+ # namespace :rake_tasks do
120
+ # Cape do |cape|
121
+ # cape.mirror_rake_tasks
122
+ # end
123
+ # end
39
124
  def mirror_rake_tasks(task_expression=nil)
40
125
  d = nil
41
126
  rake.each_task task_expression do |t|
@@ -44,13 +129,27 @@ module Cape
44
129
  self
45
130
  end
46
131
 
47
- # Returns the command used to run Rake on remote computers. Defaults to
48
- # Rake::DEFAULT_EXECUTABLE.
132
+ # The command used to run Rake on remote computers.
133
+ #
134
+ # @return [String] the command used to run Rake on remote computers
135
+ #
136
+ # @see Rake::DEFAULT_EXECUTABLE
49
137
  def remote_rake_executable
50
138
  rake.remote_executable
51
139
  end
52
140
 
53
141
  # Sets the command used to run Rake on remote computers.
142
+ #
143
+ # @param [String] value the command used to run Rake on remote computers
144
+ # @return [String] _value_
145
+ #
146
+ # @example Changing the remote Rake executable
147
+ # require 'cape'
148
+ #
149
+ # Cape do
150
+ # self.remote_rake_executable = '/path/to/rake'
151
+ # $stdout.puts "We changed the remote Rake executable to #{self.remote_rake_executable.inspect}."
152
+ # end
54
153
  def remote_rake_executable=(value)
55
154
  rake.remote_executable = value
56
155
  end
@@ -62,10 +161,6 @@ module Cape
62
161
  Capistrano.new
63
162
  end
64
163
 
65
- def method_missing(method, *args, &block)
66
- @outer_self.send(method, *args, &block)
67
- end
68
-
69
164
  def raise_unless_capistrano
70
165
  if @outer_self.method(:task).owner.name !~ /^Capistrano::/
71
166
  raise 'Use this in the context of Capistrano recipes'
@@ -7,9 +7,15 @@ module Cape
7
7
  DEFAULT_EXECUTABLE = '/usr/bin/env rake'.freeze
8
8
 
9
9
  # Sets the command used to run Rake on the local computer.
10
+ #
11
+ # @param [String] value the command used to run Rake on the local computer
12
+ # @return [String] _value_
10
13
  attr_writer :local_executable
11
14
 
12
15
  # Sets the command used to run Rake on remote computers.
16
+ #
17
+ # @param [String] value the command used to run Rake on remote computers
18
+ # @return [String] _value_
13
19
  attr_writer :remote_executable
14
20
 
15
21
  # Constructs a new Rake object with the specified _attributes_.
@@ -19,15 +25,16 @@ module Cape
19
25
  end
20
26
  end
21
27
 
22
- # Yields each available Rake task to a block. The optional _task_expression_
23
- # argument limits the list to a single task or a namespace containing
24
- # multiple tasks.
28
+ # Enumerates Rake tasks.
25
29
  #
26
- # Tasks are yielded as Hash objects of the form:
30
+ # @param [String, Symbol] task_expression the full name of a task or
31
+ # namespace to filter; optional
32
+ # @param [Proc] block a block that processes tasks
27
33
  #
28
- # {:name => <String>,
29
- # :parameters => <String Array or nil>,
30
- # :description => <String>}
34
+ # @yield [task] a block that processes tasks
35
+ # @yieldparam [Hash] task metadata on a task
36
+ #
37
+ # @return [Rake] the object
31
38
  def each_task(task_expression=nil)
32
39
  task_expression = " #{task_expression}" if task_expression
33
40
  command = "#{local_executable} --tasks #{task_expression}"
@@ -43,14 +50,20 @@ module Cape
43
50
  self
44
51
  end
45
52
 
46
- # Returns the command used to run Rake on the local computer. Defaults to
47
- # DEFAULT_EXECUTABLE.
53
+ # The command used to run Rake on the local computer.
54
+ #
55
+ # @return [String] the command used to run Rake on the local computer
56
+ #
57
+ # @see DEFAULT_EXECUTABLE
48
58
  def local_executable
49
59
  @local_executable ||= DEFAULT_EXECUTABLE
50
60
  end
51
61
 
52
- # Returns the command used to run Rake on remote computers. Defaults to
53
- # DEFAULT_EXECUTABLE.
62
+ # The command used to run Rake on remote computers.
63
+ #
64
+ # @return [String] the command used to run Rake on remote computers
65
+ #
66
+ # @see DEFAULT_EXECUTABLE
54
67
  def remote_executable
55
68
  @remote_executable ||= DEFAULT_EXECUTABLE
56
69
  end
@@ -0,0 +1,30 @@
1
+ module Cape
2
+
3
+ # Provides utility functions.
4
+ module Util
5
+
6
+ # Conditionally transforms the specified _noun_ into its plural form.
7
+ #
8
+ # @param [String] noun a singular noun
9
+ # @param [Fixnum] count the quantity of _noun_; optional
10
+ # @return [String] the plural of _noun_, unless _count_ is +1+
11
+ def self.pluralize(singular_noun, count=2)
12
+ return singular_noun if count == 1
13
+
14
+ "#{singular_noun}s"
15
+ end
16
+
17
+ # Builds a list phrase from the elements of the specified _array_.
18
+ #
19
+ # @param [Array of String] array zero or more nouns
20
+ # @return [String] the elements of _array_, joined with commas and "and", as
21
+ # appropriate
22
+ def self.to_list_phrase(array)
23
+ return array.join(' and ') if (array.length <= 2)
24
+
25
+ [array[0...-1].join(', '), array[-1]].join ', and '
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -1,6 +1,6 @@
1
1
  module Cape
2
2
 
3
3
  # The version of Cape.
4
- VERSION = '1.0.1'
4
+ VERSION = '1.0.2'
5
5
 
6
6
  end
@@ -1,44 +1,44 @@
1
- require 'cape/strings'
1
+ require 'cape/util'
2
2
 
3
- describe Cape::Strings do
3
+ describe Cape::Util do
4
4
  describe '::pluralize' do
5
5
  it "should pluralize 'foo' as expected" do
6
- Cape::Strings.pluralize('foo').should == 'foos'
6
+ Cape::Util.pluralize('foo').should == 'foos'
7
7
  end
8
8
 
9
9
  it "should pluralize 'foo' as expected for a count of 2" do
10
- Cape::Strings.pluralize('foo', 2).should == 'foos'
10
+ Cape::Util.pluralize('foo', 2).should == 'foos'
11
11
  end
12
12
 
13
13
  it "should not pluralize for a count of 1" do
14
- Cape::Strings.pluralize('foo', 1).should == 'foo'
14
+ Cape::Util.pluralize('foo', 1).should == 'foo'
15
15
  end
16
16
 
17
17
  it "should pluralize 'foo' as expected for a count of 0" do
18
- Cape::Strings.pluralize('foo', 0).should == 'foos'
18
+ Cape::Util.pluralize('foo', 0).should == 'foos'
19
19
  end
20
20
 
21
21
  it "should pluralize 'foo' as expected for a count of -1" do
22
- Cape::Strings.pluralize('foo', -1).should == 'foos'
22
+ Cape::Util.pluralize('foo', -1).should == 'foos'
23
23
  end
24
24
  end
25
25
 
26
26
  describe '::to_list_phrase' do
27
27
  it 'should make the expected list phrase of an empty array' do
28
- Cape::Strings.to_list_phrase([]).should == ''
28
+ Cape::Util.to_list_phrase([]).should == ''
29
29
  end
30
30
 
31
31
  it 'should make the expected list phrase of a 1-element array' do
32
- Cape::Strings.to_list_phrase(%w(foo)).should == 'foo'
32
+ Cape::Util.to_list_phrase(%w(foo)).should == 'foo'
33
33
  end
34
34
 
35
35
  it 'should make the expected list phrase of a 2-element array' do
36
- Cape::Strings.to_list_phrase(%w(foo bar)).should == 'foo and bar'
36
+ Cape::Util.to_list_phrase(%w(foo bar)).should == 'foo and bar'
37
37
  end
38
38
 
39
39
  it 'should make the expected list phrase of a 3-element array' do
40
40
  array = %w(foo bar baz)
41
- Cape::Strings.to_list_phrase(array).should == 'foo, bar, and baz'
41
+ Cape::Util.to_list_phrase(array).should == 'foo, bar, and baz'
42
42
  end
43
43
  end
44
44
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cape
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 1
10
- version: 1.0.1
9
+ - 2
10
+ version: 1.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Nils Jonsson
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-11-30 00:00:00 Z
18
+ date: 2011-12-29 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: aruba
@@ -106,10 +106,9 @@ files:
106
106
  - features/dsl/mirror_rake_tasks/with_defined_task_argument.feature
107
107
  - features/dsl/mirror_rake_tasks/with_undefined_argument.feature
108
108
  - features/dsl/mirror_rake_tasks/without_arguments.feature
109
+ - features/dsl/rake_executable.feature
109
110
  - features/step_definitions.rb
110
111
  - features/support/env.rb
111
- - features/task_invocation/nonparameterized.feature
112
- - features/task_invocation/parameterized.feature
113
112
  - lib/cape.rb
114
113
  - lib/cape/capistrano.rb
115
114
  - lib/cape/core_ext.rb
@@ -117,15 +116,15 @@ files:
117
116
  - lib/cape/core_ext/symbol.rb
118
117
  - lib/cape/dsl.rb
119
118
  - lib/cape/rake.rb
120
- - lib/cape/strings.rb
119
+ - lib/cape/util.rb
121
120
  - lib/cape/version.rb
122
121
  - spec/cape/capistrano_spec.rb
123
122
  - spec/cape/core_ext/hash_spec.rb
124
123
  - spec/cape/core_ext/symbol_spec.rb
125
124
  - spec/cape/dsl_spec.rb
126
125
  - spec/cape/rake_spec.rb
127
- - spec/cape/strings_spec.rb
128
126
  - spec/cape/task_spec.rb
127
+ - spec/cape/util_spec.rb
129
128
  - spec/cape/version_spec.rb
130
129
  - spec/cape_spec.rb
131
130
  homepage: ""
@@ -176,17 +175,16 @@ test_files:
176
175
  - features/dsl/mirror_rake_tasks/with_defined_task_argument.feature
177
176
  - features/dsl/mirror_rake_tasks/with_undefined_argument.feature
178
177
  - features/dsl/mirror_rake_tasks/without_arguments.feature
178
+ - features/dsl/rake_executable.feature
179
179
  - features/step_definitions.rb
180
180
  - features/support/env.rb
181
- - features/task_invocation/nonparameterized.feature
182
- - features/task_invocation/parameterized.feature
183
181
  - spec/cape/capistrano_spec.rb
184
182
  - spec/cape/core_ext/hash_spec.rb
185
183
  - spec/cape/core_ext/symbol_spec.rb
186
184
  - spec/cape/dsl_spec.rb
187
185
  - spec/cape/rake_spec.rb
188
- - spec/cape/strings_spec.rb
189
186
  - spec/cape/task_spec.rb
187
+ - spec/cape/util_spec.rb
190
188
  - spec/cape/version_spec.rb
191
189
  - spec/cape_spec.rb
192
190
  has_rdoc: true
@@ -1,69 +0,0 @@
1
- Feature: Invoking parameterless Rake tasks via Capistrano
2
-
3
- In order to invoke Rake tasks via Capistrano,
4
- As a developer using Cape,
5
- I want to use the `cap` command.
6
-
7
- Scenario: invoke Rake task 'with_period'
8
- Given a full-featured Rakefile
9
- And a file named "Capfile" with:
10
- """
11
- load 'deploy' if respond_to?(:namespace) # cap2 differentiator
12
-
13
- # Uncomment if you are using Rails' asset pipeline
14
- # load 'deploy/assets'
15
-
16
- Dir['vendor/gems/*/recipes/*.rb','vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
17
-
18
- load 'config/deploy' # remove this line to skip loading any of the default tasks
19
- require 'cape'
20
-
21
- Cape do
22
- mirror_rake_tasks
23
- end
24
- """
25
- And a file named "config/deploy.rb" with:
26
- """
27
- require 'cape'
28
-
29
- Cape do
30
- mirror_rake_tasks
31
- end
32
- """
33
- When I run `cap with_period`
34
- Then the output should contain:
35
- """
36
- * executing `with_period'
37
- """
38
-
39
- Scenario: invoke Rake task 'my_namespace:in_a_namespace'
40
- Given a full-featured Rakefile
41
- And a file named "Capfile" with:
42
- """
43
- load 'deploy' if respond_to?(:namespace) # cap2 differentiator
44
-
45
- # Uncomment if you are using Rails' asset pipeline
46
- # load 'deploy/assets'
47
-
48
- Dir['vendor/gems/*/recipes/*.rb','vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
49
-
50
- load 'config/deploy' # remove this line to skip loading any of the default tasks
51
- require 'cape'
52
-
53
- Cape do
54
- mirror_rake_tasks
55
- end
56
- """
57
- And a file named "config/deploy.rb" with:
58
- """
59
- require 'cape'
60
-
61
- Cape do
62
- mirror_rake_tasks
63
- end
64
- """
65
- When I run `cap my_namespace:in_a_namespace`
66
- Then the output should contain:
67
- """
68
- * executing `my_namespace:in_a_namespace'
69
- """
@@ -1,70 +0,0 @@
1
- Feature: Invoking parameterized Rake tasks via Capistrano
2
-
3
- In order to invoke Rake tasks via Capistrano,
4
- As a developer using Cape,
5
- I want to use the `cap` command.
6
-
7
- Scenario: invoke Rake task 'with_one_arg' without an argument
8
- Given a full-featured Rakefile
9
- And a file named "Capfile" with:
10
- """
11
- load 'deploy' if respond_to?(:namespace) # cap2 differentiator
12
-
13
- # Uncomment if you are using Rails' asset pipeline
14
- # load 'deploy/assets'
15
-
16
- Dir['vendor/gems/*/recipes/*.rb','vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
17
-
18
- load 'config/deploy' # remove this line to skip loading any of the default tasks
19
- require 'cape'
20
-
21
- Cape do
22
- mirror_rake_tasks
23
- end
24
- """
25
- And a file named "config/deploy.rb" with:
26
- """
27
- require 'cape'
28
-
29
- Cape do
30
- mirror_rake_tasks
31
- end
32
- """
33
- When I run `cap with_one_arg`
34
- Then the output should contain:
35
- """
36
- * executing `with_one_arg'
37
- """
38
- And the output should contain "Environment variable THE_ARG must be set (RuntimeError)"
39
-
40
- Scenario: invoke Rake task 'with_one_arg' with its argument
41
- Given a full-featured Rakefile
42
- And a file named "Capfile" with:
43
- """
44
- load 'deploy' if respond_to?(:namespace) # cap2 differentiator
45
-
46
- # Uncomment if you are using Rails' asset pipeline
47
- # load 'deploy/assets'
48
-
49
- Dir['vendor/gems/*/recipes/*.rb','vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
50
-
51
- load 'config/deploy' # remove this line to skip loading any of the default tasks
52
- require 'cape'
53
-
54
- Cape do
55
- mirror_rake_tasks
56
- end
57
- """
58
- And a file named "config/deploy.rb" with:
59
- """
60
- require 'cape'
61
-
62
- Cape do
63
- mirror_rake_tasks
64
- end
65
- """
66
- When I run `cap with_one_arg THE_ARG="the arg goes here"`
67
- Then the output should contain:
68
- """
69
- * executing `with_one_arg'
70
- """
@@ -1,25 +0,0 @@
1
- module Cape
2
-
3
- # Provides utility methods for String objects.
4
- module Strings
5
-
6
- extend self
7
-
8
- # Returns the English plural form of _noun_, unless _count_ is +1+. The
9
- # _count_ argument is optional, and defaults to +2+.
10
- def pluralize(noun, count=2)
11
- return noun if count == 1
12
-
13
- "#{noun}s"
14
- end
15
-
16
- # Builds an English list phrase from the elements of _array_.
17
- def to_list_phrase(array)
18
- return array.join(' and ') if (array.length <= 2)
19
-
20
- [array[0...-1].join(', '), array[-1]].join ', and '
21
- end
22
-
23
- end
24
-
25
- end