capistrano 2.8.0 → 3.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. checksums.yaml +7 -0
  2. data/.docker/Dockerfile +7 -0
  3. data/.docker/ssh_key_rsa +49 -0
  4. data/.docker/ssh_key_rsa.pub +1 -0
  5. data/.docker/ubuntu_setup.sh +23 -0
  6. data/.github/issue_template.md +19 -0
  7. data/.github/pull_request_template.md +22 -0
  8. data/.github/release-drafter.yml +25 -0
  9. data/.github/workflows/ci.yml +80 -0
  10. data/.github/workflows/release-drafter.yml +18 -0
  11. data/.gitignore +23 -8
  12. data/.rubocop.yml +62 -0
  13. data/CHANGELOG.md +1 -0
  14. data/CONTRIBUTING.md +63 -0
  15. data/DEVELOPMENT.md +112 -0
  16. data/Gemfile +42 -9
  17. data/LICENSE.txt +21 -0
  18. data/README.md +221 -0
  19. data/RELEASING.md +17 -0
  20. data/Rakefile +17 -8
  21. data/UPGRADING-3.7.md +86 -0
  22. data/bin/cap +2 -3
  23. data/bin/capify +7 -89
  24. data/capistrano.gemspec +29 -43
  25. data/docker-compose.yml +8 -0
  26. data/features/configuration.feature +28 -0
  27. data/features/deploy.feature +92 -0
  28. data/features/deploy_failure.feature +17 -0
  29. data/features/doctor.feature +11 -0
  30. data/features/installation.feature +21 -0
  31. data/features/sshconnect.feature +11 -0
  32. data/features/stage_failure.feature +9 -0
  33. data/features/step_definitions/assertions.rb +162 -0
  34. data/features/step_definitions/cap_commands.rb +21 -0
  35. data/features/step_definitions/setup.rb +91 -0
  36. data/features/subdirectory.feature +9 -0
  37. data/features/support/docker_gateway.rb +53 -0
  38. data/features/support/env.rb +1 -0
  39. data/features/support/remote_command_helpers.rb +29 -0
  40. data/features/support/remote_ssh_helpers.rb +33 -0
  41. data/lib/Capfile +3 -0
  42. data/lib/capistrano/all.rb +17 -0
  43. data/lib/capistrano/application.rb +153 -0
  44. data/lib/capistrano/configuration/empty_filter.rb +9 -0
  45. data/lib/capistrano/configuration/filter.rb +26 -0
  46. data/lib/capistrano/configuration/host_filter.rb +29 -0
  47. data/lib/capistrano/configuration/null_filter.rb +9 -0
  48. data/lib/capistrano/configuration/plugin_installer.rb +51 -0
  49. data/lib/capistrano/configuration/question.rb +76 -0
  50. data/lib/capistrano/configuration/role_filter.rb +29 -0
  51. data/lib/capistrano/configuration/scm_resolver.rb +149 -0
  52. data/lib/capistrano/configuration/server.rb +137 -0
  53. data/lib/capistrano/configuration/servers.rb +56 -96
  54. data/lib/capistrano/configuration/validated_variables.rb +110 -0
  55. data/lib/capistrano/configuration/variables.rb +79 -94
  56. data/lib/capistrano/configuration.rb +178 -33
  57. data/lib/capistrano/console.rb +1 -0
  58. data/lib/capistrano/defaults.rb +36 -0
  59. data/lib/capistrano/deploy.rb +3 -0
  60. data/lib/capistrano/doctor/environment_doctor.rb +19 -0
  61. data/lib/capistrano/doctor/gems_doctor.rb +45 -0
  62. data/lib/capistrano/doctor/output_helpers.rb +79 -0
  63. data/lib/capistrano/doctor/servers_doctor.rb +105 -0
  64. data/lib/capistrano/doctor/variables_doctor.rb +74 -0
  65. data/lib/capistrano/doctor.rb +6 -0
  66. data/lib/capistrano/dotfile.rb +2 -0
  67. data/lib/capistrano/dsl/env.rb +43 -0
  68. data/lib/capistrano/dsl/paths.rb +89 -0
  69. data/lib/capistrano/dsl/stages.rb +31 -0
  70. data/lib/capistrano/dsl/task_enhancements.rb +61 -0
  71. data/lib/capistrano/dsl.rb +95 -0
  72. data/lib/capistrano/framework.rb +2 -0
  73. data/lib/capistrano/i18n.rb +46 -0
  74. data/lib/capistrano/immutable_task.rb +30 -0
  75. data/lib/capistrano/install.rb +1 -0
  76. data/lib/capistrano/plugin.rb +95 -0
  77. data/lib/capistrano/proc_helpers.rb +13 -0
  78. data/lib/capistrano/scm/git.rb +105 -0
  79. data/lib/capistrano/scm/hg.rb +55 -0
  80. data/lib/capistrano/scm/plugin.rb +13 -0
  81. data/lib/capistrano/scm/svn.rb +56 -0
  82. data/lib/capistrano/scm/tasks/git.rake +84 -0
  83. data/lib/capistrano/scm/tasks/hg.rake +53 -0
  84. data/lib/capistrano/scm/tasks/svn.rake +53 -0
  85. data/lib/capistrano/scm.rb +115 -0
  86. data/lib/capistrano/setup.rb +36 -0
  87. data/lib/capistrano/tasks/console.rake +25 -0
  88. data/lib/capistrano/tasks/deploy.rake +280 -0
  89. data/lib/capistrano/tasks/doctor.rake +24 -0
  90. data/lib/capistrano/tasks/framework.rake +67 -0
  91. data/lib/capistrano/tasks/install.rake +41 -0
  92. data/lib/capistrano/templates/Capfile +38 -0
  93. data/lib/capistrano/templates/deploy.rb.erb +39 -0
  94. data/lib/capistrano/templates/stage.rb.erb +61 -0
  95. data/lib/capistrano/upload_task.rb +9 -0
  96. data/lib/capistrano/version.rb +1 -14
  97. data/lib/capistrano/version_validator.rb +32 -0
  98. data/lib/capistrano.rb +0 -3
  99. data/spec/integration/dsl_spec.rb +632 -0
  100. data/spec/integration_spec_helper.rb +5 -0
  101. data/spec/lib/capistrano/application_spec.rb +60 -0
  102. data/spec/lib/capistrano/configuration/empty_filter_spec.rb +17 -0
  103. data/spec/lib/capistrano/configuration/filter_spec.rb +109 -0
  104. data/spec/lib/capistrano/configuration/host_filter_spec.rb +71 -0
  105. data/spec/lib/capistrano/configuration/null_filter_spec.rb +17 -0
  106. data/spec/lib/capistrano/configuration/plugin_installer_spec.rb +98 -0
  107. data/spec/lib/capistrano/configuration/question_spec.rb +92 -0
  108. data/spec/lib/capistrano/configuration/role_filter_spec.rb +80 -0
  109. data/spec/lib/capistrano/configuration/scm_resolver_spec.rb +56 -0
  110. data/spec/lib/capistrano/configuration/server_spec.rb +309 -0
  111. data/spec/lib/capistrano/configuration/servers_spec.rb +331 -0
  112. data/spec/lib/capistrano/configuration_spec.rb +357 -0
  113. data/spec/lib/capistrano/doctor/environment_doctor_spec.rb +44 -0
  114. data/spec/lib/capistrano/doctor/gems_doctor_spec.rb +67 -0
  115. data/spec/lib/capistrano/doctor/output_helpers_spec.rb +47 -0
  116. data/spec/lib/capistrano/doctor/servers_doctor_spec.rb +86 -0
  117. data/spec/lib/capistrano/doctor/variables_doctor_spec.rb +89 -0
  118. data/spec/lib/capistrano/dsl/paths_spec.rb +228 -0
  119. data/spec/lib/capistrano/dsl/task_enhancements_spec.rb +108 -0
  120. data/spec/lib/capistrano/dsl_spec.rb +125 -0
  121. data/spec/lib/capistrano/immutable_task_spec.rb +31 -0
  122. data/spec/lib/capistrano/plugin_spec.rb +84 -0
  123. data/spec/lib/capistrano/scm/git_spec.rb +194 -0
  124. data/spec/lib/capistrano/scm/hg_spec.rb +109 -0
  125. data/spec/lib/capistrano/scm/svn_spec.rb +137 -0
  126. data/spec/lib/capistrano/scm_spec.rb +103 -0
  127. data/spec/lib/capistrano/upload_task_spec.rb +19 -0
  128. data/spec/lib/capistrano/version_validator_spec.rb +118 -0
  129. data/spec/lib/capistrano_spec.rb +7 -0
  130. data/spec/spec_helper.rb +29 -0
  131. data/spec/support/matchers.rb +5 -0
  132. data/spec/support/tasks/database.rake +11 -0
  133. data/spec/support/tasks/fail.rake +8 -0
  134. data/spec/support/tasks/failed.rake +5 -0
  135. data/spec/support/tasks/plugin.rake +6 -0
  136. data/spec/support/tasks/root.rake +11 -0
  137. data/spec/support/test_app.rb +205 -0
  138. metadata +234 -208
  139. data/.rvmrc +0 -1
  140. data/CHANGELOG +0 -954
  141. data/README.mdown +0 -76
  142. data/lib/capistrano/callback.rb +0 -45
  143. data/lib/capistrano/cli/execute.rb +0 -85
  144. data/lib/capistrano/cli/help.rb +0 -125
  145. data/lib/capistrano/cli/help.txt +0 -81
  146. data/lib/capistrano/cli/options.rb +0 -243
  147. data/lib/capistrano/cli/ui.rb +0 -40
  148. data/lib/capistrano/cli.rb +0 -47
  149. data/lib/capistrano/command.rb +0 -286
  150. data/lib/capistrano/configuration/actions/file_transfer.rb +0 -51
  151. data/lib/capistrano/configuration/actions/inspect.rb +0 -46
  152. data/lib/capistrano/configuration/actions/invocation.rb +0 -298
  153. data/lib/capistrano/configuration/callbacks.rb +0 -148
  154. data/lib/capistrano/configuration/connections.rb +0 -230
  155. data/lib/capistrano/configuration/execution.rb +0 -143
  156. data/lib/capistrano/configuration/loading.rb +0 -197
  157. data/lib/capistrano/configuration/namespaces.rb +0 -197
  158. data/lib/capistrano/configuration/roles.rb +0 -73
  159. data/lib/capistrano/errors.rb +0 -19
  160. data/lib/capistrano/ext/string.rb +0 -5
  161. data/lib/capistrano/extensions.rb +0 -57
  162. data/lib/capistrano/logger.rb +0 -59
  163. data/lib/capistrano/processable.rb +0 -53
  164. data/lib/capistrano/recipes/compat.rb +0 -32
  165. data/lib/capistrano/recipes/deploy/assets.rb +0 -57
  166. data/lib/capistrano/recipes/deploy/dependencies.rb +0 -44
  167. data/lib/capistrano/recipes/deploy/local_dependency.rb +0 -54
  168. data/lib/capistrano/recipes/deploy/remote_dependency.rb +0 -111
  169. data/lib/capistrano/recipes/deploy/scm/accurev.rb +0 -169
  170. data/lib/capistrano/recipes/deploy/scm/base.rb +0 -196
  171. data/lib/capistrano/recipes/deploy/scm/bzr.rb +0 -86
  172. data/lib/capistrano/recipes/deploy/scm/cvs.rb +0 -153
  173. data/lib/capistrano/recipes/deploy/scm/darcs.rb +0 -96
  174. data/lib/capistrano/recipes/deploy/scm/git.rb +0 -282
  175. data/lib/capistrano/recipes/deploy/scm/mercurial.rb +0 -137
  176. data/lib/capistrano/recipes/deploy/scm/none.rb +0 -44
  177. data/lib/capistrano/recipes/deploy/scm/perforce.rb +0 -138
  178. data/lib/capistrano/recipes/deploy/scm/subversion.rb +0 -121
  179. data/lib/capistrano/recipes/deploy/scm.rb +0 -19
  180. data/lib/capistrano/recipes/deploy/strategy/base.rb +0 -88
  181. data/lib/capistrano/recipes/deploy/strategy/checkout.rb +0 -20
  182. data/lib/capistrano/recipes/deploy/strategy/copy.rb +0 -224
  183. data/lib/capistrano/recipes/deploy/strategy/export.rb +0 -20
  184. data/lib/capistrano/recipes/deploy/strategy/remote.rb +0 -52
  185. data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +0 -57
  186. data/lib/capistrano/recipes/deploy/strategy.rb +0 -19
  187. data/lib/capistrano/recipes/deploy/templates/maintenance.rhtml +0 -53
  188. data/lib/capistrano/recipes/deploy.rb +0 -568
  189. data/lib/capistrano/recipes/standard.rb +0 -37
  190. data/lib/capistrano/recipes/templates/maintenance.rhtml +0 -53
  191. data/lib/capistrano/role.rb +0 -102
  192. data/lib/capistrano/server_definition.rb +0 -56
  193. data/lib/capistrano/shell.rb +0 -260
  194. data/lib/capistrano/ssh.rb +0 -101
  195. data/lib/capistrano/task_definition.rb +0 -75
  196. data/lib/capistrano/transfer.rb +0 -216
  197. data/rvmrc.sample +0 -1
  198. data/test/cli/execute_test.rb +0 -132
  199. data/test/cli/help_test.rb +0 -165
  200. data/test/cli/options_test.rb +0 -329
  201. data/test/cli/ui_test.rb +0 -28
  202. data/test/cli_test.rb +0 -17
  203. data/test/command_test.rb +0 -289
  204. data/test/configuration/actions/file_transfer_test.rb +0 -61
  205. data/test/configuration/actions/inspect_test.rb +0 -65
  206. data/test/configuration/actions/invocation_test.rb +0 -247
  207. data/test/configuration/callbacks_test.rb +0 -220
  208. data/test/configuration/connections_test.rb +0 -420
  209. data/test/configuration/execution_test.rb +0 -175
  210. data/test/configuration/loading_test.rb +0 -132
  211. data/test/configuration/namespace_dsl_test.rb +0 -311
  212. data/test/configuration/roles_test.rb +0 -144
  213. data/test/configuration/servers_test.rb +0 -183
  214. data/test/configuration/variables_test.rb +0 -190
  215. data/test/configuration_test.rb +0 -88
  216. data/test/deploy/local_dependency_test.rb +0 -76
  217. data/test/deploy/remote_dependency_test.rb +0 -135
  218. data/test/deploy/scm/accurev_test.rb +0 -23
  219. data/test/deploy/scm/base_test.rb +0 -55
  220. data/test/deploy/scm/bzr_test.rb +0 -51
  221. data/test/deploy/scm/darcs_test.rb +0 -37
  222. data/test/deploy/scm/git_test.rb +0 -184
  223. data/test/deploy/scm/mercurial_test.rb +0 -134
  224. data/test/deploy/scm/none_test.rb +0 -35
  225. data/test/deploy/scm/subversion_test.rb +0 -32
  226. data/test/deploy/strategy/copy_test.rb +0 -321
  227. data/test/extensions_test.rb +0 -69
  228. data/test/fixtures/cli_integration.rb +0 -5
  229. data/test/fixtures/config.rb +0 -5
  230. data/test/fixtures/custom.rb +0 -3
  231. data/test/logger_test.rb +0 -123
  232. data/test/recipes_test.rb +0 -25
  233. data/test/role_test.rb +0 -11
  234. data/test/server_definition_test.rb +0 -121
  235. data/test/shell_test.rb +0 -90
  236. data/test/ssh_test.rb +0 -113
  237. data/test/task_definition_test.rb +0 -116
  238. data/test/transfer_test.rb +0 -160
  239. data/test/utils.rb +0 -37
