rye 0.9.7 → 0.9.8

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.
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.9.8
@@ -0,0 +1,20 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDNjCCAh6gAwIBAgIBADANBgkqhkiG9w0BAQUFADBBMQ8wDQYDVQQDDAZkZWxh
3
+ bm8xGTAXBgoJkiaJk/IsZAEZFglzb2x1dGlvdXMxEzARBgoJkiaJk/IsZAEZFgNj
4
+ b20wHhcNMTMwMjA2MTE1NzQ1WhcNMTQwMjA2MTE1NzQ1WjBBMQ8wDQYDVQQDDAZk
5
+ ZWxhbm8xGTAXBgoJkiaJk/IsZAEZFglzb2x1dGlvdXMxEzARBgoJkiaJk/IsZAEZ
6
+ FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDg1hMtl0XsMuUK
7
+ AKTgYWv3gjj7vuEsE2EjT+vyBg8/LpqVVwZziiaebJT9IZiQ+sCFqbiakj0b53pI
8
+ hg1yOaBEmH6/W0L7rwzqaRV9sW1eJs9JxFYQCnd67zUnzj8nnRlOjG+hhIG+Vsij
9
+ npsGbt28pefuNZJjO5q2clAlfSniIIHfIsU7/StEYu6FUGOjnwryZ0r5yJlr9RrE
10
+ Gs+q0DW8QnZ9UpAfuDFQZuIqeKQFFLE7nMmCGaA+0BN1nLl3fVHNbLHq7Avk8+Z+
11
+ ZuuvkdscbHlO/l+3xCNQ5nUnHwq0ADAbMLOlmiYYzqXoWLjmeI6me/clktJCfN2R
12
+ oZG3UQvvAgMBAAGjOTA3MAkGA1UdEwQCMAAwHQYDVR0OBBYEFMSJOEtHzE4l0azv
13
+ M0JK0kKNToK1MAsGA1UdDwQEAwIEsDANBgkqhkiG9w0BAQUFAAOCAQEAtOdE73qx
14
+ OH2ydi9oT2hS5f9G0y1Z70Tlwh+VGExyfxzVE9XwC+iPpJxNraiHYgF/9/oky7ZZ
15
+ R9q0/tJneuhAenZdiQkX7oi4O3v9wRS6YHoWBxMPFKVRLNTzvVJsbmfpCAlp5/5g
16
+ ps4wQFy5mibElGVlOobf/ghqZ25HS9J6kd0/C/ry0AUtTogsL7TxGwT4kbCx63ub
17
+ 3vywEEhsJUzfd97GCABmtQfRTldX/j7F1z/5wd8p+hfdox1iibds9ZtfaZA3KzKn
18
+ kchWN9B6zg9r1XMQ8BM2Jz0XoPanPe354+lWwjpkRKbFow/ZbQHcCLCq24+N6b6g
19
+ dgKfNDzwiDpqCA==
20
+ -----END CERTIFICATE-----
data/lib/rye.rb CHANGED
@@ -1,5 +1,11 @@
1
1
  # vim: set sw=2 ts=2 :
2
2
 
3
+ module Rye
4
+ unless defined?(Rye::HOME)
5
+ HOME = File.expand_path( File.join(File.dirname(__FILE__), '..') )
6
+ end
7
+ end
8
+
3
9
  require 'logger'
4
10
  require 'thread'
5
11
  require 'base64'
@@ -19,11 +25,11 @@ require 'esc'
19
25
  #
20
26
  # Safely run remote commands via SSH in Ruby.
21
27
  #
22
- # Rye is similar to Rush[http://rush.heroku.com] but everything
28
+ # Rye is similar to Rush[http://rush.heroku.com] but everything
23
29
  # happens over SSH (no HTTP daemon) and the default settings are
24
30
  # less dangerous (for safety). For example, file globs and the
25
- # "rm" command are disabled so unless otherwise specified, you
26
- # can't do this: <tt>rbox.rm('/etc/**/*')</tt>.
31
+ # "rm" command are disabled so unless otherwise specified, you
32
+ # can't do this: <tt>rbox.rm('/etc/**/*')</tt>.
27
33
  #
28
34
  # However, you can do this:
29
35
  #
@@ -31,7 +37,7 @@ require 'esc'
31
37
  # rset.add_boxes('host1', 'host2', 'host3', 'host4')
32
38
  # rset.ps('aux')
33
39
  #
