sshkit 1.1.0 → 1.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1d240b417c873ab9f0c9e56797700ae369c9e247
4
- data.tar.gz: d254ac62cb140472b626d2aacb6f6de5d43b8c04
3
+ metadata.gz: 3898c2edc5a5a2dc313f80f0170c5511f67358ee
4
+ data.tar.gz: 2d9a40af7ea3e3f862d68c5bdc9b892f848cbbc6
5
5
  SHA512:
6
- metadata.gz: 5c5732a48ae1ea014a15012a9e9b2f4ddecf89ab9926d5d98ec91b27984ec9313bcfe8e736b70afcafac6832c094267dcc1863e6cbbc6af546b28339d8ec022b
7
- data.tar.gz: 6fff632e1d8853d80535c812cc31bf45710f5887d2135747f078fc2b642567d213717d410bb54d6e36cb37167975e24ee76899fa2a35693a99d240faeb558cc3
6
+ metadata.gz: 4d04c3dec016fdb417fb550b5f3a4d247a1d1165867e60457b5cf652d2a8b6660721a9e703442ba611c57397b1b85133ccb16b4c539f051cd9e3f251bed120e7
7
+ data.tar.gz: 7389b19eb7a6f724207d5f00b889ff3ea93f1b70b48f02a4dc9a705d1d4563c3d4f09e510bf0b6f4791a33ccf8b6dc8b2c9eab37627c389ff7ab723c6d5a4b0a
@@ -3,14 +3,35 @@
3
3
  This file is written in reverse chronological order, newer releases will
4
4
  appear at the top.
5
5
 
6
- ## 1.1.0
6
+ ## 1.2.0
7
+
8
+ * Support picking up a project local SSH config file, if a SSH config file
9
+ exists at ./.ssh/config it will be merged with the ~/.ssh/config. This is
10
+ ideal for defining project-local proxies/gateways, etc. Thanks to Alex
11
+ @0rca Vzorov.
12
+ * Tests and general improvements to the Printer backends (mostly used
13
+ internally). Thanks to Michael @miry Nikitochkin.
14
+ * Update the net-scp dependency version. Thanks again to Michael @miry
15
+ Nikitochkin.
16
+ * Improved command map. This feature allows mapped variables to be pushed
17
+ and unshifted onto the mapping so that the Capistrano extensions for
18
+ rbenv and bundler, etc can work together. For discussion about the reasoning
19
+ see https://github.com/capistrano/capistrano/issues/639 and
20
+ https://github.com/capistrano/sshkit/pull/45. A big thanks to Kir @kirs
21
+ Shatrov.
22
+ * `test()` and `capture()` now behave as expected inside a `run_locally` block
23
+ meaning that they now run on your local machine, rather than erring out. Thanks
24
+ to Kentaro @kentaroi Imai.
25
+ * The `:wait` option is now successfully passed to the runner now. Previously the
26
+ `:wait` option was ignored. Thanks to Jordan @jhollinger Hollinger for catching
27
+ the mistake in our test coverage.
28
+ * Fixes and general improvements to the `download()` method which until now was
29
+ quite naïve. Thanks to @chqr.
7
30
 
8
- * The output now reads "Command exited with status _", rather than "command
9
- failed", or "command succeded", the semantics are the same, but people
10
- were confused by "failure", when things were running correctly.
31
+ ## 1.1.0
11
32
 
12
- * Small fix to the printer backend for tests, casting command to a string
13
- explicitly.
33
+ * Please see the Git history. `git rebase` ate our changelog (we should have been
34
+ more careful)
14
35
 
15
36
  ## 1.0.0
16
37
 
@@ -222,8 +222,8 @@ which will cause the command to abort.
222
222
 
223
223
  ## Make a test, or run a command which may fail without raising an error:
224
224
 
