capistrano 2.5.5 → 2.5.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,13 @@
1
+ == 2.5.6 / 25 May 2009
2
+
3
+ * Clean the cached git repository [Graeme Mathieson]
4
+ * Fixes perforce issues reported at http://bit.ly/wt0es [Scott Johnson]
5
+ * Improved back-tick handling code in relation to the above.
6
+ * Removes rails-assumptions, more info see a freshly generated config/deploy.rb
7
+ * Fixes a Git issue when submodules update upstream. (via mailing list) [sneakin]
8
+ * Ensures that the deploy_to directory is chowned :user/:user during deploy:setup
9
+ * Capify now creates the config directory in directories without one.
10
+
1
11
  == 2.5.5 / 24 Feb 2009
2
12
 
3
13
  * Make sure role(:foo) actually declares an (empty) role for :foo, even without server arguments [Jamis Buck]
@@ -5,6 +5,39 @@ Capistrano is a utility and framework for executing commands in parallel on mult
5
5
  Capistrano was originally designed to simplify and automate deployment of web applications to distributed environments, and originally came bundled with a set of tasks designed for deploying Rails applications. The deployment tasks are now (as of Capistrano 2.0) opt-in and require clients to explicitly put
6
6
  "load 'deploy'" in their recipes.
7
7
 
8
+ == 2.5.6 Warning
9
+
10
+ _+Warning+_: while every care has been taken to make sure you do not feel too much disruption from existing deploys when upgrading to 2.5.6 unless you alter your capfile (see "New Style Capification" towards the end of the readme for more) will require a couple more lines to keep compatibility with old recipes.
11
+
12
+ The changes in 2.5.6 include bug fixes, but importantly also remove a number of rails assumptions. This has been done both to ensure that people who aren't deploy Rails applications aren't put-off using Capistrano, and also that those of us that do use Rails have a choice about certain things. (starting our app, restarting it, stopping it, do we want cap to manage migrations, etc..)
13
+
14
+ As a result failure to read this document thoroughly could lead to problems, if you do install 2.5.6 and your recipe breaks, please either uninstall the gem and file a bug report (we will try to fix them within hours if received through our lighthouse app account.) or invoke cap in the following way to dictate which version you wish to use:
15
+
16
+ cap _2.5.5_ deploy
17
+ cap _2.5.5_ staging my:task:here
18
+ cap _2.5.5_ -vT
19
+ cap _2.5.6_ -vT
20
+
21
+ Please open issues on the bug tracer at http://capistrano.lighthouseapp.com/ if you experience problems
22
+
23
+ == Documentation
24
+
25
+ We know that documentation is something that really lets us down, that's why there is a repository for a handbook below, please open an issue on it if you would like something documented:
26
+
27
+ * http://github.com/leehambley/capistrano-handbook
28
+
29
+ If you prefer the wiki style of documentation, then please see our wiki
30
+
31
+ * http://wiki.capify.org
32
+
33
+ Due to a failure of MySQL with PHP, searches shorter than three characters are all but ignored, we're going to rectify this, but in the meantime, please do what you can, tickets opened on the handbook for the wiki will be answered too, so please let us know if you don't find something you needed.
34
+
35
+ We take bug reports via lighthouse app, you can find that page here:
36
+
37
+ * http://capistrano.lighthouseapp.com
38
+
39
+ More documentation is on the way, if in doubt try opening the recipes that ship with capistrano.
40
+
8
41
  == DEPENDENCIES
9
42
 
