sshkit 1.21.7 → 1.22.1

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
  SHA256:
3
- metadata.gz: 33d280d41b8674934f244cd9a094ebeb3d34dfb0d700fd172f0a3e4ed25ccd01
4
- data.tar.gz: 2f75eb42f4ffa10eaa44e1c35fdccc169f334ca4498c1864c414bfad83138a86
3
+ metadata.gz: 9678c16acec683a599b5cca548346060ba08fd5616e79109af71deac743d33f3
4
+ data.tar.gz: 6213ece3ddf070a9bf715452da5883f27eb0d3cff81bc5b8a5ccd73f4649c03d
5
5
  SHA512:
6
- metadata.gz: 4206a3850adb7e7f666e2031dba9681aef7d236e04baac0cd584f07e118babe25cbfdb49efae13419be567ce870f28ccc33d128538e462d2091a76712f9c1b12
7
- data.tar.gz: 622f95a26e026ed0842e3bd1759518303145616ed8b8348e0ebe2a8b5bac5a0c0359118258a56b538ada3a30586542c2e6aa29592a86c51b44c4e06719038bce
6
+ metadata.gz: 265bf603d9c5d7557beaf9e33270acb8e626238016f4bd892017ac4cf2afa1a3f7364612c85d10a239c93fc278a2a6fe2904011688fac78e871388b4b9249c0b
7
+ data.tar.gz: ee46c52f728b8d550182332f88c07dd8b885717afe12291248a6b5a200a3d8180dacc7de863ef3e0ee8f23c264def9dff670cd97e84eea6cfee4d8c3534d2350
@@ -7,6 +7,6 @@ jobs:
7
7
  steps:
8
8
  - uses: actions/checkout@master
9
9
  - name: Draft Release
10
- uses: toolmantim/release-drafter@v5.25.0
10
+ uses: toolmantim/release-drafter@v6.0.0
11
11
  env:
12
12
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
data/EXAMPLES.md CHANGED
@@ -121,9 +121,6 @@ on hosts do |host|
121
121
  end
122
122
  ```
123
123
 
124
- **Note:** The `upload!()` method doesn't honor the values of `as()` etc, this
125
- will be improved as the library matures, but we're not there yet.
126
-
127
124
  ## Upload a file from a stream
128
125
 
129
126
  ```ruby
@@ -148,9 +145,6 @@ end
148
145
  This spares one from having to figure out the correct escaping sequences for
149
146
  something like "echo(:cat, '...?...', '> /etc/sudoers.d/yolo')".
150
147
 
151
- **Note:** The `upload!()` method doesn't honor the values of `within()`, `as()`
152
- etc, this will be improved as the library matures, but we're not there yet.
153
-
154
148
  ## Upload a directory of files
155
149
 
156
150
  ```ruby
@@ -160,7 +154,25 @@ end
160
154
  ```
161
155
 
162
156
  In this case the `recursive: true` option mirrors the same options which are