225
- on hosts do |host
226
- if test "[ -d /opt/sites ]" do
225
+ on hosts do |host|
226
+ if test "[ -d /opt/sites ]"
227
227
  within "/opt/sites" do
228
228
  execute :git, :pull
229
229
  end
data/README.md CHANGED
@@ -142,6 +142,16 @@ One can override the hash map for individual commands:
142
142
  puts SSHKit.config.command_map[:rake]
143
143
  # => /usr/local/rbenv/shims/rake
144
144
 
145
+ Another oportunity is to add command prefixes:
146
+
147
+ SSHKit.config.command_map.prefix[:rake].push("bundle exec")
148
+ puts SSHKit.config.command_map[:rake]
149
+ # => bundle exec rake
150
+
151
+ SSHKit.config.command_map.prefix[:rake].unshift("/usr/local/rbenv/bin exec")
152
+ puts SSHKit.config.command_map[:rake]
153
+ # => /usr/local/rbenv/bin exec bundle exec rake
154
+
145
155
  One can also override the command map completely, this may not be wise, but it
146
156
  would be possible, for example:
147
157
 
@@ -4,6 +4,7 @@ require_relative '../core_ext/hash'
4
4
  require_relative 'host'
5
5
 
6
6
  require_relative 'command'
7
+ require_relative 'command_map'
7
8
  require_relative 'configuration'
8
9
  require_relative 'coordinator'
9
10
 
@@ -13,7 +13,26 @@ module SSHKit
13
13
  instance_exec(&@block)
14
14
  end
15
15
 
16
+ def test(*args)
17
+ options = args.extract_options!.merge(
18
+ raise_on_non_zero_exit: false,
19
+ verbosity: Logger::DEBUG
20
+ )
21
+ _execute(*[*args, options]).success?
22
+ end
23
+
16
24
  def execute(*args)
25
+ _execute(*args).success?
26
+ end
27
+
28
+ def capture(*args)
29
+ options = args.extract_options!.merge(verbosity: Logger::DEBUG)
30
+ _execute(*[*args, options]).full_stdout.strip
31
+ end
32
+
33
+ private
34
+
35
+ def _execute(*args)
17
36
  command(*args).tap do |cmd|
18
37
  output << cmd
19
38
 
@@ -1,6 +1,18 @@
1
1
  require 'net/ssh'
2
2
  require 'net/scp'
3
3
 
4
+ module Net
5
+ module SSH
6
+ class Config
7
+ class << self
8
+ def default_files
9
+ @@default_files + [File.join(Dir.pwd, '.ssh/config')]
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+
4
16
  module SSHKit
5
17
 
6
18
  class Logger
@@ -65,29 +77,13 @@ module SSHKit
65
77
  end
66
78
 
67
79
  def upload!(local, remote, options = {})
68
- ssh.scp.upload!(local, remote, options) do |ch, name, sent, total|
69
- percentage = (sent.to_f * 100 / total.to_f)
70
- unless percentage.nan?
71
- if percentage > 0 && percentage % 10 == 0
72
- info "Uploading #{name} #{percentage.round(2)}%"
73
- else
74
- debug "Uploading #{name} #{percentage.round(2)}%"
75
- end
76
- else
77
- warn "Error calculating percentage #{percentage} is NaN"
78
- end
79
- end
80
+ summarizer = transfer_summarizer('Uploading')
81
+ ssh.scp.upload!(local, remote, options, &summarizer)
80
82
  end
81
83
 
82
84
  def download!(remote, local=nil, options = {})
83
- ssh.scp.download!(remote, local, options) do |ch, name, received, total|
84
- percentage = (received.to_f * 100 / total.to_f).to_i
85
- if percentage > 0 && percentage % 10 == 0
86
- info "Downloading #{name} #{percentage}%"
87
- else
88
- debug "Downloading #{name} #{percentage}%"
89
- end
90
- end
85
+ summarizer = transfer_summarizer('Downloading')
86
+ ssh.scp.download!(remote, local, options, &summarizer)
91
87
  end