34
- # * See +bin/try+ for a bunch of working examples.
40
+ # * See +bin/try+ for a bunch of working examples.
35
41
  # * See Rye::Box#initialize for info about disabling safe-mode.
36
42
  #
37
43
  #--
@@ -42,22 +48,38 @@ require 'esc'
42
48
  #++
43
49
  module Rye
44
50
  extend self
45
-
46
- VERSION = "0.9.7".freeze unless defined?(VERSION)
47
-
51
+
52
+ module VERSION
53
+ @path = File.join(Rye::HOME, 'VERSION')
54
+ class << self
55
+ attr_reader :version, :path
56
+ def version
57
+ @version || read_version
58
+ end
59
+ def read_version
60
+ return if @version
61
+ @version = File.read(path).strip!
62
+ end
63
+ def prerelease?() false end
64
+ def to_a() version.split('.') end
65
+ def to_s() version end
66
+ def inspect() version end
67
+ end
68
+ end
69
+
48
70
  @@sysinfo = nil
49
71
  @@agent_env = Hash.new # holds ssh-agent env vars
50
72
  @@mutex = Mutex.new # for synchronizing threads
51
-
73
+
52
74
  # Accessor for an instance of SystemInfo
53
75
  def Rye.sysinfo
54
76
  @@sysinfo = SysInfo.new if @@sysinfo.nil?
55
77
  @@sysinfo
56
78
  end
57
-
79
+
58
80
  # Accessor for an instance of SystemInfo
59
81
  def sysinfo; Rye.sysinfo end
60
-
82
+
61
83
  class RyeError < RuntimeError; end
62
84
  class NoBoxes < RyeError; end
63
85
  class NoPassword < RyeError
@@ -82,19 +104,19 @@ module Rye
82
104
  def stdout; @rap.stdout if @rap; end
83
105
  def exit_status; @rap.exit_status if @rap; end
84
106
  end
85
-
86
- # Reload Rye dynamically. Useful with irb.
87
- # NOTE: does not reload rye.rb.
107
+
108
+ # Reload Rye dynamically. Useful with irb.
109
+ # NOTE: does not reload rye.rb.
88
110
  def reload
89
111
  pat = File.join(File.dirname(__FILE__), 'rye')
90
112
  %w{key rap cmd box set hop}.each {|lib| load File.join(pat, "#{lib}.rb") }
91
113
  end
92
-
114
+
93
115
  def mutex
94
116
  @@mutex
95
117
  end
96
-
97
- # Looks for private keys in +path+ and returns and Array of paths
118
+
119
+ # Looks for private keys in +path+ and returns an Array of paths
98
120
  # to the files it finds. Raises an Exception if path does not exist.
99
121
  # If path is a file rather than a directory, it will check whether
100
122
  # that single file is a private key.
@@ -105,12 +127,12 @@ module Rye
105
127
  else
106
128
  files = [path]
107
129
  end
108
-
130
+
109
131
  files = files.select do |file|
110
132
  next if File.directory?(file)
111
133
  pk = nil
112
134
  begin
113
- tmp = Rye::Key.from_file(file)
135
+ tmp = Rye::Key.from_file(file)
114
136
  pk = tmp if tmp.private?
115
137
  rescue OpenSSL::PKey::PKeyError
116
138
  end
@@ -118,15 +140,15 @@ module Rye
118
140
  end
119
141
  files || []
120
142
  end
121
-
122
- # Add one or more private keys to the SSH Agent.
123
- # * +keys+ one or more file paths to private keys used for passwordless logins.
143
+
144
+ # Add one or more private keys to the SSH Agent.
145
+ # * +keys+ one or more file paths to private keys used for passwordless logins.
124
146
  def add_keys(*keys)
125
147
  keys = keys.flatten.compact || []
126
148
  return if keys.empty?
127
149
  Rye.shell("ssh-add", keys)
128
150
  end
129
-
151
+
130
152
  # Returns an Array of info about the currently available
131
153
  # SSH keys, as provided by the SSH Agent.
132
154
  #
@@ -142,25 +164,25 @@ module Rye
142
164
  #end
143
165
  Dir.glob(File.join(Rye.sysinfo.home, '.ssh', 'id_*sa'))
144
166
  end
145
-
167
+
146
168
  def remote_host_keys(*hostnames)
147
169
  hostnames = hostnames.flatten.compact || []
148
170
  return if hostnames.empty?
149
171
  Rye.shell("ssh-keyscan", hostnames)
