railsless-deploy 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ *.gem
2
+ *.gemspec
3
+ pkg/*
@@ -0,0 +1,27 @@
1
+ # Lee Hambley's Railsless Deploy
2
+
3
+ ## 0.0.15 - July 7th 2009
4
+
5
+ * Removed `require 'yaml'` as we don't use it
6
+ * Removed the tasks (which contained only deprecation warnings) from deploy:start, deploy:stop and deploy:restart.
7
+
8
+ ## 0.0.14 - July 7th 2009
9
+
10
+ * Added dates to changelog.
11
+ * Including the output of cap -T in the readme for display on GitHub.
12
+
13
+ ## 0.0.13 - July 7th 2009
14
+
15
+ * Fixes a README problem and includes the README and CHANGELOG in the gem.
16
+
17
+ ## 0.0.12 - July 7th 2009
18
+
19
+ * Trivial documentation changes
20
+
21
+ ## 0.0.11 - July 6th 2009
22
+
23
+ * Gemspec changed to run under SAFE=3 mode
24
+
25
+ ## 0.0.10 - July 6th 2009
26
+
27
+ * Initial release, GitHub gem enabled.
@@ -0,0 +1,22 @@
1
+ Copyright (c) <2009> Lee Hambley <lee.hambley@gmail.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,50 @@
1
+ # Lee Hambley's Railsless Deploy
2
+
3
+ If you want to get the most out of Capistrano and you do not want to have to deal with the *railsisms* that ship by default, this is the gem for you.
4
+
5
+ ## Installation
6
+
7
+ # gem sources -a http://gems.github.com/
8
+ # gem install leehambley-railsless-deploy
9
+
10
+ ## Usage
11
+
12
+ Open your application's `Capfile` and make it look like this, the last three lines are the magic. also you can safely remove line two if you won't be loading additional plugin files. (this is a railsism):
13
+
14
+ load 'deploy' if respond_to?(:namespace) # cap2 differentiator
15
+ # Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
16
+
17
+ require 'rubygems'
18
+ require 'railsless-deploy'
19
+ load 'config/deploy'
20
+
21
+ You should then be able to proceed as you would usually, you may want to familiarise yourself with the truncated list of tasks, you can get a full list with:
22
+
23
+ $ cap -T
24
+
25
+ ## What's in the box?
26
+
27
+ If you want to try before you buy, here's the list of tasks included with this version of the deploy recipe:
28
+
29
+ cap deploy # Deploys your project.
30
+ cap deploy:check # Test deployment dependencies.
31
+ cap deploy:cleanup # Clean up old releases.
32
+ cap deploy:cold # Deploys and starts a `cold' application.
33
+ cap deploy:pending # Displays the commits since your last deploy.
34
+ cap deploy:pending:diff # Displays the `diff' since your last deploy.
35
+ cap deploy:rollback # Rolls back to a previous version and restarts.
36
+ cap deploy:rollback:code # Rolls back to the previously deployed version.
37
+ cap deploy:setup # Prepares one or more servers for deployment.
38
+ cap deploy:symlink # Updates the symlink to the most recently deployed ...
39
+ cap deploy:update # Copies your project and updates the symlink.
40
+ cap deploy:update_code # Copies your project to the remote servers.
41
+ cap deploy:upload # Copy files to the currently deployed version.
42
+ cap invoke # Invoke a single command on the remote servers.
43
+ cap shell # Begin an interactive Capistrano session.
44
+
45
+
46
+ ## Bugs & Feedback
47
+
48
+ Via my Github profile please:
49
+
50
+ http://github.com/leehambley
@@ -0,0 +1,13 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gemspec|
4
+ gemspec.name = "railsless-deploy"
5
+ gemspec.summary = "Replacement for the default Capistrano tasks, designed to make life easier for PHP/Perl/Python developers"
6
+ gemspec.description = "Replacement for the rails deploy strategy which ships with Capistrano, allows you to deploy any platform with ease; some people have had huge success with this deploying rails projects where they needed to customise their deploy strategy beyond the code which ships with the Capistrano gem."
7
+ gemspec.email = "lee.hambley@gmail.com"
8
+ gemspec.homepage = "http://github.com/leehambley/railsless-deploy/"
9
+ gemspec.authors = ["Lee Hambley"]
10
+ end
11
+ rescue LoadError
12
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
13
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,412 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+
3
+ require 'capistrano/recipes/deploy/scm'
4
+ require 'capistrano/recipes/deploy/strategy'
5
+
6
+ def _cset(name, *args, &block)
7
+ unless exists?(name)
8
+ set(name, *args, &block)
9
+ end
10
+ end
11
+
12
+ # =========================================================================
13
+ # These variables MUST be set in the client capfiles. If they are not set,
14
+ # the deploy will fail with an error.
15
+ # =========================================================================
16
+
17
+ _cset(:application) { abort "Please specify the name of your application, set :application, 'foo'" }
18
+ _cset(:repository) { abort "Please specify the repository that houses your application's code, set :repository, 'foo'" }
19
+
20
+ # =========================================================================
21
+ # These variables may be set in the client capfile if their default values
22
+ # are not sufficient.
23
+ # =========================================================================
24
+
25
+ _cset :scm, :subversion
26
+ _cset :deploy_via, :checkout
27
+
28
+ _cset(:deploy_to) { "/u/apps/#{application}" }
29
+ _cset(:revision) { source.head }
30
+
31
+ # =========================================================================
32
+ # These variables should NOT be changed unless you are very confident in
33
+ # what you are doing. Make sure you understand all the implications of your
34
+ # changes if you do decide to muck with these!
35
+ # =========================================================================
36
+
37
+ _cset(:source) { Capistrano::Deploy::SCM.new(scm, self) }
38
+ _cset(:real_revision) { source.local.query_revision(revision) { |cmd| with_env("LC_ALL", "C") { run_locally(cmd) } } }
39
+
40
+ _cset(:strategy) { Capistrano::Deploy::Strategy.new(deploy_via, self) }
41
+
42
+ _cset(:release_name) { set :deploy_timestamped, true; Time.now.utc.strftime("%Y%m%d%H%M%S") }
43
+
44
+ _cset :version_dir, "releases"
45
+ _cset :shared_dir, "shared"
46
+ _cset :shared_children, %w(system log pids)
47
+ _cset :current_dir, "current"
48
+
49
+ _cset(:releases_path) { File.join(deploy_to, version_dir) }
50
+ _cset(:shared_path) { File.join(deploy_to, shared_dir) }
51
+ _cset(:current_path) { File.join(deploy_to, current_dir) }
52
+ _cset(:release_path) { File.join(releases_path, release_name) }
53
+
54
+ _cset(:releases) { capture("ls -xt #{releases_path}").split.reverse }
55
+ _cset(:current_release) { File.join(releases_path, releases.last) }
56
+ _cset(:previous_release) { releases.length > 1 ? File.join(releases_path, releases[-2]) : nil }
57
+
58
+ _cset(:current_revision) { capture("cat #{current_path}/REVISION").chomp }
59
+ _cset(:latest_revision) { capture("cat #{current_release}/REVISION").chomp }
60
+ _cset(:previous_revision) { capture("cat #{previous_release}/REVISION").chomp }
61
+
62
+ _cset(:run_method) { fetch(:use_sudo, true) ? :sudo : :run }
63
+
64
+ # some tasks, like symlink, need to always point at the latest release, but
65
+ # they can also (occassionally) be called standalone. In the standalone case,
66
+ # the timestamped release_path will be inaccurate, since the directory won't
67
+ # actually exist. This variable lets tasks like symlink work either in the
68
+ # standalone case, or during deployment.
69
+ _cset(:latest_release) { exists?(:deploy_timestamped) ? release_path : current_release }
70
+
71
+ # =========================================================================
72
+ # These are helper methods that will be available to your recipes.
73
+ # =========================================================================
74
+
75
+ # Auxiliary helper method for the `deploy:check' task. Lets you set up your
76
+ # own dependencies.
77
+ def depend(location, type, *args)
78
+ deps = fetch(:dependencies, {})
79
+ deps[location] ||= {}
80
+ deps[location][type] ||= []
81
+ deps[location][type] << args
82
+ set :dependencies, deps
83
+ end
84
+
85
+ # Temporarily sets an environment variable, yields to a block, and restores
86
+ # the value when it is done.
87
+ def with_env(name, value)
88
+ saved, ENV[name] = ENV[name], value
89
+ yield
90
+ ensure
91
+ ENV[name] = saved
92
+ end
93
+
94
+ # logs the command then executes it locally.
95
+ # returns the command output as a string
96
+ def run_locally(cmd)
97
+ logger.trace "executing locally: #{cmd.inspect}" if logger
98
+ `#{cmd}`
99
+ end
100
+
101
+ # If a command is given, this will try to execute the given command, as
102
+ # described below. Otherwise, it will return a string for use in embedding in
103
+ # another command, for executing that command as described below.
104
+ #
105
+ # If :run_method is :sudo (or :use_sudo is true), this executes the given command
106
+ # via +sudo+. Otherwise is uses +run+. If :as is given as a key, it will be
107
+ # passed as the user to sudo as, if using sudo. If the :as key is not given,
108
+ # it will default to whatever the value of the :admin_runner variable is,
109
+ # which (by default) is unset.
110
+ #
111
+ # THUS, if you want to try to run something via sudo, and what to use the
112
+ # root user, you'd just to try_sudo('something'). If you wanted to try_sudo as
113
+ # someone else, you'd just do try_sudo('something', :as => "bob"). If you
114
+ # always wanted sudo to run as a particular user, you could do
115
+ # set(:admin_runner, "bob").
116
+ def try_sudo(*args)
117
+ options = args.last.is_a?(Hash) ? args.pop : {}
118
+ command = args.shift
119
+ raise ArgumentError, "too many arguments" if args.any?
120
+
121
+ as = options.fetch(:as, fetch(:admin_runner, nil))
122
+ via = fetch(:run_method, :sudo)
123
+ if command
124
+ invoke_command(command, :via => via, :as => as)
125
+ elsif via == :sudo
126
+ sudo(:as => as)
127
+ else
128
+ ""
129
+ end
130
+ end
131
+
132
+ # Same as sudo, but tries sudo with :as set to the value of the :runner
133
+ # variable (which defaults to "app").
134
+ def try_runner(*args)
135
+ options = args.last.is_a?(Hash) ? args.pop : {}
136
+ args << options.merge(:as => fetch(:runner, "app"))
137
+ try_sudo(*args)
138
+ end
139
+
140
+ # =========================================================================
141
+ # These are the tasks that are available to help with deploying web apps,
142
+ # and specifically, Rails applications. You can have cap give you a summary
143
+ # of them with `cap -T'.
144
+ # =========================================================================
145
+
146
+ namespace :deploy do
147
+ desc <<-DESC
148
+ Deploys your project. This calls both `update' and `restart'. Note that \
149
+ this will generally only work for applications that have already been deployed \
150
+ once. For a "cold" deploy, you'll want to take a look at the `deploy:cold' \
151
+ task, which handles the cold start specifically.
152
+ DESC
153
+ task :default do
154
+ update
155
+ # restart
156
+ end
157
+
158
+ desc <<-DESC
159
+ Prepares one or more servers for deployment. Before you can use any \
160
+ of the Capistrano deployment tasks with your project, you will need to \
161
+ make sure all of your servers have been prepared with `cap deploy:setup'. When \
162
+ you add a new server to your cluster, you can easily run the setup task \
163
+ on just that server by specifying the HOSTS environment variable:
164
+
165
+ $ cap HOSTS=new.server.com deploy:setup
166
+
167
+ It is safe to run this task on servers that have already been set up; it \
168
+ will not destroy any deployed revisions or data.
169
+ DESC
170
+ task :setup, :except => { :no_release => true } do
171
+ dirs = [deploy_to, releases_path, shared_path]
172
+ dirs += shared_children.map { |d| File.join(shared_path, d) }
173
+ run "#{try_sudo} mkdir -p #{dirs.join(' ')} && #{try_sudo} chmod g+w #{dirs.join(' ')}"
174
+ end
175
+
176
+ desc <<-DESC
177
+ Copies your project and updates the symlink. It does this in a \
178
+ transaction, so that if either `update_code' or `symlink' fail, all \
179
+ changes made to the remote servers will be rolled back, leaving your \
180
+ system in the same state it was in before `update' was invoked. Usually, \
181
+ you will want to call `deploy' instead of `update', but `update' can be \
182
+ handy if you want to deploy, but not immediately restart your application.
183
+ DESC
184
+ task :update do
185
+ transaction do
186
+ update_code
187
+ symlink
188
+ end
189
+ end
190
+
191
+ desc <<-DESC
192
+ Copies your project to the remote servers. This is the first stage \
193
+ of any deployment; moving your updated code and assets to the deployment \
194
+ servers. You will rarely call this task directly, however; instead, you \
195
+ should call the `deploy' task (to do a complete deploy) or the `update' \
196
+ task (if you want to perform the `restart' task separately).
197
+
198
+ You will need to make sure you set the :scm variable to the source \
199
+ control software you are using (it defaults to :subversion), and the \
200
+ :deploy_via variable to the strategy you want to use to deploy (it \
201
+ defaults to :checkout).
202
+ DESC
203
+ task :update_code, :except => { :no_release => true } do
204
+ on_rollback { run "rm -rf #{release_path}; true" }
205
+ strategy.deploy!
206
+ finalize_update
207
+ end
208
+
209
+ desc <<-DESC
210
+ [internal] Touches up the released code. This is called by update_code \
211
+ after the basic deploy finishes. It assumes a Rails project was deployed, \
212
+ so if you are deploying something else, you may want to override this \
213
+ task with your own environment's requirements.
214
+
215
+ This task will make the release group-writable (if the :group_writable \
216
+ variable is set to true, which is the default). It will then set up \
217
+ symlinks to the shared directory for the log, system, and tmp/pids \
218
+ directories, and will lastly touch all assets in public/images, \
219
+ public/stylesheets, and public/javascripts so that the times are \
220
+ consistent (so that asset timestamping works). This touch process \
221
+ is only carried out if the :normalize_asset_timestamps variable is \
222
+ set to true, which is the default.
223
+ DESC
224
+ task :finalize_update, :except => { :no_release => true } do
225
+ run "chmod -R g+w #{latest_release}" if fetch(:group_writable, true)
226
+ end
227
+
228
+ desc <<-DESC
229
+ Updates the symlink to the most recently deployed version. Capistrano works \
230
+ by putting each new release of your application in its own directory. When \
231
+ you deploy a new version, this task's job is to update the `current' symlink \
232
+ to point at the new version. You will rarely need to call this task \
233
+ directly; instead, use the `deploy' task (which performs a complete \
234
+ deploy, including `restart') or the 'update' task (which does everything \
235
+ except `restart').
236
+ DESC
237
+ task :symlink, :except => { :no_release => true } do
238
+ on_rollback do
239
+ if previous_release
240
+ run "rm -f #{current_path}; ln -s #{previous_release} #{current_path}; true"
241
+ else
242
+ logger.important "no previous release to rollback to, rollback of symlink skipped"
243
+ end
244
+ end
245
+
246
+ run "rm -f #{current_path} && ln -s #{latest_release} #{current_path}"
247
+ end
248
+
249
+ desc <<-DESC
250
+ Copy files to the currently deployed version. This is useful for updating \
251
+ files piecemeal, such as when you need to quickly deploy only a single \
252
+ file. Some files, such as updated templates, images, or stylesheets, \
253
+ might not require a full deploy, and especially in emergency situations \
254
+ it can be handy to just push the updates to production, quickly.
255
+
256
+ To use this task, specify the files and directories you want to copy as a \
257
+ comma-delimited list in the FILES environment variable. All directories \
258
+ will be processed recursively, with all files being pushed to the \
259
+ deployment servers.
260
+
261
+ $ cap deploy:upload FILES=templates,controller.rb
262
+
263
+ Dir globs are also supported:
264
+
265
+ $ cap deploy:upload FILES='config/apache/*.conf'
266
+ DESC
267
+ task :upload, :except => { :no_release => true } do
268
+ files = (ENV["FILES"] || "").split(",").map { |f| Dir[f.strip] }.flatten
269
+ abort "Please specify at least one file or directory to update (via the FILES environment variable)" if files.empty?
270
+
271
+ files.each { |file| top.upload(file, File.join(current_path, file)) }
272
+ end
273
+
274
+ namespace :rollback do
275
+ desc <<-DESC
276
+ [internal] Points the current symlink at the previous revision.
277
+ This is called by the rollback sequence, and should rarely (if
278
+ ever) need to be called directly.
279
+ DESC
280
+ task :revision, :except => { :no_release => true } do
281
+ if previous_release
282
+ run "rm #{current_path}; ln -s #{previous_release} #{current_path}"
283
+ else
284
+ abort "could not rollback the code because there is no prior release"
285
+ end
286
+ end
287
+
288
+ desc <<-DESC
289
+ [internal] Removes the most recently deployed release.
290
+ This is called by the rollback sequence, and should rarely
291
+ (if ever) need to be called directly.
292
+ DESC
293
+ task :cleanup, :except => { :no_release => true } do
294
+ run "if [ `readlink #{current_path}` != #{current_release} ]; then rm -rf #{current_release}; fi"
295
+ end
296
+
297
+ desc <<-DESC
298
+ Rolls back to the previously deployed version. The `current' symlink will \
299
+ be updated to point at the previously deployed version, and then the \
300
+ current release will be removed from the servers.
301
+ DESC
302
+ task :code, :except => { :no_release => true } do
303
+ revision
304
+ cleanup
305
+ end
306
+
307
+ desc <<-DESC
308
+ Rolls back to a previous version and restarts. This is handy if you ever \
309
+ discover that you've deployed a lemon; `cap rollback' and you're right \
310
+ back where you were, on the previously deployed version.
311
+ DESC
312
+ task :default do
313
+ revision
314
+ cleanup
315
+ end
316
+ end
317
+
318
+ desc <<-DESC
319
+ Clean up old releases. By default, the last 5 releases are kept on each \
320
+ server (though you can change this with the keep_releases variable). All \
321
+ other deployed revisions are removed from the servers. By default, this \
322
+ will use sudo to clean up the old releases, but if sudo is not available \
323
+ for your environment, set the :use_sudo variable to false instead.
324
+ DESC
325
+ task :cleanup, :except => { :no_release => true } do
326
+ count = fetch(:keep_releases, 5).to_i
327
+ if count >= releases.length
328
+ logger.important "no old releases to clean up"
329
+ else
330
+ logger.info "keeping #{count} of #{releases.length} deployed releases"
331
+
332
+ directories = (releases - releases.last(count)).map { |release|
333
+ File.join(releases_path, release) }.join(" ")
334
+
335
+ try_sudo "rm -rf #{directories}"
336
+ end
337
+ end
338
+
339
+ desc <<-DESC
340
+ Test deployment dependencies. Checks things like directory permissions, \
341
+ necessary utilities, and so forth, reporting on the things that appear to \
342
+ be incorrect or missing. This is good for making sure a deploy has a \
343
+ chance of working before you actually run `cap deploy'.
344
+
345
+ You can define your own dependencies, as well, using the `depend' method:
346
+
347
+ depend :remote, :gem, "tzinfo", ">=0.3.3"
348
+ depend :local, :command, "svn"
349
+ depend :remote, :directory, "/u/depot/files"
350
+ DESC
351
+ task :check, :except => { :no_release => true } do
352
+ dependencies = strategy.check!
353
+
354
+ other = fetch(:dependencies, {})
355
+ other.each do |location, types|
356
+ types.each do |type, calls|
357
+ if type == :gem
358
+ dependencies.send(location).command(fetch(:gem_command, "gem")).or("`gem' command could not be found. Try setting :gem_command")
359
+ end
360
+
361
+ calls.each do |args|
362
+ dependencies.send(location).send(type, *args)
363
+ end
364
+ end
365
+ end
366
+
367
+ if dependencies.pass?
368
+ puts "You appear to have all necessary dependencies installed"
369
+ else
370
+ puts "The following dependencies failed. Please check them and try again:"
371
+ dependencies.reject { |d| d.pass? }.each do |d|
372
+ puts "--> #{d.message}"
373
+ end
374
+ abort
375
+ end
376
+ end
377
+
378
+ desc <<-DESC
379
+ Deploys and starts a `cold' application. This is useful if you have not \
380
+ deployed your application before, or if your application is (for some \
381
+ other reason) not currently running. It will deploy the code, run any \
382
+ pending migrations, and then instead of invoking `deploy:restart', it will \
383
+ invoke `deploy:start' to fire up the application servers.
384
+ DESC
385
+ task :cold do
386
+ update
387
+ end
388
+
389
+ namespace :pending do
390
+ desc <<-DESC
391
+ Displays the `diff' since your last deploy. This is useful if you want \
392
+ to examine what changes are about to be deployed. Note that this might \
393
+ not be supported on all SCM's.
394
+ DESC
395
+ task :diff, :except => { :no_release => true } do
396
+ system(source.local.diff(current_revision))
397
+ end
398
+
399
+ desc <<-DESC
400
+ Displays the commits since your last deploy. This is good for a summary \
401
+ of the changes that have occurred since the last deploy. Note that this \
402
+ might not be supported on all SCM's.
403
+ DESC
404
+ task :default, :except => { :no_release => true } do
405
+ from = source.next_revision(current_revision)
406
+ system(source.local.log(from))
407
+ end
408
+ end
409
+
410
+ end
411
+
412
+ end # Capistrano::Configuration.instance(:must_exist).load do
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: railsless-deploy
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Lee Hambley
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-15 00:00:00 +02:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Replacement for the rails deploy strategy which ships with Capistrano, allows you to deploy any platform with ease; some people have had huge success with this deploying rails projects where they needed to customise their deploy strategy beyond the code which ships with the Capistrano gem.
17
+ email: lee.hambley@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE.markdown
24
+ - README.markdown
25
+ files:
26
+ - .gitignore
27
+ - CHANGELOG.markdown
28
+ - LICENSE.markdown
29
+ - README.markdown
30
+ - Rakefile
31
+ - VERSION
32
+ - lib/railsless-deploy.rb
33
+ has_rdoc: true
34
+ homepage: http://github.com/leehambley/railsless-deploy/
35
+ licenses: []
36
+
37
+ post_install_message:
38
+ rdoc_options:
39
+ - --charset=UTF-8
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ version:
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ version:
54
+ requirements: []
55
+
56
+ rubyforge_project:
57
+ rubygems_version: 1.3.5
58
+ signing_key:
59
+ specification_version: 3
60
+ summary: Replacement for the default Capistrano tasks, designed to make life easier for PHP/Perl/Python developers
61
+ test_files: []
62
+