163
- available to [`Net::{SCP,SFTP}`](http://net-ssh.github.io/net-scp/).
157
+ available to [`Net::SCP`](https://github.com/net-ssh/net-scp) and
158
+ [`Net::SFTP`](https://github.com/net-ssh/net-sftp).
159
+
160
+ ## Set the upload/download method (SCP or SFTP).
161
+
162
+ SSHKit can use SCP or SFTP for file transfers. The default is SCP, but this can be changed to SFTP per host:
163
+
164
+ ```ruby
165
+ host = SSHKit::Host.new('user@example.com')
166
+ host.transfer_method = :sftp
167
+ ```
168
+
169
+ or globally:
170
+
171
+ ```ruby
172
+ SSHKit::Backend::Netssh.configure do |ssh|
173
+ ssh.transfer_method = :sftp
174
+ end
175
+ ```
164
176
 
165
177
  ## Setting global SSH options
166
178
 
@@ -235,16 +247,16 @@ end
235
247
 
236
248
  ```ruby
237
249
  # The default format is pretty, which outputs colored text
238
- SSHKit.config.format = :pretty
250
+ SSHKit.config.use_format :pretty
239
251
 
240
252
  # Text with no coloring
241
- SSHKit.config.format = :simpletext
253
+ SSHKit.config.use_format :simpletext
242
254
 
243
255
  # Red / Green dots for each completed step
244
- SSHKit.config.format = :dot
256
+ SSHKit.config.use_format :dot
245
257
 
246
258
  # No output
247
- SSHKit.config.format = :blackhole
259
+ SSHKit.config.use_format :blackhole
248
260
  ```
249
261
 
250
262
  ## Implement a dirt-simple formatter class
@@ -254,7 +266,7 @@ module SSHKit
254
266
  module Formatter
255
267
  class MyFormatter < SSHKit::Formatter::Abstract
256
268
  def write(obj)
257
- case obj.is_a? SSHKit::Command
269
+ if obj.is_a? SSHKit::Command
258
270
  # Do something here, see the SSHKit::Command documentation
259
271
  end
260
272
  end
@@ -263,7 +275,7 @@ module SSHKit
263
275
  end
264
276
 
265
277
  # If your formatter is defined in the SSHKit::Formatter module configure with the format option:
266
- SSHKit.config.format = :myformatter
278
+ SSHKit.config.use_format :myformatter
267
279
 
268
280
  # Or configure the output directly
269
281
  SSHKit.config.output = MyFormatter.new($stdout)
data/README.md CHANGED
@@ -68,7 +68,8 @@ you can pass the `strip: false` option: `capture(:ls, '-l', strip: false)`
68
68
  ### Transferring files
69
69
 
70
70
  All backends also support the `upload!` and `download!` methods for transferring files.
71
- For the remote backend, the file is transferred with scp.
71
+ For the remote backend, the file is transferred with scp by default, but sftp is also
72
+ supported. See [EXAMPLES.md](EXAMPLES.md) for details.
72
73
 
73
74
  ```ruby
74
75
  on '1.example.com' do
@@ -1,3 +1,5 @@
1
+ require "base64"
2
+
1
3
  module SSHKit
2
4
 
3
5
  module Backend
@@ -140,4 +142,4 @@ module SSHKit
140
142
 
141
143
  end
142
144
 
143
- end
145
+ end
@@ -0,0 +1,26 @@
1
+ require "net/scp"
2
+
3
+ module SSHKit
4
+ module Backend
5
+ class Netssh < Abstract
6
+ class ScpTransfer
7
+ def initialize(ssh, summarizer)
8
+ @ssh = ssh
9
+ @summarizer = summarizer
10
+ end
11
+
12
+ def upload!(local, remote, options)
13
+ ssh.scp.upload!(local, remote, options, &summarizer)
14
+ end
15
+
16
+ def download!(remote, local, options)
17
+ ssh.scp.download!(remote, local, options, &summarizer)
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :ssh, :summarizer
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,46 @@
1
+ require "net/sftp"
2
+
3
+ module SSHKit
4
+ module Backend
5
+ class Netssh < Abstract
6
+ class SftpTransfer
7
+ def initialize(ssh, summarizer)
8
+ @ssh = ssh
9
+ @summarizer = summarizer
10
+ end
11
+
12
+ def upload!(local, remote, options)
13
+ options = { progress: self }.merge(options || {})
14
+ ssh.sftp.connect!
15
+ ssh.sftp.upload!(local, remote, options)
16
+ ensure
17
+ ssh.sftp.close_channel
18
+ end
19
+
20
+ def download!(remote, local, options)
21
+ options = { progress: self }.merge(options || {})
22
+ destination = local ? local : StringIO.new.tap { |io| io.set_encoding('BINARY') }
23
+
24
+ ssh.sftp.connect!
25
+ ssh.sftp.download!(remote, destination, options)
26
+ local ? true : destination.string
27
+ ensure
28
+ ssh.sftp.close_channel
29
+ end
30
+
31
+ def on_get(download, entry, offset, data)
32
+ entry.size ||= download.sftp.file.open(entry.remote) { |file| file.stat.size }
33
+ summarizer.call(nil, entry.remote, offset + data.bytesize, entry.size)
34
+ end
35
+
36
+ def on_put(_upload, file, offset, data)
37
+ summarizer.call(nil, file.local, offset + data.bytesize, file.size)
38
+ end
39
+
40
+ private
41
+
42
+ attr_reader :ssh, :summarizer
43
+ end
44
+ end
45
+ end
46
+ end
@@ -2,7 +2,6 @@ require 'English'
2
2
  require 'strscan'
3
3
  require 'mutex_m'
4
4
  require 'net/ssh'
5
- require 'net/scp'
6
5
 
7
6
  module Net
8
7
  module SSH
@@ -23,10 +22,27 @@ module SSHKit
23
22
  module Backend
24
23
 
25
24
  class Netssh < Abstract
25
+ def self.assert_valid_transfer_method!(method)
26
+ return if [:scp, :sftp].include?(method)
27
+
28
+ raise ArgumentError, "#{method.inspect} is not a valid transfer method. Supported methods are :scp, :sftp."
29
+ end
30
+
26
31
  class Configuration
27
32
  attr_accessor :connection_timeout, :pty
33
+ attr_reader :transfer_method
28
34
  attr_writer :ssh_options
29
35
 
36
+ def initialize
37
+ self.transfer_method = :scp
38
+ end
39
+
40
+ def transfer_method=(method)
41
+ Netssh.assert_valid_transfer_method!(method)
42
+
43
+ @transfer_method = method
44
+ end
45
+
30
46
  def ssh_options
31
47
  default_options.merge(@ssh_options ||= {})
32
48
  end
@@ -64,16 +80,16 @@ module SSHKit
64
80
  def upload!(local, remote, options = {})
65
81
  summarizer = transfer_summarizer('Uploading', options)
66
82
  remote = File.join(pwd_path, remote) unless remote.to_s.start_with?("/") || pwd_path.nil?
67
- with_ssh do |ssh|
68
- ssh.scp.upload!(local, remote, options, &summarizer)
83
+ with_transfer(summarizer) do |transfer|
84
+ transfer.upload!(local, remote, options)
69
85
  end
70
86
  end
71
87
 
72
88
  def download!(remote, local=nil, options = {})
73
89
  summarizer = transfer_summarizer('Downloading', options)
74
90
  remote = File.join(pwd_path, remote) unless remote.to_s.start_with?("/") || pwd_path.nil?
75
- with_ssh do |ssh|
76
- ssh.scp.download!(remote, local, options, &summarizer)
91
+ with_transfer(summarizer) do |transfer|
92
+ transfer.download!(remote, local, options)
77
93
  end
78
94
  end
79
95
 
@@ -105,7 +121,7 @@ module SSHKit
105
121
  last_percentage = nil
106
122
  proc do |_ch, name, transferred, total|
107
123
  percentage = (transferred.to_f * 100 / total.to_f)
108
- unless percentage.nan?
124
+ unless percentage.nan? || percentage.infinite?
109
125
  message = "#{action} #{name} #{percentage.round(2)}%"
110
126
  percentage_r = (percentage / log_percent).truncate * log_percent
111
127
  if percentage_r > 0 && (last_name != name || last_percentage != percentage_r)
@@ -183,6 +199,20 @@ module SSHKit
183
199
  )
184
200
  end
185
201
 
202
+ def with_transfer(summarizer)
203
+ transfer_method = host.transfer_method || self.class.config.transfer_method
204
+ transfer_class = if transfer_method == :sftp
205
+ require_relative "netssh/sftp_transfer"
206
+ SftpTransfer
207
+ else
208
+ require_relative "netssh/scp_transfer"
209
+ ScpTransfer
210
+ end
211
+
212
+ with_ssh do |ssh|
213
+ yield(transfer_class.new(ssh, summarizer))
214
+ end
215
+ end
186
216
  end
187
217
  end
188
218
 
data/lib/sshkit/host.rb CHANGED
@@ -7,6 +7,7 @@ module SSHKit
7
7
  class Host
8
8
 
9
9
  attr_accessor :password, :hostname, :port, :user, :ssh_options
10
+ attr_reader :transfer_method
10
11
 
11
12
  def key=(new_key)
12
13
  @keys = [new_key]
@@ -41,6 +42,12 @@ module SSHKit
41
42
  end
42
43
  end
43
44
 
45
+ def transfer_method=(method)
46
+ Backend::Netssh.assert_valid_transfer_method!(method) unless method.nil?
47
+
48
+ @transfer_method = method
49
+ end
50
+
44
51
  def local?
45
52
  @local
46
53
  end
@@ -1,3 +1,3 @@
1
1
  module SSHKit
2
- VERSION = "1.21.7".freeze
2
+ VERSION = "1.22.1".freeze
3
3
  end
data/sshkit.gemspec CHANGED
@@ -20,9 +20,11 @@ Gem::Specification.new do |gem|
20
20
  gem.require_paths = ["lib"]
21
21
  gem.version = SSHKit::VERSION
22
22
 
23
+ gem.add_runtime_dependency('base64') if RUBY_VERSION >= "2.4"
23
24
  gem.add_runtime_dependency('mutex_m')
24
25
  gem.add_runtime_dependency('net-ssh', '>= 2.8.0')
25
26
  gem.add_runtime_dependency('net-scp', '>= 1.1.2')
27
+ gem.add_runtime_dependency('net-sftp', '>= 2.1.2')
26
28
 
27
29
  gem.add_development_dependency('danger')
28
30
  gem.add_development_dependency('minitest', '>= 5.0.0')
@@ -0,0 +1,83 @@
1
+ require 'securerandom'
2
+
3
+ module SSHKit
4
+ module Backend
5
+ module NetsshTransferTests
6
+ def setup
7
+ super
8
+ @output = String.new
9
+ SSHKit.config.output_verbosity = :debug
10
+ SSHKit.config.output = SSHKit::Formatter::SimpleText.new(@output)
11
+ end
12
+
13
+ def a_host
14
+ VagrantWrapper.hosts['one']
15
+ end
16
+
17
+ def test_upload_and_then_capture_file_contents
18
+ actual_file_contents = ""
19
+ file_name = File.join("/tmp", SecureRandom.uuid)
20
+ File.open file_name, 'w+' do |f|
21
+ f.write "Some Content\nWith a newline and trailing spaces \n "
22
+ end
23
+ Netssh.new(a_host) do
24
+ upload!(file_name, file_name)
25
+ actual_file_contents = capture(:cat, file_name, strip: false)
26
+ end.run
27
+ assert_equal "Some Content\nWith a newline and trailing spaces \n ", actual_file_contents
28
+ end
29
+
30
+ def test_upload_within
31
+ file_name = SecureRandom.uuid
32
+ file_contents = "Some Content"
33
+ dir_name = SecureRandom.uuid
34
+ actual_file_contents = ""
35
+ Netssh.new(a_host) do |_host|
36
+ within("/tmp") do
37
+ execute :mkdir, "-p", dir_name
38
+ within(dir_name) do
39
+ upload!(StringIO.new(file_contents), file_name)
40
+ end
41
+ end
42
+ actual_file_contents = capture(:cat, "/tmp/#{dir_name}/#{file_name}", strip: false)
43
+ end.run
44
+ assert_equal file_contents, actual_file_contents
45
+ end
46
+
47
+ def test_upload_string_io
48
+ file_contents = ""
49
+ Netssh.new(a_host) do |_host|
50
+ file_name = File.join("/tmp", SecureRandom.uuid)
51
+ upload!(StringIO.new('example_io'), file_name)
52
+ file_contents = download!(file_name)
53
+ end.run
54
+ assert_equal "example_io", file_contents
55
+ end
56
+
57
+ def test_upload_large_file
58
+ size = 25
59
+ fills = SecureRandom.random_bytes(1024*1024)
60
+ file_name = "/tmp/file-#{size}.txt"
61
+ File.open(file_name, 'wb') do |f|
62
+ (size).times {f.write(fills) }
63
+ end
64
+ file_contents = ""
65
+ Netssh.new(a_host) do
66
+ upload!(file_name, file_name)
67
+ file_contents = download!(file_name)
68
+ end.run
69
+ assert_equal File.open(file_name, 'rb').read, file_contents
70
+ end
71
+
72
+ def test_upload_via_pathname
73
+ file_contents = ""
74
+ Netssh.new(a_host) do |_host|
75
+ file_name = Pathname.new(File.join("/tmp", SecureRandom.uuid))
76
+ upload!(StringIO.new('example_io'), file_name)
77
+ file_contents = download!(file_name)
78
+ end.run
79
+ assert_equal "example_io", file_contents
80
+ end
81
+ end
82
+ end
83
+ end
@@ -1,5 +1,4 @@
1
1
  require 'helper'
2
- require 'securerandom'
3
2
  require 'benchmark'
4
3
 
5
4
  module SSHKit
@@ -136,71 +135,6 @@ module SSHKit
136
135
  end.run
137
136
  end
138
137
 
139
- def test_upload_and_then_capture_file_contents
140
- actual_file_contents = ""
141
- file_name = File.join("/tmp", SecureRandom.uuid)
142
- File.open file_name, 'w+' do |f|
143
- f.write "Some Content\nWith a newline and trailing spaces \n "
144
- end
145
- Netssh.new(a_host) do
146
- upload!(file_name, file_name)
147
- actual_file_contents = capture(:cat, file_name, strip: false)
148
- end.run
149
- assert_equal "Some Content\nWith a newline and trailing spaces \n ", actual_file_contents
150
- end
151
-
152
- def test_upload_within
153
- file_name = SecureRandom.uuid
154
- file_contents = "Some Content"
155
- dir_name = SecureRandom.uuid
156
- actual_file_contents = ""
157
- Netssh.new(a_host) do |_host|
158
- within("/tmp") do
159
- execute :mkdir, "-p", dir_name
160
- within(dir_name) do
161
- upload!(StringIO.new(file_contents), file_name)
162
- end
163
- end
164
- actual_file_contents = capture(:cat, "/tmp/#{dir_name}/#{file_name}", strip: false)
165
- end.run
166
- assert_equal file_contents, actual_file_contents
167
- end
168
-
169
- def test_upload_string_io
170
- file_contents = ""
171
- Netssh.new(a_host) do |_host|
172
- file_name = File.join("/tmp", SecureRandom.uuid)
173
- upload!(StringIO.new('example_io'), file_name)
174
- file_contents = download!(file_name)
175
- end.run
176
- assert_equal "example_io", file_contents
177
- end
178
-
179
- def test_upload_large_file
180
- size = 25
181
- fills = SecureRandom.random_bytes(1024*1024)
182
- file_name = "/tmp/file-#{size}.txt"
183
- File.open(file_name, 'wb') do |f|
184
- (size).times {f.write(fills) }
185
- end
186
- file_contents = ""
187
- Netssh.new(a_host) do
188
- upload!(file_name, file_name)
189
- file_contents = download!(file_name)
190
- end.run
191
- assert_equal File.open(file_name, 'rb').read, file_contents
192
- end
193
-
194
- def test_upload_via_pathname
195
- file_contents = ""
196
- Netssh.new(a_host) do |_host|
197
- file_name = Pathname.new(File.join("/tmp", SecureRandom.uuid))
198
- upload!(StringIO.new('example_io'), file_name)
199
- file_contents = download!(file_name)
200
- end.run
201
- assert_equal "example_io", file_contents
202
- end
203
-
204
138
  def test_interaction_handler
205
139
  captured_command_result = nil
206
140
  Netssh.new(a_host) do
@@ -0,0 +1,23 @@
1
+ require 'helper'
2
+ require_relative 'netssh_transfer_tests'
3
+
4
+ module SSHKit
5
+ module Backend
6
+ class TestNetsshScp < FunctionalTest
7
+ include NetsshTransferTests
8
+
9
+ def setup
10
+ super
11
+ SSHKit::Backend::Netssh.configure do |ssh|
12
+ ssh.transfer_method = :scp
13
+ end
14
+ end
15
+
16
+ def test_scp_implementation_is_used
17
+ Netssh.new(a_host).send(:with_transfer, nil) do |transfer|
18
+ assert_instance_of Netssh::ScpTransfer, transfer
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ require 'helper'
2
+ require_relative 'netssh_transfer_tests'
3
+
4
+ module SSHKit
5
+ module Backend
6
+ class TestNetsshSftp < FunctionalTest
7
+ include NetsshTransferTests
8
+
9
+ def setup
10
+ super
11
+ SSHKit::Backend::Netssh.configure do |ssh|
12
+ ssh.transfer_method = :sftp
13
+ end
14
+ end
15
+
16
+ def test_sftp_implementation_is_used
17
+ Netssh.new(a_host).send(:with_transfer, nil) do |transfer|
18
+ assert_instance_of Netssh::SftpTransfer, transfer
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -124,7 +124,7 @@ module SSHKit
124
124
  assert_equal 2, lines.length
125
125
 
126
126
  assert_equal("[Deprecated] The background method is deprecated. Blame badly behaved pseudo-daemons!\n", lines[0])
127
- assert_match(/ \(Called from.*test_abstract.rb:\d+:in `block in test_background_logs_deprecation_warnings'\)\n/, lines[1])
127
+ assert_match(/ \(Called from.*test_abstract.rb:\d+:in .block in .*test_background_logs_deprecation_warnings.\)\n/, lines[1])
128
128
  end
129
129
 
130
130
  def test_calling_abstract_with_undefined_execute_command_raises_exception
@@ -5,6 +5,12 @@ module SSHKit
5
5
  module Backend
6
6
  class TestNetssh < UnitTest
7
7
 
8
+ def teardown
9
+ super
10
+ # Reset config to defaults after each test
11
+ backend.instance_variable_set :@config, nil
12
+ end
13
+
8
14
  def backend
9
15
  @backend ||= Netssh
10
16
  end
@@ -13,6 +19,7 @@ module SSHKit
13
19
  backend.configure do |ssh|
14
20
  ssh.pty = true
15
21
  ssh.connection_timeout = 30
22
+ ssh.transfer_method = :sftp
16
23
  ssh.ssh_options = {
17
24
  keys: %w(/home/user/.ssh/id_rsa),
18
25
  forward_agent: false,
@@ -21,6 +28,7 @@ module SSHKit
21
28
  end
22
29
 
23
30
  assert_equal 30, backend.config.connection_timeout
31
+ assert_equal :sftp, backend.config.transfer_method
24
32
  assert_equal true, backend.config.pty
25
33
 
26
34
  assert_equal %w(/home/user/.ssh/id_rsa), backend.config.ssh_options[:keys]
@@ -29,6 +37,46 @@ module SSHKit
29
37
  assert_instance_of backend::KnownHosts, backend.config.ssh_options[:known_hosts]
30
38
  end
31
39
 
40
+ def test_transfer_method_prohibits_invalid_values
41
+ error = assert_raises ArgumentError do
42
+ backend.configure do |ssh|
43
+ ssh.transfer_method = :nope
44
+ end
45
+ end
46
+
47
+ assert_match ":nope is not a valid transfer method", error.message
48
+ end
49
+
50
+ def test_transfer_method_does_not_allow_nil
51
+ error = assert_raises ArgumentError do
52
+ backend.configure do |ssh|
53
+ ssh.transfer_method = nil
54
+ end
55
+ end
56
+
57
+ assert_match "nil is not a valid transfer method", error.message
58
+ end
59
+
60
+ def test_transfer_method_defaults_to_scp
61
+ assert_equal :scp, backend.config.transfer_method
62
+ end
63
+
64
+ def test_host_can_override_transfer_method
65
+ backend.configure do |ssh|
66
+ ssh.transfer_method = :scp
67
+ end
68
+
69
+ host = Host.new("fake")
70
+ host.transfer_method = :sftp
71
+
72
+ netssh = backend.new(host)
73
+ netssh.stubs(:with_ssh).yields(nil)
74
+
75
+ netssh.send(:with_transfer, nil) do |transfer|
76
+ assert_instance_of Netssh::SftpTransfer, transfer
77
+ end
78
+ end
79
+
32
80
  def test_netssh_ext
33
81
  assert_includes Net::SSH::Config.default_files, "#{Dir.pwd}/.ssh/config"
34
82
  end
@@ -20,7 +20,7 @@ module SSHKit
20
20
 
21
21
  assert_equal(2, actual_lines.size)
22
22
  assert_equal "[Deprecated] Some message\n", actual_lines[0]
23
- assert_match %r{ \(Called from .*sshkit/test/unit/test_deprecation_logger.rb:#{line_number}:in `generate_warning'\)\n}, actual_lines[1]
23
+ assert_match %r{ \(Called from .*sshkit/test/unit/test_deprecation_logger.rb:#{line_number}:in .*generate_warning.\)\n}, actual_lines[1]
24
24
  end
25
25
 
26
26
  def test_handles_nil_output
@@ -142,6 +142,33 @@ module SSHKit
142
142
  end
143
143
  end
144
144
 
145
+ def test_transfer_method_defaults_to_nil
146
+ host = Host.new 'example.com'
147
+ assert_nil host.transfer_method
148
+ end
149
+
150
+ def test_transfer_method_can_be_configured
151
+ host = Host.new 'example.com'
152
+
153
+ host.transfer_method = :scp
154
+ assert_equal :scp, host.transfer_method
155
+
156
+ host.transfer_method = :sftp
157
+ assert_equal :sftp, host.transfer_method
158
+
159
+ host.transfer_method = nil
160
+ assert_nil host.transfer_method
161
+ end
162
+
163
+ def test_transfer_method_prohibits_invalid_values
164
+ host = Host.new 'example.com'
165
+
166
+ error = assert_raises ArgumentError do
167
+ host.transfer_method = :nope
168
+ end
169
+
170
+ assert_match ":nope is not a valid transfer method", error.message
171
+ end
145
172
  end
146
173
 
147
174
  end
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.21.7
4
+ version: 1.22.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lee Hambley
@@ -9,8 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-12-26 00:00:00.000000000 Z
12
+ date: 2024-04-01 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: base64
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
14
28
  - !ruby/object:Gem::Dependency
15
29
  name: mutex_m
16
30
  requirement: !ruby/object:Gem::Requirement
@@ -53,6 +67,20 @@ dependencies:
53
67
  - - ">="
54
68
  - !ruby/object:Gem::Version
55
69
  version: 1.1.2
70
+ - !ruby/object:Gem::Dependency
71
+ name: net-sftp
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: 2.1.2
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: 2.1.2
56
84
  - !ruby/object:Gem::Dependency
57
85
  name: danger
58
86
  requirement: !ruby/object:Gem::Requirement
@@ -228,6 +256,8 @@ files:
228
256
  - lib/sshkit/backends/local.rb
229
257
  - lib/sshkit/backends/netssh.rb
230
258
  - lib/sshkit/backends/netssh/known_hosts.rb
259
+ - lib/sshkit/backends/netssh/scp_transfer.rb
260
+ - lib/sshkit/backends/netssh/sftp_transfer.rb
231
261
  - lib/sshkit/backends/printer.rb
232
262
  - lib/sshkit/backends/skipper.rb
233
263
  - lib/sshkit/color.rb
@@ -255,8 +285,11 @@ files:
255
285
  - lib/sshkit/version.rb
256
286
  - sshkit.gemspec
257
287
  - test/boxes.json
288
+ - test/functional/backends/netssh_transfer_tests.rb
258
289
  - test/functional/backends/test_local.rb
259
290
  - test/functional/backends/test_netssh.rb
291
+ - test/functional/backends/test_netssh_scp.rb
292
+ - test/functional/backends/test_netssh_sftp.rb
260
293
  - test/functional/test_ssh_server_comes_up_for_functional_tests.rb
261
294
  - test/helper.rb
262
295
  - test/known_hosts/github
@@ -305,14 +338,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
305
338
  - !ruby/object:Gem::Version
306
339
  version: '0'
307
340
  requirements: []
308
- rubygems_version: 3.5.3
341
+ rubygems_version: 3.5.6
309
342
  signing_key:
310
343
  specification_version: 4
311
344
  summary: SSHKit makes it easy to write structured, testable SSH commands in Ruby
312
345
  test_files:
313
346
  - test/boxes.json
347
+ - test/functional/backends/netssh_transfer_tests.rb
314
348
  - test/functional/backends/test_local.rb
315
349
  - test/functional/backends/test_netssh.rb
350
+ - test/functional/backends/test_netssh_scp.rb
351
+ - test/functional/backends/test_netssh_sftp.rb
316
352
  - test/functional/test_ssh_server_comes_up_for_functional_tests.rb
317
353
  - test/helper.rb
318
354
  - test/known_hosts/github