92
88
 
93
89
  class << self
@@ -102,6 +98,23 @@ module SSHKit
102
98
 
103
99
  private
104
100
 
101
+ def transfer_summarizer(action)
102
+ proc do |ch, name, transferred, total|
103
+ percentage = (transferred.to_f * 100 / total.to_f)
104
+ unless percentage.nan?
105
+ message = "#{action} #{name} #{percentage.round(2)}%"
106
+ if percentage > 0 && percentage.round % 10 == 0
107
+ info message
108
+ else
109
+ debug message
110
+ end
111
+ else
112
+ warn "Error calculating percentage #{transferred}/#{total}, " <<
113
+ "is #{name} empty?"
114
+ end
115
+ end
116
+ end
117
+
105
118
  def _execute(*args)
106
119
  command(*args).tap do |cmd|
107
120
  output << cmd
@@ -11,7 +11,7 @@ module SSHKit
11
11
 
12
12
  def execute(*args)
13
13
  command(*args).tap do |cmd|
14
- output << cmd.to_s
14
+ output << sprintf("%s\n", cmd)
15
15
  end
16
16
  end
17
17
  alias :upload! :execute
@@ -0,0 +1,51 @@
1
+ module SSHKit
2
+ class CommandMap
3
+ class PrefixProvider
4
+ def initialize
5
+ @storage = {}
6
+ end
7
+
8
+ def [](command)
9
+ @storage[command] ||= []
10
+
11
+ @storage[command]
12
+ end
13
+ end
14
+
15
+ def initialize(value = nil)
16
+ @map = value || defaults
17
+ end
18
+
19
+ def [](command)
20
+ if prefix[command].any?
21
+ prefixes = prefix[command].join(" ")
22
+
23
+ "#{prefixes} #{command}"
24
+ else
25
+ @map[command]
26
+ end
27
+ end
28
+
29
+ def prefix
30
+ @prefix ||= PrefixProvider.new
31
+ end
32
+
33
+ def []=(command, new_command)
34
+ @map[command] = new_command
35
+ end
36
+
37
+ def clear
38
+ @map = defaults
39
+ end
40
+
41
+ def defaults
42
+ Hash.new do |hash, command|
43
+ if %w{if test time}.include? command.to_s
44
+ hash[command] = command.to_s
45
+ else
46
+ hash[command] = "/usr/bin/env #{command}"
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -3,7 +3,7 @@ module SSHKit
3
3
  class Configuration
4
4
 
5
5
  attr_accessor :umask, :output_verbosity
6
- attr_writer :output, :backend, :default_env, :command_map
6
+ attr_writer :output, :backend, :default_env
7
7
 
8
8
  def output
9
9
  @output ||= formatter(:pretty)
@@ -30,15 +30,11 @@ module SSHKit
30
30
  end
31
31
 
32
32
  def command_map
33
- @command_map ||= begin
34
- Hash.new do |hash, command|
35
- if %w{if test time}.include? command.to_s
36
- hash[command] = command.to_s
37
- else
38
- hash[command] = "/usr/bin/env #{command}"
39
- end
40
- end
41
- end
33
+ @command_map ||= SSHKit::CommandMap.new
34
+ end
35
+
36
+ def command_map=(value)
37
+ @command_map = SSHKit::CommandMap.new(value)
42
38
  end
43
39
 
44
40
  private
@@ -18,9 +18,9 @@ module SSHKit
18
18
  when :groups then Runner::Group
19
19
  else
20
20
  raise RuntimeError, "Don't know how to handle run style #{options[:in].inspect}"
21
- end.new(hosts, &block).execute
21
+ end.new(hosts, options, &block).execute
22
22
  else
23
- Runner::Null.new(hosts, &block).execute
23
+ Runner::Null.new(hosts, options, &block).execute
24
24
  end