150
172
  end
151
-
152
- # Takes a command with arguments and returns it in a
153
- # single String with escaped args and some other stuff.
154
- #
173
+
174
+ # Takes a command with arguments and returns it in a
175
+ # single String with escaped args and some other stuff.
176
+ #
155
177
  # * +cmd+ The shell command name or absolute path.
156
- # * +args+ an Array of command arguments.
178
+ # * +args+ an Array of command arguments.
157
179
  #
158
180
  # The command is searched for in the local PATH (where
159
181
  # Rye is running). An exception is raised if it's not
160
182
  # found. NOTE: Because this happens locally, you won't
161
183
  # want to use this method if the environment is quite
162
184
  # different from the remote machine it will be executed
163
- # on.
185
+ # on.
164
186
  #
165
187
  # The command arguments are passed through Escape.shell_command
166
188
  # (that means you can't use environment variables or asterisks).
@@ -177,32 +199,32 @@ module Rye
177
199
  end
178
200
  Rye.escape(@safe, found_cmd, *args)
179
201
  end
180
-
181
- # An all ruby implementation of unix "which" command.
202
+
203
+ # An all ruby implementation of unix "which" command.
182
204
  #
183
205
  # * +executable+ the name of the executable
184
- #
206
+ #
185
207
  # Returns the absolute path if found in PATH otherwise nil.
186
208
  def which(executable)
187
209
  return unless executable.is_a?(String)
188
210
  return executable if Rye.sysinfo.os == :windows
189
211
  #return executable if File.exists?(executable) # SHOULD WORK, MUST TEST
190
212
  shortname = File.basename(executable)
191
- dir = Rye.sysinfo.paths.select do |path| # dir contains all of the
192
- next unless File.exists? path # occurrences of shortname
193
- Dir.new(path).entries.member?(shortname) # found in the paths.
213
+ dir = Rye.sysinfo.paths.select do |path| # dir contains all of the
214
+ next unless File.exists? path # occurrences of shortname
215
+ Dir.new(path).entries.member?(shortname) # found in the paths.
194
216
  end
195
217
  File.join(dir.first, shortname) unless dir.empty? # Return just the first
196
218
  end
197
-
219
+
198
220
  # Execute a local system command (via the shell, not SSH)
199
- #
221
+ #
200
222
  # * +cmd+ the executable path (relative or absolute)
201
223
  # * +args+ Array of arguments to be sent to the command. Each element
202
224
  # is one argument:. i.e. <tt>['-l', 'some/path']</tt>
203
225
  #
204
226
  # NOTE: shell is a bit paranoid so it escapes every argument. This means
205
- # you can only use literal values. That means no asterisks too.
227
+ # you can only use literal values. That means no asterisks too.
206
228
  #
207
229
  # Returns a Rye::Rap object.
208
230
  #
@@ -227,27 +249,27 @@ module Rye
227
249
  rap.add_exit_status($?)
228
250
  rap
229
251
  end
230
-
252
+
231
253
  # Creates a string from +cmd+ and +args+. If +safe+ is true
232
- # it will send them through Escape.shell_command otherwise
233
- # it will return them joined by a space character.
254
+ # it will send them through Escape.shell_command otherwise
255
+ # it will return them joined by a space character.
234
256
  def escape(safe, cmd, *args)
235
257
  args = args.flatten.compact || []
236
258
  safe ? Escape.shell_command(cmd, *args).to_s : [cmd, args].flatten.compact.join(' ')
237
259
  end
238
-
260
+
239
261
  def sshagent_info
240
262
  @@agent_env
241
263
  end
242
-
243
- # Returns +str+ with the leading indentation removed.
264
+
265
+ # Returns +str+ with the leading indentation removed.
244
266
  # Stolen from http://github.com/mynyml/unindent/ because it was better.
245
267
  def without_indent(str)
246
268
  indent = str.split($/).each {|line| !line.strip.empty? }.map {|line| line.index(/[^\s]/) }.compact.min
