capistrano 2.15.11 → 3.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
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