25
25
  end
26
26
 
@@ -29,7 +29,6 @@ module SSHKit
29
29
  HostWithUsernameAndPortParser,
30
30
  IPv6HostWithPortParser,
31
31
  HostWithUsernameParser,
32
- HostWithUsernameAndPortParser
33
32
  ].select do |p|
34
33
  p.suitable?(host_string_or_options_hash)
35
34
  end
@@ -117,16 +116,10 @@ module SSHKit
117
116
 
118
117
  end
119
118
 
120
- # @private
121
- # :nodoc:
122
- class HostWithUsernameAndPortParser < SimpleHostParser
119
+ class HostWithPortParser < SimpleHostParser
123
120
 
124
121
  def self.suitable?(host_string)
125
- !host_string.match /.*@.*\:.*/
126
- end
127
-
128
- def username
129
- @host_string.split('@').last.to_i
122
+ !host_string.match /[@|\[|\]]/
130
123
  end
131
124
 
132
125
  def port
@@ -134,25 +127,26 @@ module SSHKit
134
127
  end
135
128
 
136
129
  def hostname
137
- @host_string.split(/@|\:/)[1]
130
+ @host_string.split(':').first
138
131
  end
139
132
 
140
133
  end
141
134
 
142
- class HostWithPortParser < SimpleHostParser
143
-
135
+ # @private
136
+ # :nodoc:
137
+ class HostWithUsernameAndPortParser < SimpleHostParser
144
138
  def self.suitable?(host_string)
145
- !host_string.match /[@|\[|\]]/
139
+ host_string.match /@.*:\d+/
146
140
  end
147
-
148
- def port
149
- @host_string.split(':').last.to_i
141
+ def username
142
+ @host_string.split(/:|@/)[0]
150
143
  end
151
-
152
144
  def hostname
153
- @host_string.split(':').first
145
+ @host_string.split(/:|@/)[1]
146
+ end
147
+ def port
148
+ @host_string.split(/:|@/)[2].to_i
154
149
  end
155
-
156
150
  end
157
151
 
158
152
  # @private
@@ -188,21 +182,4 @@ module SSHKit
188
182
  end
189
183
  end
190
184
 
191
- # @private
192
- # :nodoc:
193
- class HostWithUsernameAndPortParser < SimpleHostParser
194
- def self.suitable?(host_string)
195
- host_string.match /@.*:\d+/
196
- end
197
- def username
198
- @host_string.split(/:|@/)[0]
199
- end
200
- def hostname
201
- @host_string.split(/:|@/)[1]
202
- end
203
- def port
204
- @host_string.split(/:|@/)[2].to_i
205
- end
206
- end
207
-
208
185
  end
@@ -4,10 +4,11 @@ module SSHKit
4
4
 
5
5
  class Abstract
6
6
 
7
- attr_reader :hosts, :block
7
+ attr_reader :hosts, :options, :block
8
8
 
9
- def initialize(hosts, &block)
9
+ def initialize(hosts, options = nil, &block)
10
10
  @hosts = Array(hosts)
11
+ @options = options || {}
11
12
  @block = block
12
13
  end
13
14
 
@@ -12,7 +12,7 @@ module SSHKit
12
12
  end
13
13
  private
14
14
  def wait_interval
15
- @wait_interval ||= 2
15
+ @wait_interval || options[:wait] || 2
16
16
  end
17
17
  end
18
18
 
@@ -1,3 +1,3 @@
1
1
  module SSHKit
2
- VERSION = "1.1.0"
2
+ VERSION = "1.2.0"
3
3
  end
@@ -16,9 +16,9 @@ Gem::Specification.new do |gem|
16
16
  gem.require_paths = ["lib"]
17
17
  gem.version = SSHKit::VERSION
18
18
 