247
269
  str.gsub(/^[[:blank:]]{#{indent}}/, '')
248
270
  end
249
-
250
- #
271
+
272
+ #
251
273
  # Generates a string of random alphanumeric characters.
252
274
  # * +len+ is the length, an Integer. Default: 8
253
275
  # * +safe+ in safe-mode, ambiguous characters are removed (default: true):
@@ -259,7 +281,7 @@ module Rye
259
281
  1.upto(len) { |i| str << chars[rand(chars.size-1)] }
260
282
  str
261
283
  end
262
-
284
+
263
285
  class Tpl
264
286
  attr_reader :src, :result, :basename
265
287
  def initialize(src, basename='rye-template')
@@ -286,13 +308,13 @@ module Rye
286
308
  end
287
309
  def to_s() src end
288
310
  end
289
-
290
- private
291
-
311
+
312
+ private
313
+
292
314
  Rye.reload
293
-
315
+
294
316
  end
295
317
 
296
318
 
297
319
 
298
-
320
+
@@ -106,6 +106,7 @@ module Rye
106
106
  # * :password => the user's password (ignored if there's a valid private key)
107
107
  # * :templates => the template engine to use for uploaded files. One of: :erb (default)
108
108
  # * :sudo => Run all commands via sudo (default: false)
109
+ # * :password_prompt => Show a password prompt on auth failure (default: true)
109
110
  #
110
111
  # NOTE: +opts+ can also contain any parameter supported by
111
112
  # Net::SSH.start that is not already mentioned above.
@@ -132,7 +133,8 @@ module Rye
132
133
  :error => STDERR,
133
134
  :getenv => true,
134
135
  :templates => :erb,
135
- :quiet => false
136
+ :quiet => false,
137
+ :password_prompt => true
136
138
  }.merge(opts)
137
139
 
138
140
  # Close the SSH session before Ruby exits. This will do nothing
@@ -150,8 +152,9 @@ module Rye
150
152
  @rye_ostype, @rye_impltype = @rye_opts.delete(:ostype), @rye_opts.delete(:impltype)
151
153
  @rye_quiet, @rye_sudo = @rye_opts.delete(:quiet), @rye_opts.delete(:sudo)
152
154
  @rye_templates = @rye_opts.delete(:templates)
153
-
154
- # Store the state of the terminal
155
+ @rye_password_prompt = @rye_opts.delete(:password_prompt)
156
+
157
+ # Store the state of the terminal
155
158
  @rye_stty_save = `stty -g`.chomp rescue nil
156
159
 
157
160
  unless @rye_templates.nil?
@@ -684,7 +687,7 @@ module Rye
684
687
  # only auth method
685
688
  if @rye_opts[:auth_methods] == ["publickey"]
686
689
  raise Net::SSH::AuthenticationFailed
687
- elsif STDIN.tty? && retried <= 3
690
+ elsif @rye_password_prompt && (STDIN.tty? && retried <= 3)
688
691
  STDERR.puts "Passwordless login failed for #{@rye_user}"
689
692
  @rye_opts[:password] = highline.ask("Password: ") { |q| q.echo = '' }.strip
690
693
  @rye_opts[:auth_methods].push *['keyboard-interactive', 'password']
@@ -0,0 +1,100 @@
1
+ require 'docile'
2
+
3
+ module Rye
4
+ class Set
5
+ def run cmd
6
+ instance_eval &@@command[cmd]
7
+ end
8
+ end
9
+ end
10
+
11
+ @hosts, @hostsets, @contexts = {}, {}, {}
12
+ @parallel = nil
13
+
14
+ @@colors = false || ENV['COLORS'] || ENV['TERM'].match(/.*color.*/)
15
+ @@command = {}
16
+
17
+ def parallel state; @parallel = state; end
18
+ def colors state; @@colors = state; end
19
+
20
+ def host(hostname, *args, &block)
21
+ @hosts[hostname] = Rye::Box.new(hostname, *args) unless @hosts.key? hostname
22
+ Docile.dsl_eval(Rye::Set.new.add_box(@hosts[hostname]), &block) if block_given?
23
+ end
24
+
25
+ def hostset(setname, *args, &block)
26
+ @hostsets[setname] = Rye::Set.new(setname) unless @hostsets.key? setname
27
+ args.each do |host|
28
+ @hosts[host] = Rye::Box.new(host) unless @hosts.key? host
29
+ @hostsets[setname].add_box @hosts[host] unless @hostsets[setname].boxes.include? @hosts[host]
30
+ end
31
+ if @parallel
32
+ @hostsets[setname].parallel = true
33
+ Docile.dsl_eval(@hostsets[setname], &block) if block_given?
34
+ else
35
+ @hostsets[setname].boxes.each do |host|
36
+ Docile.dsl_eval(Rye::Set.new.add_box(host), &block) if block_given?
37
+ end
38
+ end
39
+ end
40
+
41
+ def command_group(name, &block)
42
+ @@command[name] = Proc.new &block
43
+ end
44
+
45
+ def exit_status_check(cmd, opts={})
46
+ enable_quiet_mode
47
+ @pass = opts[:pass_str] || cmd.to_s + ' Passed Status Check'
48
+ @fail = opts[:fail_str] || cmd.to_s + ' Failed Status Check'
49
+ def results(obj, out)
50
+ if obj.exit_status == 0
51
+ info out, :altstring => @pass
52
+ else
53
+ err out, :altstring => @fail
54
+ end
55
+ end
56
+ out = execute cmd
57
+ if out[0].class == Rye::Rap
58
+ out.each do |rap|
59
+ results(rap, out)
60
+ end
61
+ elsif out.exit_status == 0
62
+ results(out, out)
63
+ end
64
+ disable_quiet_mode
65
+ end
66
+
67
+ def strwrap(msg, opts={})
68
+ out = ''
69
+ unless @@colors
70
+ msg.each do |str|
71
+ unless opts.key? :altstring
72
+ out += str.to_s.gsub!(/^/, "[#{str.obj.hostname}] ") + "\n"
73
+ else
74
+ out += "[#{str.obj.hostname}] #{opts[:altstring]}\n"
75
+ end
76
+ end
77
+ else
78
+ msg.each do |str|
79
+ unless opts.key? :altstring
80
+ out += str.to_s.gsub!(/^(.*)$/, str.obj.hostname)
81
+ else
82
+ out += "#{str.obj.hostname} " + opts[:altstring]
83
+ end
84
+ end
85
+ end
86
+ out
87
+ end
88
+
89
+ def info msg, *opts
90
+ STDOUT.puts strwrap(msg, *opts)
91
+ end
92
+
93
+ def err msg, *opts
94
+ STDOUT.puts strwrap(msg, *opts)
95
+ end
96
+
97
+ def debug msg, *opts
98
+ STDOUT.puts strwrap(msg, *opts)
99
+ end
100
+
@@ -1,61 +1,101 @@
1
- @spec = Gem::Specification.new do |s|
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
2
7
  s.name = "rye"
3
- s.rubyforge_project = "rye"
4
- s.version = "0.9.7"
5
- s.summary = "Rye: Safely run SSH commands on a bunch of machines at the same time (from Ruby)."
6
- s.description = s.summary
7
- s.author = "Delano Mandelbaum"
8
+ s.version = "0.9.8"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Delano Mandelbaum"]
12
+ s.cert_chain = ["gem-public_cert.pem"]
13
+ s.date = "2013-02-06"
14
+ s.description = "Run SSH commands on a bunch of machines at the same time (from Ruby)."
8
15
  s.email = "delano@solutious.com"
9
- s.homepage = "http://github.com/delano/rye/"
10
-
11
- # = DEPENDENCIES =
12
- # Add all gem dependencies
13
- s.add_dependency 'annoy'
14
- s.add_dependency 'sysinfo', '>= 0.7.3'
15
-
16
- s.add_dependency 'highline', '>= 1.5.1'
17
- s.add_dependency 'net-ssh', '>= 2.0.13'
18
- s.add_dependency 'net-scp', '>= 1.0.2'
19
- #s.add_dependency 'net-ssh-multi'
20
-
21
- # = EXECUTABLES =
22
- # The list of executables in your project (if any). Don't include the path,
23
- # just the base filename.
24
- s.executables = %w[]
25
-
26
- # = MANIFEST =
27
- # The complete list of files to be included in the release. When GitHub packages your gem,
28
- # it doesn't allow you to run any command that accesses the filesystem. You will get an
29
- # error. You can ask your VCS for the list of versioned files:
30
- # git ls-files
31
- # svn list -R
32
- s.files = %w(
33
- CHANGES.txt
34
- LICENSE.txt
35
- README.rdoc
36
- Rakefile
37
- Rudyfile
38
- bin/try
39
- lib/esc.rb
40
- lib/rye.rb
41
- lib/rye/box.rb
42
- lib/rye/cmd.rb
43
- lib/rye/key.rb
44
- lib/rye/rap.rb
45
- lib/rye/set.rb
46
- lib/rye/hop.rb
47
- rye.gemspec
48
- )
49
-
50
- s.extra_rdoc_files = %w[README.rdoc LICENSE.txt]
51
- s.has_rdoc = true
52
- s.rdoc_options = ["--line-numbers", "--title", s.summary, "--main", "README.rdoc"]
53
- s.require_paths = %w[lib]
54
- s.rubygems_version = '1.3.0'
16
+ s.extra_rdoc_files = [
17
+ "LICENSE.txt",
18
+ "README.rdoc"
19
+ ]
20
+ s.files = [
21
+ "CHANGES.txt",
22
+ "LICENSE.txt",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "Rudyfile",
26
+ "VERSION",
27
+ "gem-public_cert.pem",
28
+ "lib/esc.rb",
29
+ "lib/rye.rb",
30
+ "lib/rye/box.rb",
31
+ "lib/rye/cmd.rb",
32
+ "lib/rye/dsl.rb",
33
+ "lib/rye/hop.rb",
34
+ "lib/rye/key.rb",
35
+ "lib/rye/rap.rb",
36
+ "lib/rye/set.rb",
37
+ "rye.gemspec",
38
+ "try/10_basic_tryouts.rb",
39
+ "try/12_batch_tryouts.rb",
40
+ "try/13_set_tryouts.rb",
41
+ "try/14_auth_methods_tryouts.rb",
42
+ "try/15_file_tryouts.rb",
43
+ "try/20_file_transfer_tryouts.rb",
44
+ "try/25_template_upload.rb",
45
+ "try/30_safemode_tryouts.rb",
46
+ "try/35_basics_with_hop.rb",
47
+ "try/70_rye_cli_tryouts.rb",
48
+ "try/copying.rb",
49
+ "try/keys.rb",
50
+ "tst/10-key1",
51
+ "tst/10-key1.pub",
52
+ "tst/10-key2",
53
+ "tst/10-key2.pub",
54
+ "tst/10_keys_test.rb",
55
+ "tst/50_rset_test.rb",
56
+ "tst/60-file.mp3",
57
+ "tst/60_rbox_transfer_test.rb",
58
+ "tst/65_rbox_file_append_test.rb",
59
+ "tst/70_rbox_env_test.rb",
60
+ "tst/dsl_example.rb",
61
+ "tst/rye.rb",
62
+ "tst/shell.rb",
63
+ "tst/shell2.rb",
64
+ "tst/shell3.rb",
65
+ "tst/test_hop.rb"
66
+ ]
67
+ s.homepage = "https://github.com/delano/rye"
68
+ s.require_paths = ["lib"]
69
+ s.rubyforge_project = "rye"
70
+ s.rubygems_version = "1.8.25"
71
+ s.signing_key = "/mnt/gem/gem-private_key.pem"
72
+ s.summary = "Run SSH commands on a bunch of machines at the same time (from Ruby)."
55
73
 
56
74
  if s.respond_to? :specification_version then
57
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
58
- s.specification_version = 2
75
+ s.specification_version = 3
76
+
77
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
78
+ s.add_runtime_dependency(%q<annoy>, [">= 0"])
79
+ s.add_runtime_dependency(%q<sysinfo>, [">= 0.7.3"])
80
+ s.add_runtime_dependency(%q<highline>, [">= 1.5.1"])
81
+ s.add_runtime_dependency(%q<net-ssh>, [">= 2.0.13"])
82
+ s.add_runtime_dependency(%q<net-scp>, [">= 1.0.2"])
83
+ s.add_runtime_dependency(%q<docile>, [">= 1.0.1"])
84
+ else
85
+ s.add_dependency(%q<annoy>, [">= 0"])
86
+ s.add_dependency(%q<sysinfo>, [">= 0.7.3"])
87
+ s.add_dependency(%q<highline>, [">= 1.5.1"])
88
+ s.add_dependency(%q<net-ssh>, [">= 2.0.13"])
89
+ s.add_dependency(%q<net-scp>, [">= 1.0.2"])
90
+ s.add_dependency(%q<docile>, [">= 1.0.1"])
91
+ end
92
+ else
93
+ s.add_dependency(%q<annoy>, [">= 0"])
94
+ s.add_dependency(%q<sysinfo>, [">= 0.7.3"])
95
+ s.add_dependency(%q<highline>, [">= 1.5.1"])
96
+ s.add_dependency(%q<net-ssh>, [">= 2.0.13"])
97
+ s.add_dependency(%q<net-scp>, [">= 1.0.2"])
98
+ s.add_dependency(%q<docile>, [">= 1.0.1"])
59
99
  end
60
-
61
100
  end
101
+