10
43
  * Net::SSH v2 (http://net-ssh.rubyforge.org)
@@ -40,6 +73,63 @@ Use the +cap+ script as follows:
40
73
 
41
74
  By default, the script will look for a file called one of +capfile+ or +Capfile+. The +someaction+ text indicates which task to execute. You can do "cap -h" to see all the available options and "cap -T" to see all the available tasks.
42
75
 
76
+ == Capistrano Edge
77
+
78
+ If you want to try Capistrano code that hasn't been formerly released yet, this repository now includes a gemspec that should build what you need, here's how to get a copy:
79
+
80
+ git clone git://github.com/capistrano/capistrano.git capistrano-capistrano
81
+ cd capistrano-capsitrano
82
+ gem build capistrano.gemspec
83
+ sudo gem install capistrano-*.gem
84
+
85
+ This will install the most recent version of capistrano and make it available for both cap, and capify.
86
+
87
+ We recommend that you capify a new test application, as the resulting files are different to previous versions.
88
+
89
+ If you have multiple versions of capistrano (or indeed any gem with a binary) installed, you can call `cap` like so to specify which version to use:
90
+
91
+ cap _2.5.5_ deploy
92
+ cap _2.5.6_ deploy:setup
93
+
94
+ == New Style Capification
95
+
96
+ When calling `capify` on a new application, the result will look something like the following, this is a big change to previous versions, please take this as a warning and read the following thoroughly:
97
+
98
+ set :application, "set your application name here"
99
+ set :repository, "set your repository location here"
100
+
101
+ # If you have previously been relying upon the code to start, stop
102
+ # and restart your mongrel application, or if you rely on the database
103
+ # migration code, please uncomment the lines you require below
104
+
105
+ # If you are deploying a rails app you probably need these:
106
+
107
+ # load 'ext/rails-database-migrations.rb'
108
+ # load 'ext/rails-shared-directories.rb'
109
+
110
+ # There are also new utility libaries shipped with the core these
111
+ # include the following, please see individual files for more
112
+ # documentation, or run `cap -vT` with the following lines commented
113
+ # out to see what they make available.
114
+
115
+ # load 'ext/spinner.rb' # Designed for use with script/spin
116
+ # load 'ext/passenger-mod-rails.rb' # Restart task for use with mod_rails
117
+ # load 'ext/web-disable-enable.rb' # Gives you web:disable and web:enable
118
+
119
+ # If you aren't deploying to /u/apps/\#{application} on the target
120
+ # servers (which is the default), you can specify the actual location
121
+ # via the :deploy_to variable:
122
+ # set :deploy_to, "/var/www/\#{application}"
123
+
124
+ # If you aren't using Subversion to manage your source code, specify
125
+ # your SCM below:
126
+ # set :scm, :subversion
127
+ # see a full list by running "gem contents capistrano | grep 'scm/'"
128
+
129
+ role :web, "your web-server here"
130
+
131
+ When adding or removing extensions, where you have previously tested a `deploy:setup` we recommend that you perform another, especially for example when adding the rails-shared-directory code.
132
+
43
133
  == LICENSE:
44
134
 
45
135
  (The MIT License)
data/Rakefile CHANGED
@@ -12,6 +12,7 @@ if ENV['SNAPSHOT'].to_i == 1
12
12
  end
13
13
 
14
14
  Echoe.new('capistrano', version) do |p|
15
+ p.include_gemspec = true
15
16
  p.changelog = "CHANGELOG.rdoc"
16
17
 
17
18
  p.author = "Jamis Buck"
data/bin/capify CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'optparse'
4
+ require 'fileutils'
4
5
 
5
6
  OptionParser.new do |opts|
6
7
  opts.banner = "Usage: #{File.basename($0)} [path]"
@@ -45,6 +46,24 @@ files = {
45
46
  set :application, "set your application name here"
46
47
  set :repository, "set your repository location here"
47
48
 
49
+ # If you have previously been relying upon the code to start, stop
50
+ # and restart your mongrel application, or if you rely on the database
51
+ # migration code, please uncomment the lines you require below
52
+
53
+ # If you are deploying a rails app you probably need these:
54
+
55
+ # load 'ext/rails-database-migrations.rb'
56
+ # load 'ext/rails-shared-directories.rb'
57
+
58
+ # There are also new utility libaries shipped with the core these
59
+ # include the following, please see individual files for more
60
+ # documentation, or run `cap -vT` with the following lines commented
61
+ # out to see what they make available.
62
+
63
+ # load 'ext/spinner.rb' # Designed for use with script/spin
64
+ # load 'ext/passenger-mod-rails.rb' # Restart task for use with mod_rails
65
+ # load 'ext/web-disable-enable.rb' # Gives you web:disable and web:enable
66
+
48
67
  # If you aren't deploying to /u/apps/\#{application} on the target
49
68
  # servers (which is the default), you can specify the actual location
50
69
  # via the :deploy_to variable:
@@ -53,10 +72,10 @@ files = {
53
72
  # If you aren't using Subversion to manage your source code, specify
54
73
  # your SCM below:
55
74
  # set :scm, :subversion
75
+ # see a full list by running "gem contents capistrano | grep 'scm/'"
56
76
 
57
- role :app, "your app-server here"
58
77
  role :web, "your web-server here"
59
- role :db, "your db-server here", :primary => true
78
+
60
79
  FILE
61
80
  }
62
81
 
@@ -68,7 +87,9 @@ files.each do |file, content|
68
87
  elsif File.exists?(file.downcase)
69
88
  warn "[skip] `#{file.downcase}' exists, which could conflict with `#{file}'"
70
89
  elsif !File.exists?(File.dirname(file))
71
- warn "[skip] directory `#{File.dirname(file)}' does not exist"
90
+ FileUtils.mkdir(File.dirname(file))
91
+ retry
92
+ warn "[skip] directory `#{File.dirname(file)}' did not exist, created."
72
93
  else
73
94
  puts "[add] writing `#{file}'"
74
95
  File.open(file, "w") { |f| f.write(content) }
@@ -1,22 +1,24 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = %q{capistrano}
3
- s.version = "2.5.5"
4
-
3
+ s.version = "2.5.6"
5
4
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
6
- s.authors = ["Jamis Buck"]
5
+ s.authors = ["Jamis Buck", "Lee Hambley"]
7
6
  s.date = %q{2009-02-24}
8
7
  s.description = %q{Capistrano is a utility and framework for executing commands in parallel on multiple remote machines, via SSH.}
9
- s.email = %q{jamis@jamisbuck.org}
8
+ s.email = %q{lee.hambley@gmail.com}
10
9
  s.executables = ["cap", "capify"]
11
10
  s.extra_rdoc_files = ["CHANGELOG.rdoc", "lib/capistrano/callback.rb", "lib/capistrano/cli/execute.rb", "lib/capistrano/cli/help.rb", "lib/capistrano/cli/help.txt", "lib/capistrano/cli/options.rb", "lib/capistrano/cli/ui.rb", "lib/capistrano/cli.rb", "lib/capistrano/command.rb", "lib/capistrano/configuration/actions/file_transfer.rb", "lib/capistrano/configuration/actions/inspect.rb", "lib/capistrano/configuration/actions/invocation.rb", "lib/capistrano/configuration/callbacks.rb", "lib/capistrano/configuration/connections.rb", "lib/capistrano/configuration/execution.rb", "lib/capistrano/configuration/loading.rb", "lib/capistrano/configuration/namespaces.rb", "lib/capistrano/configuration/roles.rb", "lib/capistrano/configuration/servers.rb", "lib/capistrano/configuration/variables.rb", "lib/capistrano/configuration.rb", "lib/capistrano/errors.rb", "lib/capistrano/extensions.rb", "lib/capistrano/logger.rb", "lib/capistrano/processable.rb", "lib/capistrano/recipes/compat.rb", "lib/capistrano/recipes/deploy/dependencies.rb", "lib/capistrano/recipes/deploy/local_dependency.rb", "lib/capistrano/recipes/deploy/remote_dependency.rb", "lib/capistrano/recipes/deploy/scm/accurev.rb", "lib/capistrano/recipes/deploy/scm/base.rb", "lib/capistrano/recipes/deploy/scm/bzr.rb", "lib/capistrano/recipes/deploy/scm/cvs.rb", "lib/capistrano/recipes/deploy/scm/darcs.rb", "lib/capistrano/recipes/deploy/scm/git.rb", "lib/capistrano/recipes/deploy/scm/mercurial.rb", "lib/capistrano/recipes/deploy/scm/none.rb", "lib/capistrano/recipes/deploy/scm/perforce.rb", "lib/capistrano/recipes/deploy/scm/subversion.rb", "lib/capistrano/recipes/deploy/scm.rb", "lib/capistrano/recipes/deploy/strategy/base.rb", "lib/capistrano/recipes/deploy/strategy/checkout.rb", "lib/capistrano/recipes/deploy/strategy/copy.rb", "lib/capistrano/recipes/deploy/strategy/export.rb", "lib/capistrano/recipes/deploy/strategy/remote.rb", "lib/capistrano/recipes/deploy/strategy/remote_cache.rb", "lib/capistrano/recipes/deploy/strategy.rb", "lib/capistrano/recipes/deploy/templates/maintenance.rhtml", "lib/capistrano/recipes/deploy.rb", "lib/capistrano/recipes/standard.rb", "lib/capistrano/recipes/templates/maintenance.rhtml", "lib/capistrano/recipes/upgrade.rb", "lib/capistrano/role.rb", "lib/capistrano/server_definition.rb", "lib/capistrano/shell.rb", "lib/capistrano/ssh.rb", "lib/capistrano/task_definition.rb", "lib/capistrano/transfer.rb", "lib/capistrano/version.rb", "lib/capistrano.rb", "README.rdoc"]
12
- s.files = ["bin/cap", "bin/capify", "CHANGELOG.rdoc", "examples/sample.rb", "lib/capistrano/callback.rb", "lib/capistrano/cli/execute.rb", "lib/capistrano/cli/help.rb", "lib/capistrano/cli/help.txt", "lib/capistrano/cli/options.rb", "lib/capistrano/cli/ui.rb", "lib/capistrano/cli.rb", "lib/capistrano/command.rb", "lib/capistrano/configuration/actions/file_transfer.rb", "lib/capistrano/configuration/actions/inspect.rb", "lib/capistrano/configuration/actions/invocation.rb", "lib/capistrano/configuration/callbacks.rb", "lib/capistrano/configuration/connections.rb", "lib/capistrano/configuration/execution.rb", "lib/capistrano/configuration/loading.rb", "lib/capistrano/configuration/namespaces.rb", "lib/capistrano/configuration/roles.rb", "lib/capistrano/configuration/servers.rb", "lib/capistrano/configuration/variables.rb", "lib/capistrano/configuration.rb", "lib/capistrano/errors.rb", "lib/capistrano/extensions.rb", "lib/capistrano/logger.rb", "lib/capistrano/processable.rb", "lib/capistrano/recipes/compat.rb", "lib/capistrano/recipes/deploy/dependencies.rb", "lib/capistrano/recipes/deploy/local_dependency.rb", "lib/capistrano/recipes/deploy/remote_dependency.rb", "lib/capistrano/recipes/deploy/scm/accurev.rb", "lib/capistrano/recipes/deploy/scm/base.rb", "lib/capistrano/recipes/deploy/scm/bzr.rb", "lib/capistrano/recipes/deploy/scm/cvs.rb", "lib/capistrano/recipes/deploy/scm/darcs.rb", "lib/capistrano/recipes/deploy/scm/git.rb", "lib/capistrano/recipes/deploy/scm/mercurial.rb", "lib/capistrano/recipes/deploy/scm/none.rb", "lib/capistrano/recipes/deploy/scm/perforce.rb", "lib/capistrano/recipes/deploy/scm/subversion.rb", "lib/capistrano/recipes/deploy/scm.rb", "lib/capistrano/recipes/deploy/strategy/base.rb", "lib/capistrano/recipes/deploy/strategy/checkout.rb", "lib/capistrano/recipes/deploy/strategy/copy.rb", "lib/capistrano/recipes/deploy/strategy/export.rb", "lib/capistrano/recipes/deploy/strategy/remote.rb", "lib/capistrano/recipes/deploy/strategy/remote_cache.rb", "lib/capistrano/recipes/deploy/strategy.rb", "lib/capistrano/recipes/deploy/templates/maintenance.rhtml", "lib/capistrano/recipes/deploy.rb", "lib/capistrano/recipes/standard.rb", "lib/capistrano/recipes/templates/maintenance.rhtml", "lib/capistrano/recipes/upgrade.rb", "lib/capistrano/role.rb", "lib/capistrano/server_definition.rb", "lib/capistrano/shell.rb", "lib/capistrano/ssh.rb", "lib/capistrano/task_definition.rb", "lib/capistrano/transfer.rb", "lib/capistrano/version.rb", "lib/capistrano.rb", "Rakefile", "README.rdoc", "setup.rb", "test/cli/execute_test.rb", "test/cli/help_test.rb", "test/cli/options_test.rb", "test/cli/ui_test.rb", "test/cli_test.rb", "test/command_test.rb", "test/configuration/actions/file_transfer_test.rb", "test/configuration/actions/inspect_test.rb", "test/configuration/actions/invocation_test.rb", "test/configuration/callbacks_test.rb", "test/configuration/connections_test.rb", "test/configuration/execution_test.rb", "test/configuration/loading_test.rb", "test/configuration/namespace_dsl_test.rb", "test/configuration/roles_test.rb", "test/configuration/servers_test.rb", "test/configuration/variables_test.rb", "test/configuration_test.rb", "test/deploy/local_dependency_test.rb", "test/deploy/remote_dependency_test.rb", "test/deploy/scm/accurev_test.rb", "test/deploy/scm/base_test.rb", "test/deploy/scm/git_test.rb", "test/deploy/scm/mercurial_test.rb", "test/deploy/strategy/copy_test.rb", "test/extensions_test.rb", "test/fixtures/cli_integration.rb", "test/fixtures/config.rb", "test/fixtures/custom.rb", "test/logger_test.rb", "test/role_test.rb", "test/server_definition_test.rb", "test/shell_test.rb", "test/ssh_test.rb", "test/task_definition_test.rb", "test/transfer_test.rb", "test/utils.rb", "Manifest", "capistrano.gemspec", "test/deploy/scm/none_test.rb"]
11
+ s.files = ["bin/cap", "bin/capify", "CHANGELOG.rdoc", "examples/sample.rb", "lib/capistrano/callback.rb", "lib/capistrano/cli/execute.rb", "lib/capistrano/cli/help.rb", "lib/capistrano/cli/help.txt", "lib/capistrano/cli/options.rb", "lib/capistrano/cli/ui.rb", "lib/capistrano/cli.rb", "lib/capistrano/command.rb", "lib/capistrano/configuration/actions/file_transfer.rb", "lib/capistrano/configuration/actions/inspect.rb", "lib/capistrano/configuration/actions/invocation.rb", "lib/capistrano/configuration/callbacks.rb", "lib/capistrano/configuration/connections.rb", "lib/capistrano/configuration/execution.rb", "lib/capistrano/configuration/loading.rb", "lib/capistrano/configuration/namespaces.rb", "lib/capistrano/configuration/roles.rb", "lib/capistrano/configuration/servers.rb", "lib/capistrano/configuration/variables.rb", "lib/capistrano/configuration.rb", "lib/capistrano/errors.rb",
12
+ "lib/capistrano/extensions.rb", "lib/capistrano/logger.rb", "lib/capistrano/processable.rb", "lib/capistrano/recipes/compat.rb", "lib/capistrano/recipes/deploy/dependencies.rb", "lib/capistrano/recipes/deploy/local_dependency.rb", "lib/capistrano/recipes/deploy/remote_dependency.rb", "lib/capistrano/recipes/deploy/scm/accurev.rb", "lib/capistrano/recipes/deploy/scm/base.rb", "lib/capistrano/recipes/deploy/scm/bzr.rb", "lib/capistrano/recipes/deploy/scm/cvs.rb", "lib/capistrano/recipes/deploy/scm/darcs.rb", "lib/capistrano/recipes/deploy/scm/git.rb", "lib/capistrano/recipes/deploy/scm/mercurial.rb", "lib/capistrano/recipes/deploy/scm/none.rb", "lib/capistrano/recipes/deploy/scm/perforce.rb", "lib/capistrano/recipes/deploy/scm/subversion.rb", "lib/capistrano/recipes/deploy/scm.rb", "lib/capistrano/recipes/deploy/strategy/base.rb", "lib/capistrano/recipes/deploy/strategy/checkout.rb", "lib/capistrano/recipes/deploy/strategy/copy.rb", "lib/capistrano/recipes/deploy/strategy/export.rb", "lib/capistrano/recipes/deploy/strategy/remote.rb", "lib/capistrano/recipes/deploy/strategy/remote_cache.rb", "lib/capistrano/recipes/deploy/strategy.rb", "lib/capistrano/recipes/deploy/templates/maintenance.rhtml", "lib/capistrano/recipes/deploy.rb",
13
+ "lib/capistrano/recipes/ext/rails-shared-directories.rb",
14
+ "lib/capistrano/recipes/ext/rails-database-migrations.rb", "lib/capistrano/recipes/ext/web-disable-enable.rb", "lib/capistrano/recipes/standard.rb", "lib/capistrano/recipes/templates/maintenance.rhtml", "lib/capistrano/recipes/upgrade.rb", "lib/capistrano/role.rb", "lib/capistrano/server_definition.rb", "lib/capistrano/shell.rb", "lib/capistrano/ssh.rb", "lib/capistrano/task_definition.rb", "lib/capistrano/transfer.rb", "lib/capistrano/version.rb", "lib/capistrano.rb", "Rakefile", "README.rdoc", "setup.rb", "test/cli/execute_test.rb", "test/cli/help_test.rb", "test/cli/options_test.rb", "test/cli/ui_test.rb", "test/cli_test.rb", "test/command_test.rb", "test/configuration/actions/file_transfer_test.rb", "test/configuration/actions/inspect_test.rb", "test/configuration/actions/invocation_test.rb", "test/configuration/callbacks_test.rb", "test/configuration/connections_test.rb", "test/configuration/execution_test.rb", "test/configuration/loading_test.rb", "test/configuration/namespace_dsl_test.rb", "test/configuration/roles_test.rb", "test/configuration/servers_test.rb", "test/configuration/variables_test.rb", "test/configuration_test.rb", "test/deploy/local_dependency_test.rb", "test/deploy/remote_dependency_test.rb", "test/deploy/scm/accurev_test.rb", "test/deploy/scm/base_test.rb", "test/deploy/scm/git_test.rb", "test/deploy/scm/mercurial_test.rb", "test/deploy/strategy/copy_test.rb", "test/extensions_test.rb", "test/fixtures/cli_integration.rb", "test/fixtures/config.rb", "test/fixtures/custom.rb", "test/logger_test.rb", "test/role_test.rb", "test/server_definition_test.rb", "test/shell_test.rb", "test/ssh_test.rb", "test/task_definition_test.rb", "test/transfer_test.rb", "test/utils.rb", "Manifest", "capistrano.gemspec", "test/deploy/scm/none_test.rb"]
13
15
  s.has_rdoc = true
14
16
  s.homepage = %q{http://www.capify.org}
15
17
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Capistrano", "--main", "README.rdoc"]
16
18
  s.require_paths = ["lib"]
17
19
  s.rubyforge_project = %q{capistrano}
18
20
  s.rubygems_version = %q{1.2.0}
19
- s.summary = %q{Capistrano is a utility and framework for executing commands in parallel on multiple remote machines, via SSH.}
21
+ s.summary = %q{Simple. The way it should be.}
20
22
  s.test_files = ["test/cli/execute_test.rb", "test/cli/help_test.rb", "test/cli/options_test.rb", "test/cli/ui_test.rb", "test/cli_test.rb", "test/command_test.rb", "test/configuration/actions/file_transfer_test.rb", "test/configuration/actions/inspect_test.rb", "test/configuration/actions/invocation_test.rb", "test/configuration/callbacks_test.rb", "test/configuration/connections_test.rb", "test/configuration/execution_test.rb", "test/configuration/loading_test.rb", "test/configuration/namespace_dsl_test.rb", "test/configuration/roles_test.rb", "test/configuration/servers_test.rb", "test/configuration/variables_test.rb", "test/configuration_test.rb", "test/deploy/local_dependency_test.rb", "test/deploy/remote_dependency_test.rb", "test/deploy/scm/accurev_test.rb", "test/deploy/scm/base_test.rb", "test/deploy/scm/git_test.rb", "test/deploy/scm/mercurial_test.rb", "test/deploy/scm/none_test.rb", "test/deploy/strategy/copy_test.rb", "test/extensions_test.rb", "test/logger_test.rb", "test/role_test.rb", "test/server_definition_test.rb", "test/shell_test.rb", "test/ssh_test.rb", "test/task_definition_test.rb", "test/transfer_test.rb"]
21
23
 
22
24
  if s.respond_to? :specification_version then
@@ -24,6 +24,7 @@ module Capistrano
24
24
  # line switches for Capistrano, and what their corresponding behaviors
25
25
  # are.
26
26
  def option_parser #:nodoc:
27
+ @logger = Logger.new
27
28
  @option_parser ||= OptionParser.new do |opts|
28
29
  opts.banner = "Usage: #{File.basename($0)} [options] action ..."
29
30
 
@@ -167,6 +168,7 @@ module Capistrano
167
168
  %w(Capfile capfile).each do |file|
168
169
  if File.file?(file)
169
170
  options[:recipes] << file
171
+ @logger.info "Using recipes from #{File.join(current,file)}"
170
172
  return
171
173
  end
172
174
  end
@@ -209,8 +209,8 @@ module Capistrano
209
209
  shell = nil
210
210
  else
211
211
  shell = "#{options[:shell] || "sh"} -c"
212
- cmd = cmd.gsub(/[$\\`"]/) { |m| "\\#{m}" }
213
- cmd = "\"#{cmd}\""
212
+ cmd = cmd.gsub(/'/) { |m| "'\\''" }
213
+ cmd = "'#{cmd}'"
214
214
  end
215
215
 
216
216
  command_line = [environment, shell, cmd].compact.join(" ")
@@ -51,24 +51,26 @@ module Capistrano
51
51
  # A hash of the SSH sessions that are currently open and available.
52
52
  # Because sessions are constructed lazily, this will only contain
53
53
  # connections to those servers that have been the targets of one or more
54
- # executed tasks.
55
- attr_reader :sessions
54
+ # executed tasks. Stored on a per-thread basis to improve thread-safety.
55
+ def sessions
56
+ Thread.current[:sessions] ||= {}
57
+ end
56
58
 
57
59
  def initialize_with_connections(*args) #:nodoc:
58
60
  initialize_without_connections(*args)
59
- @sessions = {}
60
- @failed_sessions = []
61
+ Thread.current[:sessions] = {}
62
+ Thread.current[:failed_sessions] = []
61
63
  end
62
64
 
63
65
  # Indicate that the given server could not be connected to.
64
66
  def failed!(server)
65
- @failed_sessions << server
67
+ Thread.current[:failed_sessions] << server
66
68
  end
67
69
 
68
70
  # Query whether previous connection attempts to the given server have
69
71
  # failed.
70
72
  def has_failed?(server)
71
- @failed_sessions.include?(server)
73
+ Thread.current[:failed_sessions].include?(server)
72
74
  end
73
75
 
74
76
  # Used to force connections to be made to the current task's servers.
@@ -116,9 +118,9 @@ module Capistrano
116
118
  # Destroys sessions for each server in the list.
117
119
  def teardown_connections_to(servers)
118
120
  servers.each do |server|
119
- @sessions[server].close
120
- @sessions.delete(server)
121
- end
121
+ sessions[server].close
122
+ sessions.delete(server)
123
+ end
122
124
  end
123
125
 
124
126
  # Determines the set of servers within the current task's scope and
@@ -186,11 +188,13 @@ module Capistrano
186
188
  # prevents problems with the thread's scope seeing the wrong 'server'
187
189
  # variable if the thread just happens to take too long to start up.
188
190
  def establish_connection_to(server, failures=nil)
189
- Thread.new { safely_establish_connection_to(server, failures) }
191
+ current_thread = Thread.current
192
+ Thread.new { safely_establish_connection_to(server, current_thread, failures) }
190
193
  end
191
194
 
192
- def safely_establish_connection_to(server, failures=nil)
193
- sessions[server] ||= connection_factory.connect_to(server)
195
+ def safely_establish_connection_to(server, thread, failures=nil)
196
+ thread[:sessions] ||= {}
197
+ thread[:sessions][server] ||= connection_factory.connect_to(server)
194
198
  rescue Exception => err
195
199
  raise unless failures
196
200
  failures << { :server => server, :error => err }
@@ -8,22 +8,11 @@ module Capistrano
8
8
  base.send :alias_method, :initialize, :initialize_with_execution
9
9
  end
10
10
 
11
- # The call stack of the tasks. The currently executing task may inspect
12
- # this to see who its caller was. The current task is always the last
13
- # element of this stack.
14
- attr_reader :task_call_frames
15
-
16
- # The stack of tasks that have registered rollback handlers within the
17
- # current transaction. If this is nil, then there is no transaction
18
- # that is currently active.
19
- attr_reader :rollback_requests
20
-
21
11
  # A struct for representing a single instance of an invoked task.
22
12
  TaskCallFrame = Struct.new(:task, :rollback)
23
13
 
24
14
  def initialize_with_execution(*args) #:nodoc:
25
15
  initialize_without_execution(*args)
26
- @task_call_frames = []
27
16
  end
28
17
  private :initialize_with_execution
29
18
 
@@ -32,6 +21,25 @@ module Capistrano
32
21
  !rollback_requests.nil?
33
22
  end
34
23
 
24
+ # The call stack of the tasks. The currently executing task may inspect
25
+ # this to see who its caller was. The current task is always the last
26
+ # element of this stack.
27
+ def task_call_frames
28
+ Thread.current[:task_call_frames] ||= []
29
+ end
30
+
31
+
32
+ # The stack of tasks that have registered rollback handlers within the
33
+ # current transaction. If this is nil, then there is no transaction
34
+ # that is currently active.
35
+ def rollback_requests
36
+ Thread.current[:rollback_requests]
37
+ end
38
+
39
+ def rollback_requests=(rollback_requests)
40
+ Thread.current[:rollback_requests] = rollback_requests
41
+ end
42
+
35
43
  # Invoke a set of tasks in a transaction. If any task fails (raises an
36
44
  # exception), all tasks executed within the transaction are inspected to
37
45
  # see if they have an associated on_rollback hook, and if so, that hook
@@ -44,14 +52,14 @@ module Capistrano
44
52
 
45
53
  logger.info "transaction: start"
46
54
  begin
47
- @rollback_requests = []
55
+ self.rollback_requests = []
48
56
  yield
49
57
  logger.info "transaction: commit"
50
58
  rescue Object => e
51
59
  rollback!
52
60
  raise
53
61
  ensure
54
- @rollback_requests = nil
62
+ self.rollback_requests = nil if Thread.main == Thread.current
55
63
  end
56
64
  end
57
65
 
@@ -99,6 +107,9 @@ module Capistrano
99
107
  protected
100
108
 
101
109
  def rollback!
110
+ return if Thread.current[:rollback_requests].nil?
111
+ Thread.current[:rolled_back] = true
112
+
102
113
  # throw the task back on the stack so that roles are properly
103
114
  # interpreted in the scope of the task in question.
104
115
  rollback_requests.reverse.each do |frame|
@@ -151,9 +151,18 @@ namespace :deploy do
151
151
  DESC
152
152
  task :default do
153
153
  update
154
- restart
154
+ # restart
155
155
  end
156
156
 
157
+ [:start, :stop, :restart].each do |deprecated_task|
158
+ desc "#{deprecated_task.to_s} is deprecated. Please see "
159
+ task deprecated_task do
160
+
161
+ end
162
+ end
163
+
164
+
165
+
157
166
  desc <<-DESC
158
167
  Prepares one or more servers for deployment. Before you can use any \
159
168
  of the Capistrano deployment tasks with your project, you will need to \
@@ -222,23 +231,6 @@ namespace :deploy do
222
231
  DESC
223
232
  task :finalize_update, :except => { :no_release => true } do
224
233
  run "chmod -R g+w #{latest_release}" if fetch(:group_writable, true)
225
-
226
- # mkdir -p is making sure that the directories are there for some SCM's that don't
227
- # save empty folders
228
- run <<-CMD
229
- rm -rf #{latest_release}/log #{latest_release}/public/system #{latest_release}/tmp/pids &&
230
- mkdir -p #{latest_release}/public &&
231
- mkdir -p #{latest_release}/tmp &&
232
- ln -s #{shared_path}/log #{latest_release}/log &&
233
- ln -s #{shared_path}/system #{latest_release}/public/system &&
234
- ln -s #{shared_path}/pids #{latest_release}/tmp/pids
235
- CMD
236
-
237
- if fetch(:normalize_asset_timestamps, true)
238
- stamp = Time.now.utc.strftime("%Y%m%d%H%M.%S")
239
- asset_paths = %w(images stylesheets javascripts).map { |p| "#{latest_release}/public/#{p}" }.join(" ")
240
- run "find #{asset_paths} -exec touch -t #{stamp} {} ';'; true", :env => { "TZ" => "UTC" }
241
- end
242
234
  end
243
235
 
244
236
  desc <<-DESC
@@ -287,21 +279,6 @@ namespace :deploy do
287
279
  files.each { |file| top.upload(file, File.join(current_path, file)) }
288
280
  end
289
281
 
290
- desc <<-DESC
291
- Restarts your application. This works by calling the script/process/reaper \
292
- script under the current path.
293
-
294
- By default, this will be invoked via sudo as the `app' user. If \
295
- you wish to run it as a different user, set the :runner variable to \
296
- that user. If you are in an environment where you can't use sudo, set \
297
- the :use_sudo variable to false:
298
-
299
- set :use_sudo, false
300
- DESC
301
- task :restart, :roles => :app, :except => { :no_release => true } do
302
- try_runner "#{current_path}/script/process/reaper"
303
- end
304
-
305
282
  namespace :rollback do
306
283
  desc <<-DESC
307
284
  [internal] Points the current symlink at the previous revision.
@@ -328,8 +305,7 @@ namespace :deploy do
328
305
  desc <<-DESC
329
306
  Rolls back to the previously deployed version. The `current' symlink will \
330
307
  be updated to point at the previously deployed version, and then the \
331
- current release will be removed from the servers. You'll generally want \
332
- to call `rollback' instead, as it performs a `restart' as well.
308
+ current release will be removed from the servers.
333
309
  DESC
334
310
  task :code, :except => { :no_release => true } do
335
311
  revision
@@ -343,56 +319,10 @@ namespace :deploy do
343
319
  DESC
344
320
  task :default do
345
321
  revision
346
- restart
347
322
  cleanup
348
323
  end
349
324
  end
350
325
 
351
- desc <<-DESC
352
- Run the migrate rake task. By default, it runs this in most recently \
353
- deployed version of the app. However, you can specify a different release \
354
- via the migrate_target variable, which must be one of :latest (for the \
355
- default behavior), or :current (for the release indicated by the \
356
- `current' symlink). Strings will work for those values instead of symbols, \
357
- too. You can also specify additional environment variables to pass to rake \
358
- via the migrate_env variable. Finally, you can specify the full path to the \
359
- rake executable by setting the rake variable. The defaults are:
360
-
361
- set :rake, "rake"
362
- set :rails_env, "production"
363
- set :migrate_env, ""
364
- set :migrate_target, :latest
365
- DESC
366
- task :migrate, :roles => :db, :only => { :primary => true } do
367
- rake = fetch(:rake, "rake")
368
- rails_env = fetch(:rails_env, "production")
369
- migrate_env = fetch(:migrate_env, "")
370
- migrate_target = fetch(:migrate_target, :latest)
371
-
372
- directory = case migrate_target.to_sym
373
- when :current then current_path
374
- when :latest then current_release
375
- else raise ArgumentError, "unknown migration target #{migrate_target.inspect}"
376
- end
377
-
378
- run "cd #{directory}; #{rake} RAILS_ENV=#{rails_env} #{migrate_env} db:migrate"
379
- end
380
-
381
- desc <<-DESC
382
- Deploy and run pending migrations. This will work similarly to the \
383
- `deploy' task, but will also run any pending migrations (via the \
384
- `deploy:migrate' task) prior to updating the symlink. Note that the \
385
- update in this case it is not atomic, and transactions are not used, \
386
- because migrations are not guaranteed to be reversible.
387
- DESC
388
- task :migrations do
389
- set :migrate_target, :latest
390
- update_code
391
- migrate
392
- symlink
393
- restart
394
- end
395
-
396
326
  desc <<-DESC
397
327
  Clean up old releases. By default, the last 5 releases are kept on each \
398
328
  server (though you can change this with the keep_releases variable). All \
@@ -462,40 +392,6 @@ namespace :deploy do
462
392
  DESC
463
393
  task :cold do
464
394
  update
465
- migrate
466
- start
467
- end
468
-
469
- desc <<-DESC
470
- Start the application servers. This will attempt to invoke a script \
471
- in your application called `script/spin', which must know how to start \
472
- your application listeners. For Rails applications, you might just have \
473
- that script invoke `script/process/spawner' with the appropriate \
474
- arguments.
475
-
476
- By default, the script will be executed via sudo as the `app' user. If \
477
- you wish to run it as a different user, set the :runner variable to \
478
- that user. If you are in an environment where you can't use sudo, set \
479
- the :use_sudo variable to false.
480
- DESC
481
- task :start, :roles => :app do
482
- run "cd #{current_path} && #{try_runner} nohup script/spin"
483
- end
484
-
485
- desc <<-DESC
486
- Stop the application servers. This will call script/process/reaper for \
487
- both the spawner process, and all of the application processes it has \
488
- spawned. As such, it is fairly Rails specific and may need to be \
489
- overridden for other systems.
490
-
491
- By default, the script will be executed via sudo as the `app' user. If \
492
- you wish to run it as a different user, set the :runner variable to \
493
- that user. If you are in an environment where you can't use sudo, set \
494
- the :use_sudo variable to false.
495
- DESC
496
- task :stop, :roles => :app do
497
- run "if [ -f #{current_path}/tmp/pids/dispatch.spawner.pid ]; then #{try_runner} #{current_path}/script/process/reaper -a kill -r dispatch.spawner.pid; fi"
498
- try_runner "#{current_path}/script/process/reaper -a kill"
499
395
  end
500
396
 
501
397
  namespace :pending do
@@ -519,44 +415,4 @@ namespace :deploy do
519
415
  end
520
416
  end
521
417
 
522
- namespace :web do
523
- desc <<-DESC
524
- Present a maintenance page to visitors. Disables your application's web \
525
- interface by writing a "maintenance.html" file to each web server. The \
526
- servers must be configured to detect the presence of this file, and if \
527
- it is present, always display it instead of performing the request.
528
-
529
- By default, the maintenance page will just say the site is down for \
530
- "maintenance", and will be back "shortly", but you can customize the \
531
- page by specifying the REASON and UNTIL environment variables:
532
-
533
- $ cap deploy:web:disable \\
534
- REASON="hardware upgrade" \\
535
- UNTIL="12pm Central Time"
536
-
537
- Further customization will require that you write your own task.
538
- DESC
539
- task :disable, :roles => :web, :except => { :no_release => true } do
540
- require 'erb'
541
- on_rollback { run "rm #{shared_path}/system/maintenance.html" }
542
-
543
- reason = ENV['REASON']
544
- deadline = ENV['UNTIL']
545
-
546
- template = File.read(File.join(File.dirname(__FILE__), "templates", "maintenance.rhtml"))
547
- result = ERB.new(template).result(binding)
548
-
549
- put result, "#{shared_path}/system/maintenance.html", :mode => 0644
550
- end
551
-
552
- desc <<-DESC
553
- Makes the application web-accessible again. Removes the \
554
- "maintenance.html" page generated by deploy:web:disable, which (if your \
555
- web servers are configured correctly) will make your application \
556
- web-accessible again.
557
- DESC
558
- task :enable, :roles => :web, :except => { :no_release => true } do
559
- run "rm #{shared_path}/system/maintenance.html"
560
- end
561
- end
562
418
  end
@@ -151,6 +151,7 @@ module Capistrano
151
151
 
152
152
  if configuration[:git_enable_submodules]
153
153
  execute << "#{git} submodule #{verbose} init"
154
+ execute << "#{git} submodule #{verbose} sync"
154
155
  execute << "#{git} submodule #{verbose} update"
155
156
  end
156
157
 
@@ -188,9 +189,15 @@ module Capistrano
188
189
 
189
190
  if configuration[:git_enable_submodules]
190
191
  execute << "#{git} submodule #{verbose} init"
192
+ execute << "for mod in `#{git} submodule status | awk '{ print $2 }'`; do #{git} config -f .git/config submodule.${mod}.url `#{git} config -f .gitmodules --get submodule.${mod}.url` && echo Synced $mod; done"
193
+ execute << "#{git} submodule #{verbose} sync"
191
194
  execute << "#{git} submodule #{verbose} update"
192
195
  end
193
196
 
197
+ # Make sure there's nothing else lying around in the repository (for
198
+ # example, a submodule that has subsequently been removed).
199
+ execute << "#{git} clean #{verbose} -d -x -f"
200
+
194
201
  execute.join(" && ")
195
202
  end
196
203
 
@@ -18,7 +18,7 @@ module Capistrano
18
18
  # For mercurial HEAD == tip except that it bases this assumption on what
19
19
  # tip is in the current repository (so push before you deploy)
20
20
  def head
21
- "tip"
21
+ configuration[:branch] || "tip"
22
22
  end
23
23
 
24
24
  # Clone the repository and update to the specified changeset.
@@ -134,4 +134,4 @@ module Capistrano
134
134
  end
135
135
  end
136
136
  end
137
- end
137
+ end
@@ -49,7 +49,7 @@ module Capistrano
49
49
 
50
50
  # Returns a "p4 changes" command for the two revisions.
51
51
  def log(from=1, to=head)
52
- scm authentication, :changes, "-s submitted", "//#{p4client}/...#{rev_no(from)},#(rev_no(to)}"
52
+ scm authentication, :changes, "-s submitted", "//#{p4client}/...#{rev_no(from)},#{rev_no(to)}"
53
53
  end
54
54
 
55
55
  def query_revision(revision)
@@ -58,6 +58,11 @@ module Capistrano
58
58
  yield(command)[/Change (\d+) on/, 1]
59
59
  end
60
60
 
61
+ # Increments the given revision number and returns it.
62
+ def next_revision(revision)
63
+ revision.to_i + 1
64
+ end
65
+
61
66
  # Determines what the response should be for a particular bit of text
62
67
  # from the SCM. Password prompts, connection requests, passphrases,
63
68
  # etc. are handled here.
@@ -0,0 +1,50 @@
1
+ namespace :deploy do
2
+
3
+ desc <<-DESC
4
+ Run the migrate rake task. By default, it runs this in most recently \
5
+ deployed version of the app. However, you can specify a different release \
6
+ via the migrate_target variable, which must be one of :latest (for the \
7
+ default behavior), or :current (for the release indicated by the \
8
+ `current' symlink). Strings will work for those values instead of symbols, \
9
+ too. You can also specify additional environment variables to pass to rake \
10
+ via the migrate_env variable. Finally, you can specify the full path to the \
11
+ rake executable by setting the rake variable. The defaults are:
12
+
13
+ set :rake, "rake"
14
+ set :rails_env, "production"
15
+ set :migrate_env, ""
16
+ set :migrate_target, :latest
17
+ DESC
18
+ task :migrate, :roles => :db, :only => { :primary => true } do
19
+ rake = fetch(:rake, "rake")
20
+ rails_env = fetch(:rails_env, "production")
21
+ migrate_env = fetch(:migrate_env, "")
22
+ migrate_target = fetch(:migrate_target, :latest)
23
+
24
+ directory = case migrate_target.to_sym
25
+ when :current then current_path
26
+ when :latest then current_release
27
+ else raise ArgumentError, "unknown migration target #{migrate_target.inspect}"
28
+ end
29
+
30
+ run "cd #{directory}; #{rake} RAILS_ENV=#{rails_env} #{migrate_env} db:migrate"
31
+ end
32
+
33
+ desc <<-DESC
34
+ Deploy and run pending migrations. This will work similarly to the \
35
+ `deploy' task, but will also run any pending migrations (via the \
36
+ `deploy:migrate' task) prior to updating the symlink. Note that the \
37
+ update in this case it is not atomic, and transactions are not used, \
38
+ because migrations are not guaranteed to be reversible.
39
+ DESC
40
+ task :migrations do
41
+ set :migrate_target, :latest
42
+ update_code
43
+ migrate
44
+ symlink
45
+ restart
46
+ end
47
+
48
+ end
49
+
50
+ after('deploy:update_code', 'deploy:migrate')
@@ -0,0 +1,21 @@
1
+ _cset :shared_children, %w(system log pids)
2
+
3
+ after 'deploy:finalize_update' do
4
+ # mkdir -p is making sure that the directories are there for some SCM's that don't
5
+ # save empty folders
6
+ run <<-CMD
7
+ rm -rf #{latest_release}/log #{latest_release}/public/system #{latest_release}/tmp/pids &&
8
+ mkdir -p #{latest_release}/public &&
9
+ mkdir -p #{latest_release}/tmp &&
10
+ ln -s #{shared_path}/log #{latest_release}/log &&
11
+ ln -s #{shared_path}/system #{latest_release}/public/system &&
12
+ ln -s #{shared_path}/pids #{latest_release}/tmp/pids
13
+ CMD
14
+
15
+ if fetch(:normalize_asset_timestamps, true)
16
+ stamp = Time.now.utc.strftime("%Y%m%d%H%M.%S")
17
+ asset_paths = %w(images stylesheets javascripts).map { |p| "#{latest_release}/public/#{p}" }.join(" ")
18
+ run "find #{asset_paths} -exec touch -t #{stamp} {} ';'; true", :env => { "TZ" => "UTC" }
19
+ end
20
+
21
+ end
@@ -0,0 +1,40 @@
1
+ namespace :web do
2
+ desc <<-DESC
3
+ Present a maintenance page to visitors. Disables your application's web \
4
+ interface by writing a "maintenance.html" file to each web server. The \
5
+ servers must be configured to detect the presence of this file, and if \
6
+ it is present, always display it instead of performing the request.
7
+
8
+ By default, the maintenance page will just say the site is down for \
9
+ "maintenance", and will be back "shortly", but you can customize the \
10
+ page by specifying the REASON and UNTIL environment variables:
11
+
12
+ $ cap deploy:web:disable \\
13
+ REASON="hardware upgrade" \\
14
+ UNTIL="12pm Central Time"
15
+
16
+ Further customization will require that you write your own task.
17
+ DESC
18
+ task :disable, :roles => :web, :except => { :no_release => true } do
19
+ require 'erb'
20
+ on_rollback { run "rm #{shared_path}/system/maintenance.html" }
21
+
22
+ reason = ENV['REASON']
23
+ deadline = ENV['UNTIL']
24
+
25
+ template = File.read(File.join(File.dirname(__FILE__), "templates", "maintenance.rhtml"))
26
+ result = ERB.new(template).result(binding)
27
+
28
+ put result, "#{shared_path}/system/maintenance.html", :mode => 0644
29
+ end
30
+
31
+ desc <<-DESC
32
+ Makes the application web-accessible again. Removes the \
33
+ "maintenance.html" page generated by deploy:web:disable, which (if your \
34
+ web servers are configured correctly) will make your application \
35
+ web-accessible again.
36
+ DESC
37
+ task :enable, :roles => :web, :except => { :no_release => true } do
38
+ run "rm #{shared_path}/system/maintenance.html"
39
+ end
40
+ end
@@ -6,7 +6,7 @@ module Capistrano
6
6
  class Version < Net::SSH::Version
7
7
  MAJOR = 2
8
8
  MINOR = 5
9
- TINY = 5
9
+ TINY = 6
10
10
 
11
11
  # The current version, as a Version instance
12
12
  CURRENT = new(MAJOR, MINOR, TINY)
@@ -20,7 +20,7 @@ class CommandTest < Test::Unit::TestCase
20
20
 
21
21
  def test_command_with_pty_should_request_pty_and_register_success_callback
22
22
  session = setup_for_extracting_channel_action(:request_pty, true) do |ch|
23
- ch.expects(:exec).with(%(sh -c "ls"))
23
+ ch.expects(:exec).with(%(sh -c 'ls'))
24
24
  end
25
25
  Capistrano::Command.new("ls", [session], :pty => true)
26
26
  end
@@ -28,35 +28,35 @@ class CommandTest < Test::Unit::TestCase
28
28
  def test_command_with_env_key_should_have_environment_constructed_and_prepended
29
29
  session = setup_for_extracting_channel_action do |ch|
30
30
  ch.expects(:request_pty).never
31
- ch.expects(:exec).with(%(env FOO=bar sh -c "ls"))
31
+ ch.expects(:exec).with(%(env FOO=bar sh -c 'ls'))
32
32
  end
33
33
  Capistrano::Command.new("ls", [session], :env => { "FOO" => "bar" })
34
34
  end
35
35
 
36
36
  def test_env_with_symbolic_key_should_be_accepted_as_a_string
37
37
  session = setup_for_extracting_channel_action do |ch|
38
- ch.expects(:exec).with(%(env FOO=bar sh -c "ls"))
38
+ ch.expects(:exec).with(%(env FOO=bar sh -c 'ls'))
39
39
  end
40
40
  Capistrano::Command.new("ls", [session], :env => { :FOO => "bar" })
41
41
  end
42
42
 
43
43
  def test_env_as_string_should_be_substituted_in_directly
44
44
  session = setup_for_extracting_channel_action do |ch|
45
- ch.expects(:exec).with(%(env HOWDY=there sh -c "ls"))
45
+ ch.expects(:exec).with(%(env HOWDY=there sh -c 'ls'))
46
46
  end
47
47
  Capistrano::Command.new("ls", [session], :env => "HOWDY=there")
48
48
  end
49
49
 
50
50
  def test_env_with_symbolic_value_should_be_accepted_as_string
51
51
  session = setup_for_extracting_channel_action do |ch|
52
- ch.expects(:exec).with(%(env FOO=bar sh -c "ls"))
52
+ ch.expects(:exec).with(%(env FOO=bar sh -c 'ls'))
53
53
  end
54
54
  Capistrano::Command.new("ls", [session], :env => { "FOO" => :bar })
55
55
  end
56
56
 
57
57
  def test_env_value_should_be_escaped
58
58
  session = setup_for_extracting_channel_action do |ch|
59
- ch.expects(:exec).with(%(env FOO=(\\ \\\"bar\\\"\\ ) sh -c "ls"))
59
+ ch.expects(:exec).with(%(env FOO=(\\ \\\"bar\\\"\\ ) sh -c 'ls'))
60
60
  end
61
61
  Capistrano::Command.new("ls", [session], :env => { "FOO" => '( "bar" )' })
62
62
  end
@@ -68,7 +68,7 @@ class CommandTest < Test::Unit::TestCase
68
68
  command =~ /\ba=b\b/ &&
69
69
  command =~ /\bc=d\b/ &&
70
70
  command =~ /\be=f\b/ &&
71
- command =~ / sh -c "ls"$/
71
+ command =~ / sh -c 'ls'$/
72
72
  end
73
73
  end
74
74
  Capistrano::Command.new("ls", [session], :env => { :a => :b, :c => :d, :e => :f })
@@ -90,14 +90,14 @@ class CommandTest < Test::Unit::TestCase
90
90
 
91
91
  def test_successful_channel_should_send_command
92
92
  session = setup_for_extracting_channel_action do |ch|
93
- ch.expects(:exec).with(%(sh -c "ls"))
93
+ ch.expects(:exec).with(%(sh -c 'ls'))
94
94
  end
95
95
  Capistrano::Command.new("ls", [session])
96
96
  end
97
97
 
98
98
  def test_successful_channel_with_shell_option_should_send_command_via_specified_shell
99
99
  session = setup_for_extracting_channel_action do |ch|
100
- ch.expects(:exec).with(%(/bin/bash -c "ls"))
100
+ ch.expects(:exec).with(%(/bin/bash -c 'ls'))
101
101
  end
102
102
  Capistrano::Command.new("ls", [session], :shell => "/bin/bash")
103
103
  end
@@ -111,7 +111,7 @@ class CommandTest < Test::Unit::TestCase
111
111
 
112
112
  def test_successful_channel_should_send_data_if_data_key_is_present
113
113
  session = setup_for_extracting_channel_action do |ch|
114
- ch.expects(:exec).with(%(sh -c "ls"))
114
+ ch.expects(:exec).with(%(sh -c 'ls'))
115
115
  ch.expects(:send_data).with("here we go")
116
116
  end
117
117
  Capistrano::Command.new("ls", [session], :data => "here we go")
@@ -225,14 +225,14 @@ class CommandTest < Test::Unit::TestCase
225
225
 
226
226
  def test_process_with_host_placeholder_should_substitute_placeholder_with_each_host
227
227
  session = setup_for_extracting_channel_action do |ch|
228
- ch.expects(:exec).with(%(sh -c "echo capistrano"))
228
+ ch.expects(:exec).with(%(sh -c 'echo capistrano'))
229
229
  end
230
230
  Capistrano::Command.new("echo $CAPISTRANO:HOST$", [session])
231
231
  end
232
232
 
233
233
  def test_process_with_unknown_placeholder_should_not_replace_placeholder
234
234
  session = setup_for_extracting_channel_action do |ch|
235
- ch.expects(:exec).with(%(sh -c "echo \\$CAPISTRANO:OTHER\\$"))
235
+ ch.expects(:exec).with(%(sh -c 'echo $CAPISTRANO:OTHER$'))
236
236
  end
237
237
  Capistrano::Command.new("echo $CAPISTRANO:OTHER$", [session])
238
238
  end
@@ -37,6 +37,10 @@ class DeploySCMGitTest < Test::Unit::TestCase
37
37
  git = "/opt/local/bin/git"
38
38
  @config[:scm_command] = git
39
39
  assert_equal "#{git} clone -q git@somehost.com:project.git /var/www && cd /var/www && #{git} checkout -q -b deploy #{rev}", @source.checkout(rev, dest)
40
+
41
+ # with submodules
42
+ @config[:git_enable_submodules] = true
43
+ assert_equal "#{git} clone -q git@somehost.com:project.git /var/www && cd /var/www && #{git} checkout -q -b deploy #{rev} && #{git} submodule -q init && #{git} submodule -q sync && #{git} submodule -q update", @source.checkout(rev, dest)
40
44
  end
41
45
 
42
46
  def test_checkout_with_verbose_should_not_use_q_switch
@@ -88,12 +92,16 @@ class DeploySCMGitTest < Test::Unit::TestCase
88
92
  def test_sync
89
93
  dest = "/var/www"
90
94
  rev = 'c2d9e79'
91
- assert_equal "cd #{dest} && git fetch -q origin && git reset -q --hard #{rev}", @source.sync(rev, dest)
95
+ assert_equal "cd #{dest} && git fetch -q origin && git reset -q --hard #{rev} && git clean -q -d -x -f", @source.sync(rev, dest)
92
96
 
93
97
  # With :scm_command
94
98
  git = "/opt/local/bin/git"
95
99
  @config[:scm_command] = git
96
- assert_equal "cd #{dest} && #{git} fetch -q origin && #{git} reset -q --hard #{rev}", @source.sync(rev, dest)
100
+ assert_equal "cd #{dest} && #{git} fetch -q origin && #{git} reset -q --hard #{rev} && #{git} clean -q -d -x -f", @source.sync(rev, dest)
101
+
102
+ # with submodules
103
+ @config[:git_enable_submodules] = true
104
+ assert_equal "cd #{dest} && #{git} fetch -q origin && #{git} reset -q --hard #{rev} && #{git} submodule -q init && for mod in `#{git} submodule status | awk '{ print $2 }'`; do #{git} config -f .git/config submodule.${mod}.url `#{git} config -f .gitmodules --get submodule.${mod}.url` && echo Synced $mod; done && #{git} submodule -q sync && #{git} submodule -q update && #{git} clean -q -d -x -f", @source.sync(rev, dest)
97
105
  end
98
106
 
99
107
  def test_sync_with_remote
@@ -105,7 +113,7 @@ class DeploySCMGitTest < Test::Unit::TestCase
105
113
  @config[:repository] = repository
106
114
  @config[:remote] = remote
107
115
 
108
- assert_equal "cd #{dest} && git config remote.#{remote}.url #{repository} && git config remote.#{remote}.fetch +refs/heads/*:refs/remotes/#{remote}/* && git fetch -q #{remote} && git reset -q --hard #{rev}", @source.sync(rev, dest)
116
+ assert_equal "cd #{dest} && git config remote.#{remote}.url #{repository} && git config remote.#{remote}.fetch +refs/heads/*:refs/remotes/#{remote}/* && git fetch -q #{remote} && git reset -q --hard #{rev} && git clean -q -d -x -f", @source.sync(rev, dest)
109
117
  end
110
118
 
111
119
  def test_shallow_clone
@@ -124,6 +132,15 @@ class DeploySCMGitTest < Test::Unit::TestCase
124
132
  assert_equal "git clone -q -o username git@somehost.com:project.git /var/www && cd /var/www && git checkout -q -b deploy #{rev}", @source.checkout(rev, dest)
125
133
  end
126
134
 
135
+ def test_remote_clone_with_submodules
136
+ @config[:repository] = "git@somehost.com:project.git"
137
+ @config[:remote] = "username"
138
+ @config[:git_enable_submodules] = true
139
+ dest = "/var/www"
140
+ rev = 'c2d9e79'
141
+ assert_equal "git clone -q -o username git@somehost.com:project.git /var/www && cd /var/www && git checkout -q -b deploy #{rev} && git submodule -q init && git submodule -q sync && git submodule -q update", @source.checkout(rev, dest)
142
+ end
143
+
127
144
  # Tests from base_test.rb, makin' sure we didn't break anything up there!
128
145
  def test_command_should_default_to_default_command
129
146
  assert_equal "git", @source.command
@@ -17,6 +17,11 @@ class DeploySCMMercurialTest < Test::Unit::TestCase
17
17
  assert_equal "tip", @source.head
18
18
  end
19
19
 
20
+ def test_different_head
21
+ @config[:branch] = "staging"
22
+ assert_equal "staging", @source.head
23
+ end
24
+
20
25
  def test_checkout
21
26
  @config[:repository] = "http://example.com/project-hg"
22
27
  dest = "/var/www"
metadata CHANGED
@@ -1,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.5
4
+ version: 2.5.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jamis Buck
8
+ - Lee Hambley
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
12
 
12
- date: 2009-02-24 00:00:00 -07:00
13
+ date: 2009-02-24 00:00:00 +00:00
13
14
  default_executable:
14
15
  dependencies:
15
16
  - !ruby/object:Gem::Dependency
@@ -73,7 +74,7 @@ dependencies:
73
74
  version: "0"
74
75
  version:
75
76
  description: Capistrano is a utility and framework for executing commands in parallel on multiple remote machines, via SSH.
76
- email: jamis@jamisbuck.org
77
+ email: lee.hambley@gmail.com
77
78
  executables:
78
79
  - cap
79
80
  - capify
@@ -194,6 +195,9 @@ files:
194
195
  - lib/capistrano/recipes/deploy/strategy.rb
195
196
  - lib/capistrano/recipes/deploy/templates/maintenance.rhtml
196
197
  - lib/capistrano/recipes/deploy.rb
198
+ - lib/capistrano/recipes/ext/rails-shared-directories.rb
199
+ - lib/capistrano/recipes/ext/rails-database-migrations.rb
200
+ - lib/capistrano/recipes/ext/web-disable-enable.rb
197
201
  - lib/capistrano/recipes/standard.rb
198
202
  - lib/capistrano/recipes/templates/maintenance.rhtml
199
203
  - lib/capistrano/recipes/upgrade.rb
@@ -247,8 +251,11 @@ files:
247
251
  - test/utils.rb
248
252
  - Manifest
249
253
  - capistrano.gemspec
254
+ - test/deploy/scm/none_test.rb
250
255
  has_rdoc: true
251
256
  homepage: http://www.capify.org
257
+ licenses: []
258
+
252
259
  post_install_message:
253
260
  rdoc_options:
254
261
  - --line-numbers
@@ -274,10 +281,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
274
281
  requirements: []
275
282
 
276
283
  rubyforge_project: capistrano
277
- rubygems_version: 1.2.0
284
+ rubygems_version: 1.3.4
278
285
  signing_key:
279
286
  specification_version: 2
280
- summary: Capistrano is a utility and framework for executing commands in parallel on multiple remote machines, via SSH.
287
+ summary: Simple. The way it should be.
281
288
  test_files:
282
289
  - test/cli/execute_test.rb
283
290
  - test/cli/help_test.rb