19
- gem.add_dependency('net-ssh')
20
- gem.add_dependency('net-scp')
21
- gem.add_dependency('term-ansicolor')
19
+ gem.add_runtime_dependency('net-ssh')
20
+ gem.add_runtime_dependency('net-scp', '>= 1.1.2')
21
+ gem.add_runtime_dependency('term-ansicolor')
22
22
 
23
23
  gem.add_development_dependency('minitest', ['>= 2.11.3', '< 2.12.0'])
24
24
  gem.add_development_dependency('rake')
@@ -9,6 +9,14 @@ module SSHKit
9
9
  SSHKit.config.output = SSHKit::Formatter::BlackHole.new($stdout)
10
10
  end
11
11
 
12
+ def test_capture
13
+ captured_command_result = ''
14
+ Local.new do
15
+ captured_command_result = capture(:echo, 'foo')
16
+ end.run
17
+ assert_equal 'foo', captured_command_result
18
+ end
19
+
12
20
  def test_execute_raises_on_non_zero_exit_status_and_captures_stdout_and_stderr
13
21
  err = assert_raises SSHKit::Command::Failed do
14
22
  Local.new do
@@ -17,6 +25,16 @@ module SSHKit
17
25
  end
18
26
  assert_equal "echo stdout: Nothing written\necho stderr: Test capturing stderr\n", err.message
19
27
  end
28
+
29
+ def test_test
30
+ succeeded_test_result = failed_test_result = nil
31
+ Local.new do
32
+ succeeded_test_result = test('[ -d ~ ]')
33
+ failed_test_result = test('[ -f ~ ]')
34
+ end.run
35
+ assert_equal true, succeeded_test_result
36
+ assert_equal false, failed_test_result
37
+ end
20
38
  end
21
39
  end
22
40
  end
@@ -49,6 +49,10 @@ end
49
49
 
50
50
  class UnitTest < MiniTest::Unit::TestCase
51
51
 
52
+ def setup
53
+ SSHKit.reset_configuration!
54
+ end
55
+
52
56
  end
53
57
 
54
58
  class FunctionalTest < MiniTest::Unit::TestCase
@@ -12,7 +12,6 @@ module SSHKit
12
12
  backend.configure do |ssh|
13
13
  ssh.pty = true
14
14
  ssh.connection_timeout = 30
