capistrano 2.15.11 → 3.0.0.pre

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 (158) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +17 -8
  3. data/Gemfile +1 -12
  4. data/LICENSE.txt +18 -0
  5. data/README.md +65 -68
  6. data/Rakefile +4 -10
  7. data/bin/cap +2 -3
  8. data/bin/capify +7 -91
  9. data/capistrano.gemspec +20 -34
  10. data/lib/Capfile +2 -0
  11. data/lib/capistrano/application.rb +28 -0
  12. data/lib/capistrano/bundler.rb +1 -0
  13. data/lib/capistrano/configuration/question.rb +42 -0
  14. data/lib/capistrano/configuration/server.rb +24 -0
  15. data/lib/capistrano/configuration/servers.rb +43 -95
  16. data/lib/capistrano/configuration.rb +81 -44
  17. data/lib/capistrano/console.rb +1 -0
  18. data/lib/capistrano/defaults.rb +11 -0
  19. data/lib/capistrano/deploy.rb +3 -0
  20. data/lib/capistrano/dotfile.rb +3 -0
  21. data/lib/capistrano/dsl/env.rb +57 -0
  22. data/lib/capistrano/dsl/paths.rb +74 -0
  23. data/lib/capistrano/dsl/stages.rb +15 -0
  24. data/lib/capistrano/dsl/task_enhancements.rb +15 -0
  25. data/lib/capistrano/dsl.rb +38 -0
  26. data/lib/capistrano/git.rb +1 -0
  27. data/lib/capistrano/i18n.rb +33 -0
  28. data/lib/capistrano/install.rb +1 -0
  29. data/lib/capistrano/setup.rb +17 -0
  30. data/lib/capistrano/tasks/bundler.rake +13 -0
  31. data/lib/capistrano/tasks/console.rake +21 -0
  32. data/lib/capistrano/tasks/deploy.rake +153 -0
  33. data/lib/capistrano/tasks/framework.rake +45 -0
  34. data/lib/capistrano/tasks/git.rake +65 -0
  35. data/lib/capistrano/tasks/install.rake +39 -0
  36. data/lib/capistrano/templates/Capfile +43 -0
  37. data/lib/capistrano/templates/deploy.rb.erb +17 -0
  38. data/lib/capistrano/templates/stage.rb.erb +20 -0
  39. data/lib/capistrano/version.rb +1 -11
  40. data/lib/capistrano.rb +9 -3
  41. data/spec/lib/capistrano/configuration/question_spec.rb +54 -0
  42. data/spec/lib/capistrano/configuration/server_spec.rb +48 -0
  43. data/spec/lib/capistrano/configuration/servers_spec.rb +79 -0
  44. data/spec/lib/capistrano/configuration_spec.rb +80 -0
  45. data/spec/lib/capistrano/dsl/env_spec.rb +83 -0
  46. data/spec/lib/capistrano/dsl/paths_spec.rb +69 -0
  47. data/spec/lib/capistrano/dsl_spec.rb +51 -0
  48. data/spec/lib/capistrano_spec.rb +8 -0
  49. data/spec/spec_helper.rb +14 -0
  50. metadata +89 -215
  51. data/.travis.yml +0 -9
  52. data/CHANGELOG +0 -1203
  53. data/lib/capistrano/callback.rb +0 -45
  54. data/lib/capistrano/cli/execute.rb +0 -85
  55. data/lib/capistrano/cli/help.rb +0 -125
  56. data/lib/capistrano/cli/help.txt +0 -81
  57. data/lib/capistrano/cli/options.rb +0 -243
  58. data/lib/capistrano/cli/ui.rb +0 -40
  59. data/lib/capistrano/cli.rb +0 -47
  60. data/lib/capistrano/command.rb +0 -303
  61. data/lib/capistrano/configuration/actions/file_transfer.rb +0 -50
  62. data/lib/capistrano/configuration/actions/inspect.rb +0 -46
  63. data/lib/capistrano/configuration/actions/invocation.rb +0 -329
  64. data/lib/capistrano/configuration/alias_task.rb +0 -26
  65. data/lib/capistrano/configuration/callbacks.rb +0 -147
  66. data/lib/capistrano/configuration/connections.rb +0 -237
  67. data/lib/capistrano/configuration/execution.rb +0 -142
  68. data/lib/capistrano/configuration/loading.rb +0 -205
  69. data/lib/capistrano/configuration/log_formatters.rb +0 -75
  70. data/lib/capistrano/configuration/namespaces.rb +0 -223
  71. data/lib/capistrano/configuration/roles.rb +0 -83
  72. data/lib/capistrano/configuration/variables.rb +0 -127
  73. data/lib/capistrano/errors.rb +0 -19
  74. data/lib/capistrano/ext/multistage.rb +0 -67
  75. data/lib/capistrano/ext/string.rb +0 -5
  76. data/lib/capistrano/extensions.rb +0 -57
  77. data/lib/capistrano/fix_rake_deprecated_dsl.rb +0 -8
  78. data/lib/capistrano/logger.rb +0 -166
  79. data/lib/capistrano/processable.rb +0 -55
  80. data/lib/capistrano/recipes/compat.rb +0 -32
  81. data/lib/capistrano/recipes/deploy/assets.rb +0 -202
  82. data/lib/capistrano/recipes/deploy/dependencies.rb +0 -44
  83. data/lib/capistrano/recipes/deploy/local_dependency.rb +0 -54
  84. data/lib/capistrano/recipes/deploy/remote_dependency.rb +0 -117
  85. data/lib/capistrano/recipes/deploy/scm/accurev.rb +0 -169
  86. data/lib/capistrano/recipes/deploy/scm/base.rb +0 -200
  87. data/lib/capistrano/recipes/deploy/scm/bzr.rb +0 -86
  88. data/lib/capistrano/recipes/deploy/scm/cvs.rb +0 -153
  89. data/lib/capistrano/recipes/deploy/scm/darcs.rb +0 -96
  90. data/lib/capistrano/recipes/deploy/scm/git.rb +0 -299
  91. data/lib/capistrano/recipes/deploy/scm/mercurial.rb +0 -137
  92. data/lib/capistrano/recipes/deploy/scm/none.rb +0 -55
  93. data/lib/capistrano/recipes/deploy/scm/perforce.rb +0 -152
  94. data/lib/capistrano/recipes/deploy/scm/subversion.rb +0 -121
  95. data/lib/capistrano/recipes/deploy/scm.rb +0 -19
  96. data/lib/capistrano/recipes/deploy/strategy/base.rb +0 -92
  97. data/lib/capistrano/recipes/deploy/strategy/checkout.rb +0 -20
  98. data/lib/capistrano/recipes/deploy/strategy/copy.rb +0 -338
  99. data/lib/capistrano/recipes/deploy/strategy/export.rb +0 -20
  100. data/lib/capistrano/recipes/deploy/strategy/remote.rb +0 -52
  101. data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +0 -57
  102. data/lib/capistrano/recipes/deploy/strategy/unshared_remote_cache.rb +0 -21
  103. data/lib/capistrano/recipes/deploy/strategy.rb +0 -20
  104. data/lib/capistrano/recipes/deploy.rb +0 -625
  105. data/lib/capistrano/recipes/standard.rb +0 -37
  106. data/lib/capistrano/recipes/templates/maintenance.rhtml +0 -53
  107. data/lib/capistrano/role.rb +0 -102
  108. data/lib/capistrano/server_definition.rb +0 -56
  109. data/lib/capistrano/shell.rb +0 -265
  110. data/lib/capistrano/ssh.rb +0 -95
  111. data/lib/capistrano/task_definition.rb +0 -77
  112. data/lib/capistrano/transfer.rb +0 -218
  113. data/test/cli/execute_test.rb +0 -132
  114. data/test/cli/help_test.rb +0 -165
  115. data/test/cli/options_test.rb +0 -329
  116. data/test/cli/ui_test.rb +0 -28
  117. data/test/cli_test.rb +0 -17
  118. data/test/command_test.rb +0 -322
  119. data/test/configuration/actions/file_transfer_test.rb +0 -61
  120. data/test/configuration/actions/inspect_test.rb +0 -76
  121. data/test/configuration/actions/invocation_test.rb +0 -306
  122. data/test/configuration/alias_task_test.rb +0 -118
  123. data/test/configuration/callbacks_test.rb +0 -201
  124. data/test/configuration/connections_test.rb +0 -439
  125. data/test/configuration/execution_test.rb +0 -175
  126. data/test/configuration/loading_test.rb +0 -148
  127. data/test/configuration/namespace_dsl_test.rb +0 -332
  128. data/test/configuration/roles_test.rb +0 -157
  129. data/test/configuration/servers_test.rb +0 -183
  130. data/test/configuration/variables_test.rb +0 -190
  131. data/test/configuration_test.rb +0 -77
  132. data/test/deploy/local_dependency_test.rb +0 -76
  133. data/test/deploy/remote_dependency_test.rb +0 -146
  134. data/test/deploy/scm/accurev_test.rb +0 -23
  135. data/test/deploy/scm/base_test.rb +0 -55
  136. data/test/deploy/scm/bzr_test.rb +0 -51
  137. data/test/deploy/scm/darcs_test.rb +0 -37
  138. data/test/deploy/scm/git_test.rb +0 -274
  139. data/test/deploy/scm/mercurial_test.rb +0 -134
  140. data/test/deploy/scm/none_test.rb +0 -35
  141. data/test/deploy/scm/perforce_test.rb +0 -23
  142. data/test/deploy/scm/subversion_test.rb +0 -68
  143. data/test/deploy/strategy/copy_test.rb +0 -360
  144. data/test/extensions_test.rb +0 -69
  145. data/test/fixtures/cli_integration.rb +0 -5
  146. data/test/fixtures/config.rb +0 -5
  147. data/test/fixtures/custom.rb +0 -3
  148. data/test/logger_formatting_test.rb +0 -149
  149. data/test/logger_test.rb +0 -134
  150. data/test/recipes_test.rb +0 -25
  151. data/test/role_test.rb +0 -11
  152. data/test/server_definition_test.rb +0 -121
  153. data/test/shell_test.rb +0 -96
  154. data/test/ssh_test.rb +0 -113
  155. data/test/task_definition_test.rb +0 -117
  156. data/test/transfer_test.rb +0 -168
  157. data/test/utils.rb +0 -37
  158. data/test/version_test.rb +0 -11
