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,40 +0,0 @@
1
- require 'highline'
2
-
3
- # work around problem where HighLine detects an eof on $stdin and raises an
4
- # error.
5
- HighLine.track_eof = false
6
-
7
- module Capistrano
8
- class CLI
9
- module UI
10
- def self.included(base) #:nodoc:
11
- base.extend(ClassMethods)
12
- end
13
-
14
- module ClassMethods
15
- # Return the object that provides UI-specific methods, such as prompts
16
- # and more.
17
- def ui
18
- @ui ||= HighLine.new
19
- end
20
-
21
- # Prompt for a password using echo suppression.
22
- def password_prompt(prompt="Password: ")
23
- ui.ask(prompt) { |q| q.echo = false }
24
- end
25
-
26
- # Debug mode prompt
27
- def debug_prompt(cmd)
28
- ui.say("Preparing to execute command: #{cmd}")
29
- prompt = "Execute ([Yes], No, Abort) "
30
- ui.ask("#{prompt}? ") do |q|
31
- q.overwrite = false
32
- q.default = 'y'
33
- q.validate = /(y(es)?)|(no?)|(a(bort)?|\n)/i
34
- q.responses[:not_valid] = prompt
35
- end
36
- end
37
- end
38
- end
39
- end
40
- end
@@ -1,47 +0,0 @@
1
- require 'capistrano'
2
- require 'capistrano/cli/execute'
3
- require 'capistrano/cli/help'
4
- require 'capistrano/cli/options'
5
- require 'capistrano/cli/ui'
6
-
7
- module Capistrano
8
- # The CLI class encapsulates the behavior of capistrano when it is invoked
9
- # as a command-line utility. This allows other programs to embed Capistrano
10
- # and preserve its command-line semantics.
11
- class CLI
12
- # The array of (unparsed) command-line options
13
- attr_reader :args
14
-
15
- # Create a new CLI instance using the given array of command-line parameters
16
- # to initialize it. By default, +ARGV+ is used, but you can specify a
17
- # different set of parameters (such as when embedded cap in a program):
18
- #
19
- # require 'capistrano/cli'
20
- # Capistrano::CLI.parse(%W(-vvvv -f config/deploy update_code)).execute!
21
- #
22
- # Note that you can also embed cap directly by creating a new Configuration
23
- # instance and setting it up, The above snippet, redone using the
24
- # Configuration class directly, would look like:
25
- #
26
- # require 'capistrano'
27
- # require 'capistrano/cli'
28
- # config = Capistrano::Configuration.new
29
- # config.logger.level = Capistrano::Logger::TRACE
30
- # config.set(:password) { Capistrano::CLI.password_prompt }
31
- # config.load "config/deploy"
32
- # config.update_code
33
- #
34
- # There may be times that you want/need the additional control offered by
35
- # manipulating the Configuration directly, but generally interfacing with
36
- # the CLI class is recommended.
37
- def initialize(args)
38
- @args = args.dup
39
- $stdout.sync = true # so that Net::SSH prompts show up
40
- end
41
-
42
- # Mix-in the actual behavior
43
- include Execute, Options, UI
44
- include Help # needs to be included last, because it overrides some methods
45
-
46
- end
47
- end
@@ -1,286 +0,0 @@
1
- require 'benchmark'
2
- require 'capistrano/errors'
3
- require 'capistrano/processable'
4
-
5
- module Capistrano
6
-
7
- # This class encapsulates a single command to be executed on a set of remote
8
- # machines, in parallel.
9
- class Command
10
- include Processable
11
-
12
- class Tree
13
- attr_reader :configuration
14
- attr_reader :branches
15
- attr_reader :fallback
16
-
17
- include Enumerable
18
-
19
- class Branch
20
- attr_accessor :command, :callback
21
- attr_reader :options
22
-
23
- def initialize(command, options, callback)
24
- @command = command.strip.gsub(/\r?\n/, "\\\n")
25
- @callback = callback || Capistrano::Configuration.default_io_proc
26
- @options = options
27
- @skip = false
28
- end
29
-
30
- def last?
31
- options[:last]
32
- end
33
-
34
- def skip?
35
- @skip
36
- end
37
-
38
- def skip!
39
- @skip = true
40
- end
41
-
42
- def match(server)
43
- true
44
- end
45
-
46
- def to_s
47
- command.inspect
48
- end
49
- end
50
-
51
- class ConditionBranch < Branch
52
- attr_accessor :configuration
53
- attr_accessor :condition
54
-
55
- class Evaluator
56
- attr_reader :configuration, :condition, :server
57
-
58
- def initialize(config, condition, server)
59
- @configuration = config
60
- @condition = condition
61
- @server = server
62
- end
63
-
64
- def in?(role)
65
- configuration.roles[role].include?(server)
66
- end
67
-
68
- def result
69
- eval(condition, binding)
70
- end
71
-
72
- def method_missing(sym, *args, &block)
73
- if server.respond_to?(sym)
74
- server.send(sym, *args, &block)
75
- elsif configuration.respond_to?(sym)
76
- configuration.send(sym, *args, &block)
77
- else
78
- super
79
- end
80
- end
81
- end
82
-
83
- def initialize(configuration, condition, command, options, callback)
84
- @configuration = configuration
85
- @condition = condition
86
- super(command, options, callback)
87
- end
88
-
89
- def match(server)
90
- Evaluator.new(configuration, condition, server).result
91
- end
92
-
93
- def to_s
94
- "#{condition.inspect} :: #{command.inspect}"
95
- end
96
- end
97
-
98
- def initialize(config)
99
- @configuration = config
100
- @branches = []
101
- yield self if block_given?
102
- end
103
-
104
- def when(condition, command, options={}, &block)
105
- branches << ConditionBranch.new(configuration, condition, command, options, block)
106
- end
107
-
108
- def else(command, &block)
109
- @fallback = Branch.new(command, {}, block)
110
- end
111
-
112
- def branches_for(server)
113
- seen_last = false
114
- matches = branches.select do |branch|
115
- success = !seen_last && !branch.skip? && branch.match(server)
116
- seen_last = success && branch.last?
117
- success
118
- end
119
-
120
- matches << fallback if matches.empty? && fallback
121
- return matches
122
- end
123
-
124
- def each
125
- branches.each { |branch| yield branch }
126
- yield fallback if fallback
127
- return self
128
- end
129
- end
130
-
131
- attr_reader :tree, :sessions, :options
132
-
133
- def self.process(tree, sessions, options={})
134
- new(tree, sessions, options).process!
135
- end
136
-
137
- # Instantiates a new command object. The +command+ must be a string
138
- # containing the command to execute. +sessions+ is an array of Net::SSH
139
- # session instances, and +options+ must be a hash containing any of the
140
- # following keys:
141
- #
142
- # * +logger+: (optional), a Capistrano::Logger instance
143
- # * +data+: (optional), a string to be sent to the command via it's stdin
144
- # * +env+: (optional), a string or hash to be interpreted as environment
145
- # variables that should be defined for this command invocation.
146
- def initialize(tree, sessions, options={}, &block)
147
- if String === tree
148
- tree = Tree.new(nil) { |t| t.else(tree, &block) }
149
- elsif block
150
- raise ArgumentError, "block given with tree argument"
151
- end
152
-
153
- @tree = tree
154
- @sessions = sessions
155
- @options = options
156
- @channels = open_channels
157
- end
158
-
159
- # Processes the command in parallel on all specified hosts. If the command
160
- # fails (non-zero return code) on any of the hosts, this will raise a
161
- # Capistrano::CommandError.
162
- def process!
163
- elapsed = Benchmark.realtime do
164
- loop do
165
- break unless process_iteration { @channels.any? { |ch| !ch[:closed] } }
166
- end
167
- end
168
-
169
- logger.trace "command finished in #{(elapsed * 1000).round}ms" if logger
170
-
171
- if (failed = @channels.select { |ch| ch[:status] != 0 }).any?
172
- commands = failed.inject({}) { |map, ch| (map[ch[:command]] ||= []) << ch[:server]; map }
173
- message = commands.map { |command, list| "#{command.inspect} on #{list.join(',')}" }.join("; ")
174
- error = CommandError.new("failed: #{message}")
175
- error.hosts = commands.values.flatten
176
- raise error
177
- end
178
-
179
- self
180
- end
181
-
182
- # Force the command to stop processing, by closing all open channels
183
- # associated with this command.
184
- def stop!
185
- @channels.each do |ch|
186
- ch.close unless ch[:closed]
187
- end
188
- end
189
-
190
- private
191
-
192
- def logger
193
- options[:logger]
194
- end
195
-
196
- def open_channels
197
- sessions.map do |session|
198
- server = session.xserver
199
- tree.branches_for(server).map do |branch|
200
- session.open_channel do |channel|
201
- channel[:server] = server
202
- channel[:host] = server.host
203
- channel[:options] = options
204
- channel[:branch] = branch
205
-
206
- request_pty_if_necessary(channel) do |ch, success|
207
- if success
208
- logger.trace "executing command", ch[:server] if logger
209
- cmd = replace_placeholders(channel[:branch].command, ch)
210
-
211
- if options[:shell] == false
212
- shell = nil
213
- else
214
- shell = "#{options[:shell] || "sh"} -c"
215
- cmd = cmd.gsub(/'/) { |m| "'\\''" }
216
- cmd = "'#{cmd}'"
217
- end
218
-
219
- command_line = [environment, shell, cmd].compact.join(" ")
220
- ch[:command] = command_line
221
-
222
- ch.exec(command_line)
223
- ch.send_data(options[:data]) if options[:data]
224
- else
225
- # just log it, don't actually raise an exception, since the
226
- # process method will see that the status is not zero and will
227
- # raise an exception then.
228
- logger.important "could not open channel", ch[:server] if logger
229
- ch.close
230
- end
231
- end
232
-
233
- channel.on_data do |ch, data|
234
- ch[:branch].callback[ch, :out, data]
235
- end
236
-
237
- channel.on_extended_data do |ch, type, data|
238
- ch[:branch].callback[ch, :err, data]
239
- end
240
-
241
- channel.on_request("exit-status") do |ch, data|
242
- ch[:status] = data.read_long
243
- end
244
-
245
- channel.on_close do |ch|
246
- ch[:closed] = true
247
- end
248
- end
249
- end
250
- end.flatten
251
- end
252
-
253
- def request_pty_if_necessary(channel)
254
- if options[:pty]
255
- channel.request_pty do |ch, success|
256
- yield ch, success
257
- end
258
- else
259
- yield channel, true
260
- end
261
- end
262
-
263
- def replace_placeholders(command, channel)
264
- command.gsub(/\$CAPISTRANO:HOST\$/, channel[:host])
265
- end
266
-
267
- # prepare a space-separated sequence of variables assignments
268
- # intended to be prepended to a command, so the shell sets
269
- # the environment before running the command.
270
- # i.e.: options[:env] = {'PATH' => '/opt/ruby/bin:$PATH',
271
- # 'TEST' => '( "quoted" )'}
272
- # environment returns:
273
- # "env TEST=(\ \"quoted\"\ ) PATH=/opt/ruby/bin:$PATH"
274
- def environment
275
- return if options[:env].nil? || options[:env].empty?
276
- @environment ||= if String === options[:env]
277
- "env #{options[:env]}"
278
- else
279
- options[:env].inject("env") do |string, (name, value)|
280
- value = value.to_s.gsub(/[ "]/) { |m| "\\#{m}" }
281
- string << " #{name}=#{value}"
282
- end
283
- end
284
- end
285
- end
286
- end
@@ -1,51 +0,0 @@
1
- require 'capistrano/transfer'
2
-
3
- module Capistrano
4
- class Configuration
5
- module Actions
6
- module FileTransfer
7
-
8
- # Store the given data at the given location on all servers targetted
9
- # by the current task. If <tt>:mode</tt> is specified it is used to
10
- # set the mode on the file.
11
- def put(data, path, options={})
12
- opts = options.dup
13
- upload(StringIO.new(data), path, opts)
14
- end
15
-
16
- # Get file remote_path from FIRST server targeted by
17
- # the current task and transfer it to local machine as path.
18
- #
19
- # get "#{deploy_to}/current/log/production.log", "log/production.log.web"
20
- def get(remote_path, path, options={}, &block)
21
- download(remote_path, path, options.merge(:once => true), &block)
22
- end
23
-
24
- def upload(from, to, options={}, &block)
25
- mode = options.delete(:mode)
26
- transfer(:up, from, to, options, &block)
27
- if mode
28
- mode = mode.is_a?(Numeric) ? mode.to_s(8) : mode.to_s
29
- run "chmod #{mode} #{to}", options
30
- end
31
- end
32
-
33
- def download(from, to, options={}, &block)
34
- transfer(:down, from, to, options, &block)
35
- end
36
-
37
- def transfer(direction, from, to, options={}, &block)
38
- execute_on_servers(options) do |servers|
39
- targets = servers.map { |s| sessions[s] }
40
- if dry_run
41
- logger.debug "transfering: #{[direction, from, to, targets, options.merge(:logger => logger).inspect ] * ', '}"
42
- else
43
- Transfer.process(direction, from, to, targets, options.merge(:logger => logger), &block)
44
- end
45
- end
46
- end
47
-
48
- end
49
- end
50
- end
51
- end
@@ -1,46 +0,0 @@
1
- require 'capistrano/errors'
2
-
3
- module Capistrano
4
- class Configuration
5
- module Actions
6
- module Inspect
7
-
8
- # Streams the result of the command from all servers that are the
9
- # target of the current task. All these streams will be joined into a
10
- # single one, so you can, say, watch 10 log files as though they were
11
- # one. Do note that this is quite expensive from a bandwidth
12
- # perspective, so use it with care.
13
- #
14
- # The command is invoked via #invoke_command.
15
- #
16
- # Usage:
17
- #
18
- # desc "Run a tail on multiple log files at the same time"
19
- # task :tail_fcgi, :roles => :app do
20
- # stream "tail -f #{shared_path}/log/fastcgi.crash.log"
21
- # end
22
- def stream(command, options={})
23
- invoke_command(command, options) do |ch, stream, out|
24
- puts out if stream == :out
25
- warn "[err :: #{ch[:server]}] #{out}" if stream == :err
26
- end
27
- end
28
-
29
- # Executes the given command on the first server targetted by the
30
- # current task, collects it's stdout into a string, and returns the
31
- # string. The command is invoked via #invoke_command.
32
- def capture(command, options={})
33
- output = ""
34
- invoke_command(command, options.merge(:once => true)) do |ch, stream, data|
35
- case stream
36
- when :out then output << data
37
- when :err then warn "[err :: #{ch[:server]}] #{data}"
38
- end
39
- end
40
- output
41
- end
42
-
43
- end
44
- end
45
- end
46
- end