sshkit 1.21.6 → 1.22.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c02076e3d45e9cc2eeac09d86836d8d76b957e62effe234e8f35cc946097683a
4
- data.tar.gz: 748296139afb794afe86828c674a8bb41b8e080f77b8c65d3120b2c8842b481e
3
+ metadata.gz: 762a819b65ab2b01aee9bdff39037ca0b5f48a0e55b770c922eeee4b0118dcfb
4
+ data.tar.gz: 31aa61f4e968d345f0ee2c974ecf6761f86b5acb5e1f735e73c2713931f3bf7a
5
5
  SHA512:
6
- metadata.gz: f62b86ebfe3ff109d1cb6445b0a361256a5b316320706acda4a2c57cf160b8ee37086060ad15f21063e809a8b07549b01a5c92c5210e18694b88e6249ea6602f
7
- data.tar.gz: 58e77e7514508a4c8bcbfa4f1d5b789079da62cd2ffaee7de81c38efcd2760a47f8b61049a8c284e9193ca9d1cbdc8a31fadc48c7513f9e3cec7156dd172ab6c
6
+ metadata.gz: bd51f4d17794678ac7bc7f6b9c2588a7af76d94a8709414dfb3f2ba492adf1d4da134f4fc93a2a42096ac3fd2b2265a4570e5c6e7b6289c45326eddebec3bd2c
7
+ data.tar.gz: 88c219aec07643424633efa06bb9e6c3dd8539e651fb42f04cdbcc2cb513ffde40b72c32a460e5cb6893d69d3b7baad062a57246ee90eaac6062bf64f70b8bc5
@@ -8,7 +8,19 @@ jobs:
8
8
  runs-on: ubuntu-latest
9
9
  strategy:
10
10
  matrix:
11
- ruby: ["2.3", "2.4", "2.5", "2.6", "2.7", "3.0", "3.1", "3.2", "head"]
11
+ ruby:
12
+ [
13
+ "2.3",
14
+ "2.4",
15
+ "2.5",
16
+ "2.6",
17
+ "2.7",
18
+ "3.0",
19
+ "3.1",
20
+ "3.2",
21
+ "3.3",
22
+ "head",
23
+ ]
12
24
  steps:
13
25
  - uses: actions/checkout@v4
14
26
  - name: Set up Ruby
@@ -57,57 +69,3 @@ jobs:
57
69
  bundler-cache: true
58
70
  - name: Run rubocop
59
71
  run: bundle exec rake lint
60
-
61
- functional:
62
- runs-on: macos-12
63
- strategy:
64
- matrix:
65
- ruby:
66
- [
67
- "2.0",
68
- "2.1",
69
- "2.2",
70
- "2.3",
71
- "2.4",
72
- "2.5",
73
- "2.6",
74
- "2.7",
75
- "3.0",
76
- "3.1",
77
- "3.2",
78
- "head",
79
- ]
80
- steps:
81
- - uses: actions/checkout@v4
82
-
83
- - name: Cache Vagrant boxes
84
- uses: actions/cache@v3
85
- with:
86
- path: ~/.vagrant.d/boxes
87
- key: ${{ runner.os }}-vagrant-v2-${{ hashFiles('Vagrantfile') }}
88
- restore-keys: |
89
- ${{ runner.os }}-vagrant-v2-
90
-
91
- - name: Run vagrant up
92
- run: vagrant up
93
-
94
- - name: Set up Ruby
95
- uses: ruby/setup-ruby@v1
96
- with:
97
- ruby-version: ${{ matrix.ruby }}
98
- bundler-cache: true
99
-
100
- - name: Run functional tests
101
- run: bundle exec rake test:functional
102
-
103
- functional-all:
104
- runs-on: ubuntu-latest
105
- needs: [functional]
106
- if: always()
107
- steps:
108
- - name: All tests ok
109
- if: ${{ !(contains(needs.*.result, 'failure')) }}
110
- run: exit 0
111
- - name: Some tests failed
112
- if: ${{ contains(needs.*.result, 'failure') }}
113
- run: exit 1
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
@@ -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.6".freeze
2
+ VERSION = "1.22.0".freeze
3
3
  end
data/sshkit.gemspec CHANGED
@@ -20,8 +20,10 @@ Gem::Specification.new do |gem|
20
20
  gem.require_paths = ["lib"]
21
21
  gem.version = SSHKit::VERSION
22
22
 
23
+ gem.add_runtime_dependency('mutex_m')
23
24
  gem.add_runtime_dependency('net-ssh', '>= 2.8.0')
24
25
  gem.add_runtime_dependency('net-scp', '>= 1.1.2')
26
+ gem.add_runtime_dependency('net-sftp', '>= 2.1.2')
25
27
 
26
28
  gem.add_development_dependency('danger')
27
29
  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
@@ -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
@@ -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.6
4
+ version: 1.22.0
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-11-17 00:00:00.000000000 Z
12
+ date: 2024-01-09 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mutex_m
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: net-ssh
16
30
  requirement: !ruby/object:Gem::Requirement
@@ -39,6 +53,20 @@ dependencies:
39
53
  - - ">="
40
54
  - !ruby/object:Gem::Version
41
55
  version: 1.1.2
56
+ - !ruby/object:Gem::Dependency
57
+ name: net-sftp
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 2.1.2
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: 2.1.2
42
70
  - !ruby/object:Gem::Dependency
43
71
  name: danger
44
72
  requirement: !ruby/object:Gem::Requirement
@@ -214,6 +242,8 @@ files:
214
242
  - lib/sshkit/backends/local.rb
215
243
  - lib/sshkit/backends/netssh.rb
216
244
  - lib/sshkit/backends/netssh/known_hosts.rb
245
+ - lib/sshkit/backends/netssh/scp_transfer.rb
246
+ - lib/sshkit/backends/netssh/sftp_transfer.rb
217
247
  - lib/sshkit/backends/printer.rb
218
248
  - lib/sshkit/backends/skipper.rb
219
249
  - lib/sshkit/color.rb
@@ -241,8 +271,11 @@ files:
241
271
  - lib/sshkit/version.rb
242
272
  - sshkit.gemspec
243
273
  - test/boxes.json
274
+ - test/functional/backends/netssh_transfer_tests.rb
244
275
  - test/functional/backends/test_local.rb
245
276
  - test/functional/backends/test_netssh.rb
277
+ - test/functional/backends/test_netssh_scp.rb
278
+ - test/functional/backends/test_netssh_sftp.rb
246
279
  - test/functional/test_ssh_server_comes_up_for_functional_tests.rb
247
280
  - test/helper.rb
248
281
  - test/known_hosts/github
@@ -291,14 +324,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
291
324
  - !ruby/object:Gem::Version
292
325
  version: '0'
293
326
  requirements: []
294
- rubygems_version: 3.4.21
327
+ rubygems_version: 3.5.3
295
328
  signing_key:
296
329
  specification_version: 4
297
330
  summary: SSHKit makes it easy to write structured, testable SSH commands in Ruby
298
331
  test_files:
299
332
  - test/boxes.json
333
+ - test/functional/backends/netssh_transfer_tests.rb
300
334
  - test/functional/backends/test_local.rb
301
335
  - test/functional/backends/test_netssh.rb
336
+ - test/functional/backends/test_netssh_scp.rb
337
+ - test/functional/backends/test_netssh_sftp.rb
302
338
  - test/functional/test_ssh_server_comes_up_for_functional_tests.rb
303
339
  - test/helper.rb
304
340
  - test/known_hosts/github