@@ -1,53 +0,0 @@
1
-
2
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
3
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4
-
5
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
6
-
7
- <head>
8
- <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
9
- <title>System down for maintenance</title>
10
-
11
- <style type="text/css">
12
- div.outer {
13
- position: absolute;
14
- left: 50%;
15
- top: 50%;
16
- width: 500px;
17
- height: 300px;
18
- margin-left: -260px;
19
- margin-top: -150px;
20
- }
21
-
22
- .DialogBody {
23
- margin: 0;
24
- padding: 10px;
25
- text-align: left;
26
- border: 1px solid #ccc;
27
- border-right: 1px solid #999;
28
- border-bottom: 1px solid #999;
29
- background-color: #fff;
30
- }
31
-
32
- body { background-color: #fff; }
33
- </style>
34
- </head>
35
-
36
- <body>
37
-
38
- <div class="outer">
39
- <div class="DialogBody" style="text-align: center;">
40
- <div style="text-align: center; width: 200px; margin: 0 auto;">
41
- <p style="color: red; font-size: 16px; line-height: 20px;">
42
- The system is down for <%= reason ? reason : "maintenance" %>
43
- as of <%= Time.now.strftime("%H:%M %Z") %>.
44
- </p>
45
- <p style="color: #666;">
46
- It'll be back <%= deadline ? deadline : "shortly" %>.
47
- </p>
48
- </div>
49
- </div>
50
- </div>
51
-
52
- </body>
53
- </html>
@@ -1,102 +0,0 @@
1
- module Capistrano
2
- class Role
3
- include Enumerable
4
-
5
- def initialize(*list)
6
- @static_servers = []
7
- @dynamic_servers = []
8
- push(*list)
9
- end
10
-
11
- def each(&block)
12
- servers.each &block
13
- end
14
-
15
- def push(*list)
16
- options = list.last.is_a?(Hash) ? list.pop : {}
17
- list.each do |item|
18
- if item.respond_to?(:call)
19
- @dynamic_servers << DynamicServerList.new(item, options)
20
- else
21
- @static_servers << self.class.wrap_server(item, options)
22
- end
23
- end
24
- end
25
- alias_method :<<, :push
26
-
27
- def servers
28
- @static_servers + dynamic_servers
29
- end
30
- alias_method :to_ary, :servers
31
-
32
- def empty?
33
- servers.empty?
34
- end
35
-
36
- def clear
37
- @dynamic_servers.clear
38
- @static_servers.clear
39
- end
40
-
41
- def include?(server)
42
- servers.include?(server)
43
- end
44
-
45
- protected
46
-
47
- # This is the combination of a block, a hash of options, and a cached value.
48
- class DynamicServerList
49
- def initialize (block, options)
50
- @block = block
51
- @options = options
52
- @cached = []
53
- @is_cached = false
54
- end
55
-
56
- # Convert to a list of ServerDefinitions
57
- def to_ary
58
- unless @is_cached
59
- @cached = Role::wrap_list(@block.call(@options), @options)
60
- @is_cached = true
61
- end
62
- @cached
63
- end
64
-
65
- # Clear the cached value
66
- def reset!
67
- @cached.clear
68
- @is_cached = false
69
- end
70
- end
71
-
72
- # Attribute reader for the cached results of executing the blocks in turn
73
- def dynamic_servers
74
- @dynamic_servers.inject([]) { |list, item| list.concat item }
75
- end
76
-
77
- # Wraps a string in a ServerDefinition, if it isn't already.
78
- # This and wrap_list should probably go in ServerDefinition in some form.
79
- def self.wrap_server (item, options)
80
- item.is_a?(ServerDefinition) ? item : ServerDefinition.new(item, options)
81
- end
82
-
83
- # Turns a list, or something resembling a list, into a properly-formatted
84
- # ServerDefinition list. Keep an eye on this one -- it's entirely too
85
- # magical for its own good. In particular, if ServerDefinition ever inherits
86
- # from Array, this will break.
87
- def self.wrap_list (*list)
88
- options = list.last.is_a?(Hash) ? list.pop : {}
89
- if list.length == 1
90
- if list.first.nil?
91
- return []
92
- elsif list.first.is_a?(Array)
93
- list = list.first
94
- end
95
- end
96
- options.merge! list.pop if list.last.is_a?(Hash)
97
- list.map do |item|
98
- self.wrap_server item, options
99
- end
100
- end
101
- end
102
- end
@@ -1,56 +0,0 @@
1
- module Capistrano
2
- class ServerDefinition
3
- include Comparable
4
-
5
- attr_reader :host
6
- attr_reader :user
7
- attr_reader :port
8
- attr_reader :options
9
-
10
- # The default user name to use when a user name is not explicitly provided
11
- def self.default_user
12
- ENV['USER'] || ENV['USERNAME'] || "not-specified"
13
- end
14
-
15
- def initialize(string, options={})
16
- @user, @host, @port = string.match(/^(?:([^;,:=]+)@|)(.*?)(?::(\d+)|)$/)[1,3]
17
-
18
- @options = options.dup
19
- user_opt, port_opt = @options.delete(:user), @options.delete(:port)
20
-
21
- @user ||= user_opt
22
- @port ||= port_opt
23
-
24
- @port = @port.to_i if @port
25
- end
26
-
27
- def <=>(server)
28
- [host, port, user] <=> [server.host, server.port, server.user]
29
- end
30
-
31
- # Redefined, so that Array#uniq will work to remove duplicate server
32
- # definitions, based solely on their host names.
33
- def eql?(server)
34
- host == server.host &&
35
- user == server.user &&
36
- port == server.port
37
- end
38
-
39
- alias :== :eql?
40
-
41
- # Redefined, so that Array#uniq will work to remove duplicate server
42
- # definitions, based on their connection information.
43
- def hash
44
- @hash ||= [host, user, port].hash
45
- end
46
-
47
- def to_s
48
- @to_s ||= begin
49
- s = host
50
- s = "#{user}@#{s}" if user
51
- s = "#{s}:#{port}" if port && port != 22
52
- s
53
- end
54
- end
55
- end
56
- end
@@ -1,265 +0,0 @@
1
- require 'thread'
2
- require 'capistrano/processable'
3
-
4
- module Capistrano
5
- # The Capistrano::Shell class is the guts of the "shell" task. It implements
6
- # an interactive REPL interface that users can employ to execute tasks and
7
- # commands. It makes for a GREAT way to monitor systems, and perform quick
8
- # maintenance on one or more machines.
9
- class Shell
10
- include Processable
11
-
12
- # A Readline replacement for platforms where readline is either
13
- # unavailable, or has not been installed.
14
- class ReadlineFallback #:nodoc:
15
- HISTORY = []
16
-
17
- def self.readline(prompt)
18
- STDOUT.print(prompt)
19
- STDOUT.flush
20
- STDIN.gets
21
- end
22
- end
23
-
24
- # The configuration instance employed by this shell
25
- attr_reader :configuration
26
-
27
- # Instantiate a new shell and begin executing it immediately.
28
- def self.run(config)
29
- new(config).run!
30
- end
31
-
32
- # Instantiate a new shell
33
- def initialize(config)
34
- @configuration = config
35
- end
36
-
37
- # Start the shell running. This method will block until the shell
38
- # terminates.
39
- def run!
40
- setup
41
-
42
- puts <<-INTRO
43
- ====================================================================
44
- Welcome to the interactive Capistrano shell! This is an experimental
45
- feature, and is liable to change in future releases. Type 'help' for
46
- a summary of how to use the shell.
47
- --------------------------------------------------------------------
48
- INTRO
49
-
50
- loop do
51
- break if !read_and_execute
52
- end
53
-
54
- @bgthread.kill
55
- end
56
-
57
- def read_and_execute
58
- command = read_line
59
-
60
- case command
61
- when "?", "help" then help
62
- when "quit", "exit" then
63
- puts "exiting"
64
- return false
65
- when /^set -(\w)\s*(\S+)/
66
- set_option($1, $2)
67
- when /^set :(.*)\s+(.*)/
68
- configuration.set($1.to_sym, $2)
69
- puts "updated :#{$1} to #{$2}"
70
- when /^(?:(with|on)\s*(\S+))?\s*(\S.*)?/i
71
- process_command($1, $2, $3)
72
- else
73
- raise "eh?"
74
- end
75
-
76
- return true
77
- end
78
-
79
- private
80
-
81
- # Present the prompt and read a single line from the console. It also
82
- # detects ^D and returns "exit" in that case. Adds the input to the
83
- # history, unless the input is empty. Loops repeatedly until a non-empty
84
- # line is input.
85
- def read_line
86
- loop do
87
- command = reader.readline("cap> ")
88
-
89
- if command.nil?
90
- command = "exit"
91
- puts(command)
92
- else
93
- command.strip!
94
- end
95
-
96
- unless command.empty?
97
- reader::HISTORY << command
98
- return command
99
- end
100
- end
101
- end
102
-
103
- # Display a verbose help message.
104
- def help
105
- puts <<-HELP
106
- --- HELP! ---------------------------------------------------
107
- "Get me out of this thing. I just want to quit."
108
- -> Easy enough. Just type "exit", or "quit". Or press ctrl-D.
109
-
110
- "I want to execute a command on all servers."
111
- -> Just type the command, and press enter. It will be passed,
112
- verbatim, to all defined servers.
113
-
114
- "What if I only want it to execute on a subset of them?"
115
- -> No problem, just specify the list of servers, separated by
116
- commas, before the command, with the `on' keyword:
117
-
118
- cap> on app1.foo.com,app2.foo.com echo ping
119
-
120
- "Nice, but can I specify the servers by role?"
121
- -> You sure can. Just use the `with' keyword, followed by the
122
- comma-delimited list of role names:
123
-
124
- cap> with app,db echo ping
125
-
126
- "Can I execute a Capistrano task from within this shell?"
127
- -> Yup. Just prefix the task with an exclamation mark:
128
-
129
- cap> !deploy
130
- HELP
131
- end
132
-
133
- # Determine which servers the given task requires a connection to, and
134
- # establish connections to them if necessary. Return the list of
135
- # servers (names).
136
- def connect(task)
137
- servers = configuration.find_servers_for_task(task)
138
- needing_connections = servers - configuration.sessions.keys
139
- unless needing_connections.empty?
140
- puts "[establishing connection(s) to #{needing_connections.join(', ')}]"
141
- configuration.establish_connections_to(needing_connections)
142
- end
143
- servers
144
- end
145
-
146
- # Execute the given command. If the command is prefixed by an exclamation
147
- # mark, it is assumed to refer to another capistrano task, which will
148
- # be invoked. Otherwise, it is executed as a command on all associated
149
- # servers.
150
- def exec(command)
151
- @mutex.synchronize do
152
- if command[0] == ?!
153
- exec_tasks(command[1..-1].split)
154
- else
155
- servers = connect(configuration.current_task)
156
- exec_command(command, servers)
157
- end
158
- end
159
- ensure
160
- STDOUT.flush
161
- end
162
-
163
- # Given an array of task names, invoke them in sequence.
164
- def exec_tasks(list)
165
- list.each do |task_name|
166
- task = configuration.find_task(task_name)
167
- raise Capistrano::NoSuchTaskError, "no such task `#{task_name}'" unless task
168
- connect(task)
169
- configuration.execute_task(task)
170
- end
171
- rescue Capistrano::NoMatchingServersError, Capistrano::NoSuchTaskError => error
172
- warn "error: #{error.message}"
173
- end
174
-
175
- # Execute a command on the given list of servers.
176
- def exec_command(command, servers)
177
- command = command.gsub(/^(\s*)sudo\b|([|;&])\s*sudo\b/, "\\0 -p '#{configuration.sudo_prompt}'")
178
- processor = configuration.sudo_behavior_callback(Configuration.default_io_proc)
179
- sessions = servers.map { |server| configuration.sessions[server] }
180
- options = configuration.add_default_command_options({})
181
- cmd = Command.new(command, sessions, options.merge(:logger => configuration.logger), &processor)
182
- previous = trap("INT") { cmd.stop! }
183
- cmd.process!
184
- rescue Capistrano::Error => error
185
- warn "error: #{error.message}"
186
- ensure
187
- trap("INT", previous)
188
- end
189
-
190
- # Return the object that will be used to query input from the console.
191
- # The returned object will quack (more or less) like Readline.
192
- def reader
193
- @reader ||= begin
194
- require 'readline'
195
- Readline
196
- rescue LoadError
197
- ReadlineFallback
198
- end
199
- end
200
-
201
- # Prepare every little thing for the shell. Starts the background
202
- # thread and generally gets things ready for the REPL.
203
- def setup
204
- configuration.logger.level = Capistrano::Logger::INFO
205
- wait_for = 0.1
206
-
207
- @mutex = Mutex.new
208
- @bgthread = Thread.new do
209
- loop do
210
- ret = @mutex.synchronize { process_iteration(wait_for) }
211
- sleep wait_for if !ret
212
- end
213
- end
214
- end
215
-
216
- # Set the given option to +value+.
217
- def set_option(opt, value)
218
- case opt
219
- when "v" then
220
- puts "setting log verbosity to #{value.to_i}"
221
- configuration.logger.level = value.to_i
222
- when "o" then
223
- case value
224
- when "vi" then
225
- puts "using vi edit mode"
226
- reader.vi_editing_mode
227
- when "emacs" then
228
- puts "using emacs edit mode"
229
- reader.emacs_editing_mode
230
- else
231
- puts "unknown -o option #{value.inspect}"
232
- end
233
- else
234
- puts "unknown setting #{opt.inspect}"
235
- end
236
- end
237
-
238
- # Process a command. Interprets the scope_type (must be nil, "with", or
239
- # "on") and the command. If no command is given, then the scope is made
240
- # effective for all subsequent commands. If the scope value is "all",
241
- # then the scope is unrestricted.
242
- def process_command(scope_type, scope_value, command)
243
- env_var = case scope_type
244
- when "with" then "ROLES"
245
- when "on" then "HOSTS"
246
- end
247
-
248
- old_var, ENV[env_var] = ENV[env_var], (scope_value == "all" ? nil : scope_value) if env_var
249
- if command
250
- begin
251
- exec(command)
252
- ensure
253
- ENV[env_var] = old_var if env_var
254
- end
255
- else
256
- puts "scoping #{scope_type} #{scope_value}"
257
- end
258
- end
259
-
260
- # All open sessions, needed to satisfy the Command::Processable include
261
- def sessions
262
- configuration.sessions.values
263
- end
264
- end
265
- end
@@ -1,95 +0,0 @@
1
- require 'net/ssh'
2
-
3
- module Capistrano
4
- # A helper class for dealing with SSH connections.
5
- class SSH
6
- # Patch an accessor onto an SSH connection so that we can record the server
7
- # definition object that defines the connection. This is useful because
8
- # the gateway returns connections whose "host" is 127.0.0.1, instead of
9
- # the host on the other side of the tunnel.
10
- module Server #:nodoc:
11
- def self.apply_to(connection, server)
12
- connection.extend(Server)
13
- connection.xserver = server
14
- connection
15
- end
16
-
17
- attr_accessor :xserver
18
- end
19
-
20
- # An abstraction to make it possible to connect to the server via public key
21
- # without prompting for the password. If the public key authentication fails
22
- # this will fall back to password authentication.
23
- #
24
- # +server+ must be an instance of ServerDefinition.
25
- #
26
- # If a block is given, the new session is yielded to it, otherwise the new
27
- # session is returned.
28
- #
29
- # If an :ssh_options key exists in +options+, it is passed to the Net::SSH
30
- # constructor. Values in +options+ are then merged into it, and any
31
- # connection information in +server+ is added last, so that +server+ info
32
- # takes precedence over +options+, which takes precendence over ssh_options.
33
- def self.connect(server, options={})
34
- connection_strategy(server, options) do |host, user, connection_options|
35
- connection = Net::SSH.start(host, user, connection_options)
36
- Server.apply_to(connection, server)
37
- end
38
- end
39
-
40
- # Abstracts the logic for establishing an SSH connection (which includes
41
- # testing for connection failures and retrying with a password, and so forth,
42
- # mostly made complicated because of the fact that some of these variables
43
- # might be lazily evaluated and try to do something like prompt the user,
44
- # which should only happen when absolutely necessary.
45
- #
46
- # This will yield the hostname, username, and a hash of connection options
47
- # to the given block, which should return a new connection.
48
- def self.connection_strategy(server, options={}, &block)
49
- methods = [ %w(publickey hostbased), %w(password keyboard-interactive) ]
50
- password_value = nil
51
-
52
- # construct the hash of ssh options that should be passed more-or-less
53
- # directly to Net::SSH. This will be the general ssh options, merged with
54
- # the server-specific ssh-options.
55
- ssh_options = (options[:ssh_options] || {}).merge(server.options[:ssh_options] || {})
56
-
57
- # load any SSH configuration files that were specified in the SSH options. This
58
- # will load from ~/.ssh/config and /etc/ssh_config by default (see Net::SSH
59
- # for details). Merge the explicitly given ssh_options over the top of the info
60
- # from the config file.
61
- ssh_options = Net::SSH.configuration_for(server.host, ssh_options.fetch(:config, true)).merge(ssh_options)
62
-
63
- # Once we've loaded the config, we don't need Net::SSH to do it again.
64
- ssh_options[:config] = false
65
-
66
- ssh_options[:verbose] = :debug if options[:verbose] && options[:verbose] > 0
67
-
68
- user = server.user || options[:user] || ssh_options[:username] ||
69
- ssh_options[:user] || ServerDefinition.default_user
70
- port = server.port || options[:port] || ssh_options[:port]
71
-
72
- # the .ssh/config file might have changed the host-name on us
73
- host = ssh_options.fetch(:host_name, server.host)
74
-
75
- ssh_options[:port] = port if port
76
-
77
- # delete these, since we've determined which username to use by this point
78
- ssh_options.delete(:username)
79
- ssh_options.delete(:user)
80
-
81
- begin
82
- connection_options = ssh_options.merge(
83
- :password => password_value,
84
- :auth_methods => ssh_options[:auth_methods] || methods.shift
85
- )
86
-
87
- yield host, user, connection_options
88
- rescue Net::SSH::AuthenticationFailed
89
- raise if methods.empty? || ssh_options[:auth_methods]
90
- password_value = options[:password]
91
- retry
92
- end
93
- end
94
- end
95
- end
@@ -1,77 +0,0 @@
1
- require 'capistrano/server_definition'
2
-
3
- module Capistrano
4
-
5
- class TaskDefinition
6
-
7
- attr_reader :name, :namespace, :options, :body, :desc, :on_error, :max_hosts
8
-
9
- def initialize(name, namespace, options={}, &block)
10
- @name, @namespace, @options = name, namespace, options
11
- @desc = @options.delete(:desc)
12
- @on_error = options.delete(:on_error)
13
- @max_hosts = options[:max_hosts] && options[:max_hosts].to_i
14
- @body = block or raise ArgumentError, "a task requires a block"
15
- @servers = nil
16
- end
17
-
18
- # Returns the task's fully-qualified name, including the namespace
19
- def fully_qualified_name
20
- @fully_qualified_name ||= begin
21
- if namespace.default_task == self
22
- namespace.fully_qualified_name
23
- else
24
- [namespace.fully_qualified_name, name].compact.join(":")
25
- end
26
- end
27
- end
28
-
29
- def name=(value)
30
- raise ArgumentError, "expected a valid task name" if !value.respond_to?(:to_sym)
31
- @name = value.to_sym
32
- end
33
-
34
- # Returns the description for this task, with newlines collapsed and
35
- # whitespace stripped. Returns the empty string if there is no
36
- # description for this task.
37
- def description(rebuild=false)
38
- @description = nil if rebuild
39
- @description ||= begin
40
- description = @desc || ""
41
-
42
- indentation = description[/\A\s+/]
43
- if indentation
44
- reformatted_description = ""
45
- description.strip.each_line do |line|
46
- line = line.chomp.sub(/^#{indentation}/, "")
47
- line = line.gsub(/#{indentation}\s*/, " ") if line[/^\S/]
48
- reformatted_description << line << "\n"
49
- end
50
- description = reformatted_description
51
- end
52
-
53
- description.strip.gsub(/\r\n/, "\n")
54
- end
55
- end
56
-
57
- # Returns the first sentence of the full description. If +max_length+ is
58
- # given, the result will be truncated if it is longer than +max_length+,
59
- # and an ellipsis appended.
60
- def brief_description(max_length=nil)
61
- brief = description[/^.*?\.(?=\s|$)/] || description
62
-
63
- if max_length && brief.length > max_length
64
- brief = brief[0,max_length-3] + "..."
65
- end
66
-
67
- brief
68
- end
69
-
70
- # Indicates whether the task wants to continue, even if a server has failed
71
- # previously
72
- def continue_on_error?
73
- @on_error == :continue
74
- end
75
-
76
- end
77
- end