15
- ssh.connection_timeout = 30
16
15
  ssh.ssh_options = {
17
16
  keys: %w(/home/user/.ssh/id_rsa),
18
17
  forward_agent: false,
@@ -26,7 +25,31 @@ module SSHKit
26
25
  assert_equal %w(/home/user/.ssh/id_rsa), backend.config.ssh_options[:keys]
27
26
  assert_equal false, backend.config.ssh_options[:forward_agent]
28
27
  assert_equal %w(publickey password), backend.config.ssh_options[:auth_methods]
28
+
29
+ end
30
+
31
+ def test_netssh_ext
32
+ assert_includes Net::SSH::Config.default_files, "#{Dir.pwd}/.ssh/config"
33
+ end
34
+
35
+ def test_transfer_summarizer
36
+ netssh = Netssh.new(Host.new('fake'))
37
+
38
+ summarizer = netssh.send(:transfer_summarizer,'Transferring')
39
+
40
+ [
41
+ [1, 100, :debug, 'Transferring afile 1.0%'],
42
+ [1, 3, :debug, 'Transferring afile 33.33%'],
43
+ [0, 1, :debug, 'Transferring afile 0.0%'],
44
+ [1, 2, :info, 'Transferring afile 50.0%'],
45
+ [0, 0, :warn, 'percentage 0/0'],
46
+ [1023, 343, :debug, 'Transferring'],
47
+ ].each do |transferred,total,method,substring|
48
+ netssh.expects(method).with { |msg| msg.include?(substring) }
49
+ summarizer.call(nil,'afile',transferred,total)
50
+ end
29
51
  end
52
+
30
53
  end
31
54
  end
32
55
  end
@@ -12,6 +12,14 @@ module SSHKit
12
12
  end
13
13
  end
14
14
 
15
+ def backend
16
+ @backend ||= Printer
17
+ end
18
+
19
+ def teardown
20
+ @backend = nil
21
+ end
22
+
15
23
  def printer
16
24
  Printer.new(Host.new(:'example.com'), &block_to_run)
17
25
  end
@@ -26,7 +34,30 @@ module SSHKit
26
34
  printer.run
27
35
  end
28
36
  result.rewind
29
- assert_equal '/usr/bin/env ls -l /some/directory', result.read
37
+ assert_equal "/usr/bin/env ls -l /some/directory\n", result.read
38
+ end
39
+
40
+ def test_printer_respond_to_configure
41
+ assert backend.respond_to?(:configure)
42
+ end
43
+
44
+ def test_printer_any_params_config
45
+ backend.configure do |ssh|
46
+ ssh.pty = true
47
+ ssh.connection_timeout = 30
48
+ ssh.ssh_options = {
49
+ keys: %w(/home/user/.ssh/id_rsa),
50
+ forward_agent: false,
51
+ auth_methods: %w(publickey password)
52
+ }
53
+ end
54
+
55
+ assert_equal 30, backend.config.connection_timeout
56
+ assert_equal true, backend.config.pty
57
+
58
+ assert_equal %w(/home/user/.ssh/id_rsa), backend.config.ssh_options[:keys]
59
+ assert_equal false, backend.config.ssh_options[:forward_agent]
60
+ assert_equal %w(publickey password), backend.config.ssh_options[:auth_methods]
30
61
  end
31
62
 
32
63
  end
@@ -0,0 +1,40 @@
1
+ require 'helper'
2
+ require 'sshkit'
3
+
4
+ module SSHKit
5
+ class TestCommandMap < UnitTest
6
+
7
+ def setup
8
+ SSHKit.reset_configuration!
9
+ end
10
+
11
+ def test_defaults
12
+ map = CommandMap.new
13
+ assert_equal map[:rake], "/usr/bin/env rake"
14
+ assert_equal map[:test], "test"
15
+ end
16
+
17
+ def test_setter
18
+ map = CommandMap.new
19
+ map[:rake] = "/usr/local/rbenv/shims/rake"
20
+ assert_equal map[:rake], "/usr/local/rbenv/shims/rake"
21
+ end
22
+
23
+ def test_prefix
24
+ map = CommandMap.new
25
+ map.prefix[:rake].push("/home/vagrant/.rbenv/bin/rbenv exec")
26
+ map.prefix[:rake].push("bundle exec")
27
+
28
+ assert_equal map[:rake], "/home/vagrant/.rbenv/bin/rbenv exec bundle exec rake"
29
+ end
30
+
31
+ def test_prefix_unshift
32
+ map = CommandMap.new
33
+ map.prefix[:rake].push("bundle exec")
34
+ map.prefix[:rake].unshift("/home/vagrant/.rbenv/bin/rbenv exec")
35
+
36
+ assert_equal map[:rake], "/home/vagrant/.rbenv/bin/rbenv exec bundle exec rake"
37
+ end
38
+
39
+ end
40
+ end
@@ -42,11 +42,12 @@ module SSHKit
42
42
  end
43
43
 
44
44
  def test_command_map
45
+ assert_equal SSHKit.config.command_map.is_a?(SSHKit::CommandMap), true
46
+
45
47
  cm = Hash.new { |h,k| h[k] = "/opt/sites/example/current/bin #{k}"}
46
- assert_equal Hash.new, SSHKit.config.command_map
47
- assert_equal "/usr/bin/env ruby", SSHKit.config.command_map[:ruby]
48
+
48
49
  assert SSHKit.config.command_map = cm
49
- assert_equal cm, SSHKit.config.command_map
50
+ assert_equal SSHKit.config.command_map.is_a?(SSHKit::CommandMap), true
50
51
  assert_equal "/opt/sites/example/current/bin ruby", SSHKit.config.command_map[:ruby]
51
52
  end
52
53
 
@@ -6,6 +6,7 @@ module SSHKit
6
6
  class TestCoordinator < UnitTest
7
7
 
8
8
  def setup
9
+ super
9
10
  @s = String.new
10
11
  SSHKit.config.backend = SSHKit::Backend::Printer
11
12
  end
@@ -40,7 +41,7 @@ module SSHKit
40
41
  SSHKit.capture_output str do
41
42
  Coordinator.new(%w{1.example.com}).each &spy
42
43
  end
43
- assert_equal "echo 1.example.com", str.strip
44
+ assert_equal "/usr/bin/env echo 1.example.com", str.strip
44
45
  end
45
46
  end
46
47
 
@@ -60,10 +61,27 @@ module SSHKit
60
61
  assert_operator results.first.to_i, :<, results.last.to_i
61
62
  end
62
63
 
64
+ def test_the_connection_manager_can_run_things_in_sequence_with_wait
65
+ start = Time.now
66
+ SSHKit.capture_output @s do
67
+ Coordinator.new(%w{1.example.com 2.example.com}).each in: :sequence, wait: 10, &block_to_run
68
+ end
69
+ stop = Time.now
70
+ assert_operator (stop.to_i - start.to_i), :>=, 10
71
+ end
72
+
63
73
  def test_the_connection_manager_can_run_things_in_groups
64
74
  SSHKit.capture_output @s do
65
- Coordinator.new(%w{1.example.com 2.example.com 3.example.com
66
- 4.example.com 5.example.com 6.example.com}).each in: :groups, &block_to_run
75
+ Coordinator.new(
76
+ %w{
77
+ 1.example.com
78
+ 2.example.com
79
+ 3.example.com
80
+ 4.example.com
81
+ 5.example.com
82
+ 6.example.com
83
+ }
84
+ ).each in: :groups, &block_to_run
67
85
  end
68
86
  assert_equal 6, results.length
69
87
  assert_equal *results[0..1].map(&:to_i)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sshkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lee Hambley
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-17 00:00:00.000000000 Z
12
+ date: 2013-11-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: net-ssh
@@ -31,14 +31,14 @@ dependencies:
31
31
  requirements:
32
32
  - - '>='
33
33
  - !ruby/object:Gem::Version
34
- version: '0'
34
+ version: 1.1.2
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - '>='
40
40
  - !ruby/object:Gem::Version
41
- version: '0'
41
+ version: 1.1.2
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: term-ansicolor
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -219,6 +219,7 @@ files:
219
219
  - lib/sshkit/backends/printer.rb
220
220
  - lib/sshkit/backends/skipper.rb
221
221
  - lib/sshkit/command.rb
222
+ - lib/sshkit/command_map.rb
222
223
  - lib/sshkit/configuration.rb
223
224
  - lib/sshkit/coordinator.rb
224
225
  - lib/sshkit/dsl.rb
@@ -246,6 +247,7 @@ files:
246
247
  - test/unit/core_ext/test_string.rb
247
248
  - test/unit/formatters/test_pretty.rb
248
249
  - test/unit/test_command.rb
250
+ - test/unit/test_command_map.rb
249
251
  - test/unit/test_configuration.rb
250
252
  - test/unit/test_coordinator.rb
251
253
  - test/unit/test_host.rb
@@ -284,6 +286,7 @@ test_files:
284
286
  - test/unit/core_ext/test_string.rb
285
287
  - test/unit/formatters/test_pretty.rb
286
288
  - test/unit/test_command.rb
289
+ - test/unit/test_command_map.rb
287
290
  - test/unit/test_configuration.rb
288
291
  - test/unit/test_coordinator.rb
289
292
  - test/unit/test_host.rb