@@ -1,59 +0,0 @@
1
- module Capistrano
2
- class Logger #:nodoc:
3
- attr_accessor :level
4
- attr_reader :device
5
-
6
- IMPORTANT = 0
7
- INFO = 1
8
- DEBUG = 2
9
- TRACE = 3
10
-
11
- MAX_LEVEL = 3
12
-
13
- def initialize(options={})
14
- output = options[:output] || $stderr
15
- if output.respond_to?(:puts)
16
- @device = output
17
- else
18
- @device = File.open(output.to_str, "a")
19
- @needs_close = true
20
- end
21
-
22
- @options = options
23
- @level = 0
24
- end
25
-
26
- def close
27
- device.close if @needs_close
28
- end
29
-
30
- def log(level, message, line_prefix=nil)
31
- if level <= self.level
32
- indent = "%*s" % [MAX_LEVEL, "*" * (MAX_LEVEL - level)]
33
- (RUBY_VERSION >= "1.9" ? message.lines : message).each do |line|
34
- if line_prefix
35
- device.puts "#{indent} [#{line_prefix}] #{line.strip}\n"
36
- else
37
- device.puts "#{indent} #{line.strip}\n"
38
- end
39
- end
40
- end
41
- end
42
-
43
- def important(message, line_prefix=nil)
44
- log(IMPORTANT, message, line_prefix)
45
- end
46
-
47
- def info(message, line_prefix=nil)
48
- log(INFO, message, line_prefix)
49
- end
50
-
51
- def debug(message, line_prefix=nil)
52
- log(DEBUG, message, line_prefix)
53
- end
54
-
55
- def trace(message, line_prefix=nil)
56
- log(TRACE, message, line_prefix)
57
- end
58
- end
59
- end
@@ -1,53 +0,0 @@
1
- module Capistrano
2
- module Processable
3
- module SessionAssociation
4
- def self.on(exception, session)
5
- unless exception.respond_to?(:session)
6
- exception.extend(self)
7
- exception.session = session
8
- end
9
-
10
- return exception
11
- end
12
-
13
- attr_accessor :session
14
- end
15
-
16
- def process_iteration(wait=nil, &block)
17
- ensure_each_session { |session| session.preprocess }
18
-
19
- return false if block && !block.call(self)
20
-
21
- readers = sessions.map { |session| session.listeners.keys }.flatten.reject { |io| io.closed? }
22
- writers = readers.select { |io| io.respond_to?(:pending_write?) && io.pending_write? }
23
-
24
- if readers.any? || writers.any?
25
- readers, writers, = IO.select(readers, writers, nil, wait)
26
- end
27
-
28
- if readers
29
- ensure_each_session do |session|
30
- ios = session.listeners.keys
31
- session.postprocess(ios & readers, ios & writers)
32
- end
33
- end
34
-
35
- true
36
- end
37
-
38
- def ensure_each_session
39
- errors = []
40
-
41
- sessions.each do |session|
42
- begin
43
- yield session
44
- rescue Exception => error
45
- errors << SessionAssociation.on(error, session)
46
- end
47
- end
48
-
49
- raise errors.first if errors.any?
50
- sessions
51
- end
52
- end
53
- end
@@ -1,32 +0,0 @@
1
- # A collection of compatibility scripts, to ease the transition between
2
- # Capistrano 1.x and Capistrano 2.x.
3
-
4
- # Depends on the deployment system
5
- load 'deploy'
6
-
7
- map = { "diff_from_last_deploy" => "deploy:pending:diff",
8
- "update" => "deploy:update",
9
- "update_code" => "deploy:update_code",
10
- "symlink" => "deploy:symlink",
11
- "restart" => "deploy:restart",
12
- "rollback" => "deploy:rollback",
13
- "cleanup" => "deploy:cleanup",
14
- "disable_web" => "deploy:web:disable",
15
- "enable_web" => "deploy:web:enable",
16
- "cold_deploy" => "deploy:cold",
17
- "deploy_with_migrations" => "deploy:migrations" }
18
-
19
- map.each do |old, new|
20
- desc "DEPRECATED: See #{new}."
21
- eval "task(#{old.inspect}) do
22
- warn \"[DEPRECATED] `#{old}' is deprecated. Use `#{new}' instead.\"
23
- find_and_execute_task(#{new.inspect})
24
- end"
25
- end
26
-
27
- desc "DEPRECATED: See deploy:start."
28
- task :spinner do
29
- warn "[DEPRECATED] `spinner' is deprecated. Use `deploy:start' instead."
30
- set :runner, fetch(:spinner_user, "app")
31
- deploy.start
32
- end
@@ -1,57 +0,0 @@
1
- load 'deploy' unless defined?(_cset)
2
-
3
- _cset :asset_env, "RAILS_GROUPS=assets"
4
- _cset :assets_prefix, "assets"
5
-
6
- before 'deploy:finalize_update', 'deploy:assets:symlink'
7
- after 'deploy:update_code', 'deploy:assets:precompile'
8
-
9
- namespace :deploy do
10
- namespace :assets do
11
- desc <<-DESC
12
- [internal] This task will set up a symlink to the shared directory \
13
- for the assets directory. Assets are shared across deploys to avoid \
14
- mid-deploy mismatches between old application html asking for assets \
15
- and getting a 404 file not found error. The assets cache is shared \
16
- for efficiency. If you cutomize the assets path prefix, override the \
17
- :assets_prefix variable to match.
18
- DESC
19
- task :symlink, :roles => :web, :except => { :no_release => true } do
20
- run <<-CMD
21
- rm -rf #{latest_release}/public/#{assets_prefix} &&
22
- mkdir -p #{latest_release}/public &&
23
- mkdir -p #{shared_path}/assets &&
24
- ln -s #{shared_path}/assets #{latest_release}/public/#{assets_prefix}
25
- CMD
26
- end
27
-
28
- desc <<-DESC
29
- Run the asset precompilation rake task. You can specify the full path \
30
- to the rake executable by setting the rake variable. You can also \
31
- specify additional environment variables to pass to rake via the \
32
- asset_env variable. The defaults are:
33
-
34
- set :rake, "rake"
35
- set :rails_env, "production"
36
- set :asset_env, "RAILS_GROUPS=assets"
37
- DESC
38
- task :precompile, :roles => :web, :except => { :no_release => true } do
39
- run "cd #{latest_release} && #{rake} RAILS_ENV=#{rails_env} #{asset_env} assets:precompile"
40
- end
41
-
42
- desc <<-DESC
43
- Run the asset clean rake task. Use with caution, this will delete \
44
- all of your compiled assets. You can specify the full path \
45
- to the rake executable by setting the rake variable. You can also \
46
- specify additional environment variables to pass to rake via the \
47
- asset_env variable. The defaults are:
48
-
49
- set :rake, "rake"
50
- set :rails_env, "production"
51
- set :asset_env, "RAILS_GROUPS=assets"
52
- DESC
53
- task :clean, :roles => :web, :except => { :no_release => true } do
54
- run "cd #{latest_release} && #{rake} RAILS_ENV=#{rails_env} #{asset_env} assets:clean"
55
- end
56
- end
57
- end
@@ -1,44 +0,0 @@
1
- require 'capistrano/recipes/deploy/local_dependency'
2
- require 'capistrano/recipes/deploy/remote_dependency'
3
-
4
- module Capistrano
5
- module Deploy
6
- class Dependencies
7
- include Enumerable
8
-
9
- attr_reader :configuration
10
-
11
- def initialize(configuration)
12
- @configuration = configuration
13
- @dependencies = []
14
- yield self if block_given?
15
- end
16
-
17
- def check
18
- yield self
19
- self
20
- end
21
-
22
- def remote
23
- dep = RemoteDependency.new(configuration)
24
- @dependencies << dep
25
- dep
26
- end
27
-
28
- def local
29
- dep = LocalDependency.new(configuration)
30
- @dependencies << dep
31
- dep
32
- end
33
-
34
- def each
35
- @dependencies.each { |d| yield d }
36
- self
37
- end
38
-
39
- def pass?
40
- all? { |d| d.pass? }
41
- end
42
- end
43
- end
44
- end
@@ -1,54 +0,0 @@
1
- module Capistrano
2
- module Deploy
3
- class LocalDependency
4
- attr_reader :configuration
5
- attr_reader :message
6
-
7
- def initialize(configuration)
8
- @configuration = configuration
9
- @success = true
10
- end
11
-
12
- def command(command)
13
- @message ||= "`#{command}' could not be found in the path on the local host"
14
- @success = find_in_path(command)
15
- self
16
- end
17
-
18
- def or(message)
19
- @message = message
20
- self
21
- end
22
-
23
- def pass?
24
- @success
25
- end
26
-
27
- private
28
-
29
- # Searches the path, looking for the given utility. If an executable
30
- # file is found that matches the parameter, this returns true.
31
- def find_in_path(utility)
32
- path = (ENV['PATH'] || "").split(File::PATH_SEPARATOR)
33
- suffixes = self.class.on_windows? ? self.class.windows_executable_extensions : [""]
34
-
35
- path.each do |dir|
36
- suffixes.each do |sfx|
37
- file = File.join(dir, utility + sfx)
38
- return true if File.executable?(file)
39
- end
40
- end
41
-
42
- false
43
- end
44
-
45
- def self.on_windows?
46
- RUBY_PLATFORM =~ /mswin|mingw/
47
- end
48
-
49
- def self.windows_executable_extensions
50
- %w(.exe .bat .com .cmd)
51
- end
52
- end
53
- end
54
- end
@@ -1,111 +0,0 @@
1
- require 'capistrano/errors'
2
-
3
- module Capistrano
4
- module Deploy
5
- class RemoteDependency
6
- attr_reader :configuration
7
- attr_reader :hosts
8
-
9
- def initialize(configuration)
10
- @configuration = configuration
11
- @success = true
12
- @hosts = nil
13
- end
14
-
15
- def directory(path, options={})
16
- @message ||= "`#{path}' is not a directory"
17
- try("test -d #{path}", options)
18
- self
19
- end
20
-
21
- def file(path, options={})
22
- @message ||= "`#{path}' is not a file"
23
- try("test -f #{path}", options)
24
- self
25
- end
26
-
27
- def writable(path, options={})
28
- @message ||= "`#{path}' is not writable"
29
- try("test -w #{path}", options)
30
- self
31
- end
32
-
33
- def command(command, options={})
34
- @message ||= "`#{command}' could not be found in the path"
35
- try("which #{command}", options)
36
- self
37
- end
38
-
39
- def gem(name, version, options={})
40
- @message ||= "gem `#{name}' #{version} could not be found"
41
- gem_cmd = configuration.fetch(:gem_command, "gem")
42
- try("#{gem_cmd} specification --version '#{version}' #{name} 2>&1 | awk 'BEGIN { s = 0 } /^name:/ { s = 1; exit }; END { if(s == 0) exit 1 }'", options)
43
- self
44
- end
45
-
46
- def deb(name, version, options={})
47
- @message ||= "package `#{name}' #{version} could not be found"
48
- try("dpkg -s #{name} | grep '^Version: #{version}'", options)
49
- self
50
- end
51
-
52
- def match(command, expect, options={})
53
- expect = Regexp.new(Regexp.escape(expect.to_s)) unless expect.is_a?(Regexp)
54
-
55
- output_per_server = {}
56
- try("#{command} ", options) do |ch, stream, out|
57
- output_per_server[ch[:server]] ||= ''
58
- output_per_server[ch[:server]] += out
59
- end
60
-
61
- # It is possible for some of these commands to return a status != 0
62
- # (for example, rake --version exits with a 1). For this check we
63
- # just care if the output matches, so we reset the success flag.
64
- @success = true
65
-
66
- errored_hosts = []
67
- output_per_server.each_pair do |server, output|
68
- next if output =~ expect
69
- errored_hosts << server
70
- end
71
-
72
- if errored_hosts.any?
73
- @hosts = errored_hosts.join(', ')
74
- output = output_per_server[errored_hosts.first]
75
- @message = "the output #{output.inspect} from #{command.inspect} did not match #{expect.inspect}"
76
- @success = false
77
- end
78
-
79
- self
80
- end
81
-
82
- def or(message)
83
- @message = message
84
- self
85
- end
86
-
87
- def pass?
88
- @success
89
- end
90
-
91
- def message
92
- s = @message.dup
93
- s << " (#{@hosts})" if @hosts
94
- s
95
- end
96
-
97
- private
98
-
99
- def try(command, options)
100
- return unless @success # short-circuit evaluation
101
- configuration.invoke_command(command, options) do |ch,stream,out|
102
- warn "#{ch[:server]}: #{out}" if stream == :err
103
- yield ch, stream, out if block_given?
104
- end
105
- rescue Capistrano::CommandError => e
106
- @success = false
107
- @hosts = e.hosts.join(', ')
108
- end
109
- end
110
- end
111
- end
@@ -1,169 +0,0 @@
1
- require 'capistrano/recipes/deploy/scm/base'
2
- require 'rexml/xpath'
3
- require 'rexml/document'
4
-
5
- module Capistrano
6
- module Deploy
7
- module SCM
8
- # Accurev bridge for use by Capistrano. This implementation does not
9
- # implement all features of a Capistrano SCM module. The ones that are
10
- # left out are either exceedingly difficult to implement with Accurev
11
- # or are considered bad form.
12
- #
13
- # When using this module in a project, the following variables are used:
14
- # * :repository - This should match the depot that code lives in. If your code
15
- # exists in a subdirectory, you can append the path depot.
16
- # eg. foo-depot/bar_dir
17
- # * :stream - The stream in the depot that code should be pulled from. If
18
- # left blank, the depot stream will be used
19
- # * :revision - Should be in the form 'stream/transaction'.
20
- class Accurev < Base
21
- include REXML
22
- default_command 'accurev'
23
-
24
- # Defines pseudo-revision value for the most recent changes to be deployed.
25
- def head
26
- "#{stream}/highest"
27
- end
28
-
29
- # Given an Accurev revision identifier, this method returns an identifier that
30
- # can be used for later SCM calls. This returned identifier will not
31
- # change as a result of further SCM activity.
32
- def query_revision(revision)
33
- internal_revision = InternalRevision.parse(revision)
34
- return revision unless internal_revision.psuedo_revision?
35
-
36
- logger.debug("Querying for real revision for #{internal_revision}")
37
- rev_stream = internal_revision.stream
38
-
39
- logger.debug("Determining what type of stream #{rev_stream} is...")
40
- stream_xml = yield show_streams_for(rev_stream)
41
- stream_doc = Document.new(stream_xml)
42
- type = XPath.first(stream_doc, '//streams/stream/@type').value
43
-
44
- case type
45
- when 'snapshot'
46
- InternalRevision.new(rev_stream, 'highest').to_s
47
- else
48
- logger.debug("Getting latest transaction id in #{rev_stream}")
49
- # Doing another yield for a second Accurev call. Hopefully this is ok.
50
- hist_xml = yield scm(:hist, '-ftx', '-s', rev_stream, '-t', 'now.1')
51
- hist_doc = Document.new(hist_xml)
52
- transaction_id = XPath.first(hist_doc, '//AcResponse/transaction/@id').value
53
- InternalRevision.new(stream, transaction_id).to_s
54
- end
55
- end
56
-
57
- # Pops a copy of the code for the specified Accurev revision identifier.
58
- # The revision identifier is represented as a stream & transaction ID combo.
59
- # Accurev can only pop a particular transaction if a stream is created on the server
60
- # with a time basis of that transaction id. Therefore, we will create a stream with
61
- # the required criteria and pop that.
62
- def export(revision_id, destination)
63
- revision = InternalRevision.parse(revision_id)
64
- logger.debug("Exporting #{revision.stream}/#{revision.transaction_id} to #{destination}")
65
-
66
- commands = [
67
- change_or_create_stream("#{revision.stream}-capistrano-deploy", revision),
68
- "mkdir -p #{destination}",
69
- scm_quiet(:pop, "-Rv #{stream}", "-L #{destination}", "'/./#{subdir}'")
70
- ]
71
- if subdir
72
- commands.push(
73
- "mv #{destination}/#{subdir}/* #{destination}",
74
- "rm -rf #{File.join(destination, subdir)}"
75
- )
76
- end
77
- commands.join(' && ')
78
- end
79
-
80
- # Returns the command needed to show the changes that exist between the two revisions.
81
- def log(from, to=head)
82
- logger.info("Getting transactions between #{from} and #{to}")
83
- from_rev = InternalRevision.parse(from)
84
- to_rev = InternalRevision.parse(to)
85
-
86
- [
87
- scm(:hist, '-s', from_rev.stream, '-t', "#{to_rev.transaction_id}-#{from_rev.transaction_id}"),
88
- "sed -e '/transaction #{from_rev.transaction_id}/ { Q }'"
89
- ].join(' | ')
90
- end
91
-
92
- # Returns the command needed to show the diff between what is deployed and what is
93
- # pending. Because Accurev can not do this task without creating some streams,
94
- # two time basis streams will be created for the purposes of doing the diff.
95
- def diff(from, to=head)
96
- from = InternalRevision.parse(from)
97
- to = InternalRevision.parse(to)
98
-
99
- from_stream = "#{from.stream}-capistrano-diff-from"
100
- to_stream = "#{to.stream}-capistrano-diff-to"
101
-
102
- [
103
- change_or_create_stream(from_stream, from),
104
- change_or_create_stream(to_stream, to),
105
- scm(:diff, '-v', from_stream, '-V', to_stream, '-a')
106
- ].join(' && ')
107
- end
108
-
109
- private
110
- def depot
111
- repository.split('/')[0]
112
- end
113
-
114
- def stream
115
- variable(:stream) || depot
116
- end
117
-
118
- def subdir
119
- repository.split('/')[1..-1].join('/') unless repository.index('/').nil?
120
- end
121
-
122
- def change_or_create_stream(name, revision)
123
- [
124
- scm_quiet(:mkstream, '-b', revision.stream, '-s', name, '-t', revision.transaction_id),
125
- scm_quiet(:chstream, '-b', revision.stream, '-s', name, '-t', revision.transaction_id)
126
- ].join('; ')
127
- end
128
-
129
- def show_streams_for(stream)
130
- scm :show, '-fx', '-s', stream, :streams
131
- end
132
-
133
- def scm_quiet(*args)
134
- scm(*args) + (variable(:scm_verbose) ? '' : '&> /dev/null')
135
- end
136
-
137
- class InternalRevision
138
- attr_reader :stream, :transaction_id
139
-
140
- def self.parse(string)
141
- match = /([^\/]+)(\/(.+)){0,1}/.match(string)
142
- raise "Unrecognized revision identifier: #{string}" unless match
143
-
144
- stream = match[1]
145
- transaction_id = match[3] || 'highest'
146
- InternalRevision.new(stream, transaction_id)
147
- end
148
-
149
- def initialize(stream, transaction_id)
150
- @stream = stream
151
- @transaction_id = transaction_id
152
- end
153
-
154
- def psuedo_revision?
155
- @transaction_id == 'highest'
156
- end
157
-
158
- def to_s
159
- "#{stream}/#{transaction_id}"
160
- end
161
-
162
- def ==(other)
163
- (stream == other.stream) && (transaction_id == other.transaction_id)
164
- end
165
- end
166
- end
167
- end
168
- end
169
- end