sshkit 1.21.4 → 1.25.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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.docker/Dockerfile +6 -0
  3. data/.docker/ubuntu_setup.sh +22 -0
  4. data/.github/release-drafter.yml +10 -2
  5. data/.github/workflows/ci.yml +33 -20
  6. data/.github/workflows/push.yml +1 -1
  7. data/.gitignore +0 -1
  8. data/.rubocop.yml +6 -6
  9. data/.rubocop_todo.yml +3 -10
  10. data/CONTRIBUTING.md +2 -2
  11. data/EXAMPLES.md +25 -13
  12. data/Gemfile +0 -5
  13. data/README.md +2 -1
  14. data/RELEASING.md +2 -2
  15. data/Rakefile +0 -4
  16. data/docker-compose.yml +8 -0
  17. data/lib/sshkit/backends/abstract.rb +3 -4
  18. data/lib/sshkit/backends/connection_pool/cache.rb +2 -2
  19. data/lib/sshkit/backends/connection_pool.rb +0 -1
  20. data/lib/sshkit/backends/netssh/known_hosts.rb +8 -8
  21. data/lib/sshkit/backends/netssh/scp_transfer.rb +26 -0
  22. data/lib/sshkit/backends/netssh/sftp_transfer.rb +46 -0
  23. data/lib/sshkit/backends/netssh.rb +36 -7
  24. data/lib/sshkit/color.rb +2 -2
  25. data/lib/sshkit/host.rb +25 -0
  26. data/lib/sshkit/runners/parallel.rb +0 -2
  27. data/lib/sshkit/version.rb +1 -1
  28. data/sshkit.gemspec +6 -2
  29. data/test/functional/backends/netssh_transfer_tests.rb +83 -0
  30. data/test/functional/backends/test_netssh.rb +5 -71
  31. data/test/functional/backends/test_netssh_scp.rb +23 -0
  32. data/test/functional/backends/test_netssh_sftp.rb +23 -0
  33. data/test/helper.rb +4 -42
  34. data/test/support/docker_wrapper.rb +71 -0
  35. data/test/unit/backends/test_abstract.rb +57 -2
  36. data/test/unit/backends/test_netssh.rb +48 -0
  37. data/test/unit/test_command.rb +2 -1
  38. data/test/unit/test_command_map.rb +8 -8
  39. data/test/unit/test_configuration.rb +2 -1
  40. data/test/unit/test_deprecation_logger.rb +1 -1
  41. data/test/unit/test_host.rb +39 -0
  42. metadata +74 -29
  43. data/Vagrantfile +0 -20
  44. data/test/boxes.json +0 -17
  45. data/test/functional/test_ssh_server_comes_up_for_functional_tests.rb +0 -24
  46. data/test/support/vagrant_wrapper.rb +0 -64
@@ -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
@@ -211,7 +211,8 @@ module SSHKit
211
211
  end
212
212
 
213
213
  def test_deprecated_stdtream_accessors
214
- deprecation_out = ''
214
+ deprecation_out = +''
215
+
215
216
  SSHKit.config.deprecation_output = deprecation_out
216
217
 
217
218
  c = Command.new(:whoami)
@@ -27,26 +27,26 @@ module SSHKit
27
27
 
28
28
  def test_prefix
29
29
  map = CommandMap.new
30
- map.prefix[:rake].push("/home/vagrant/.rbenv/bin/rbenv exec")
30
+ map.prefix[:rake].push("/home/deployer/.rbenv/bin/rbenv exec")
31
31
  map.prefix[:rake].push("bundle exec")
32
32
 
33
- assert_equal map[:rake], "/home/vagrant/.rbenv/bin/rbenv exec bundle exec rake"
33
+ assert_equal map[:rake], "/home/deployer/.rbenv/bin/rbenv exec bundle exec rake"
34
34
  end
35
35
 
36
36
  def test_prefix_procs
37
37
  map = CommandMap.new
38
- map.prefix[:rake].push("/home/vagrant/.rbenv/bin/rbenv exec")
38
+ map.prefix[:rake].push("/home/deployer/.rbenv/bin/rbenv exec")
39
39
  map.prefix[:rake].push(proc{ "bundle exec" })
40
40
 
41
- assert_equal map[:rake], "/home/vagrant/.rbenv/bin/rbenv exec bundle exec rake"
41
+ assert_equal map[:rake], "/home/deployer/.rbenv/bin/rbenv exec bundle exec rake"
42
42
  end
43
43
 
44
44
  def test_prefix_unshift
45
45
  map = CommandMap.new
46
46
  map.prefix[:rake].push("bundle exec")
47
- map.prefix[:rake].unshift("/home/vagrant/.rbenv/bin/rbenv exec")
47
+ map.prefix[:rake].unshift("/home/deployer/.rbenv/bin/rbenv exec")
48
48
 
49
- assert_equal map[:rake], "/home/vagrant/.rbenv/bin/rbenv exec bundle exec rake"
49
+ assert_equal map[:rake], "/home/deployer/.rbenv/bin/rbenv exec bundle exec rake"
50
50
  end
51
51
 
52
52
  def test_indifferent_setter
@@ -59,10 +59,10 @@ module SSHKit
59
59
 
60
60
  def test_indifferent_prefix
61
61
  map = CommandMap.new
62
- map.prefix[:rake].push("/home/vagrant/.rbenv/bin/rbenv exec")
62
+ map.prefix[:rake].push("/home/deployer/.rbenv/bin/rbenv exec")
63
63
  map.prefix["rake"].push("bundle exec")
64
64
 
65
- assert_equal map[:rake], "/home/vagrant/.rbenv/bin/rbenv exec bundle exec rake"
65
+ assert_equal map[:rake], "/home/deployer/.rbenv/bin/rbenv exec bundle exec rake"
66
66
  end
67
67
 
68
68
  def test_prefix_initialization_is_thread_safe
@@ -11,7 +11,8 @@ module SSHKit
11
11
  end
12
12
 
13
13
  def test_deprecation_output
14
- output = ''
14
+ output = +''
15
+
15
16
  SSHKit.config.deprecation_output = output
16
17
  SSHKit.config.deprecation_logger.log('Test')
17
18
  assert_equal "[Deprecated] Test\n", output.lines.first
@@ -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
@@ -28,6 +28,12 @@ module SSHKit
28
28
  assert_equal 'example.com', h.hostname
29
29
  end
30
30
 
31
+ def test_custom_host_with_port
32
+ h = Host.new 'db:22'
33
+ assert_equal 22, h.port
34
+ assert_equal 'db', h.hostname
35
+ end
36
+
31
37
  def test_host_with_username
32
38
  h = Host.new 'root@example.com'
33
39
  assert_equal 'root', h.username
@@ -50,6 +56,12 @@ module SSHKit
50
56
  assert_equal 'localhost', h.hostname
51
57
  end
52
58
 
59
+ def test_ipv6_without_brackets
60
+ h = Host.new '1fff:0:a88:85a3::ac1f'
61
+ assert_nil h.port
62
+ assert_equal '1fff:0:a88:85a3::ac1f', h.hostname
63
+ end
64
+
53
65
  def test_does_not_confuse_ipv6_hosts_with_port_specification
54
66
  h = Host.new '[1fff:0:a88:85a3::ac1f]:8001'
55
67
  assert_equal 8001, h.port
@@ -142,6 +154,33 @@ module SSHKit
142
154
  end
143
155
  end
144
156
 
157
+ def test_transfer_method_defaults_to_nil
158
+ host = Host.new 'example.com'
159
+ assert_nil host.transfer_method
160
+ end
161
+
162
+ def test_transfer_method_can_be_configured
163
+ host = Host.new 'example.com'
164
+
165
+ host.transfer_method = :scp
166
+ assert_equal :scp, host.transfer_method
167
+
168
+ host.transfer_method = :sftp
169
+ assert_equal :sftp, host.transfer_method
170
+
171
+ host.transfer_method = nil
172
+ assert_nil host.transfer_method
173
+ end
174
+
175
+ def test_transfer_method_prohibits_invalid_values
176
+ host = Host.new 'example.com'
177
+
178
+ error = assert_raises ArgumentError do
179
+ host.transfer_method = :nope
180
+ end
181
+
182
+ assert_match ":nope is not a valid transfer method", error.message
183
+ end
145
184
  end
146
185
 
147
186
  end
metadata CHANGED
@@ -1,16 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sshkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.21.4
4
+ version: 1.25.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lee Hambley
8
8
  - Tom Clements
9
- autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2023-02-20 00:00:00.000000000 Z
11
+ date: 1980-01-02 00:00:00.000000000 Z
13
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: base64
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: logger
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
14
41
  - !ruby/object:Gem::Dependency
15
42
  name: net-ssh
16
43
  requirement: !ruby/object:Gem::Requirement
@@ -40,13 +67,27 @@ dependencies:
40
67
  - !ruby/object:Gem::Version
41
68
  version: 1.1.2
42
69
  - !ruby/object:Gem::Dependency
43
- name: danger
70
+ name: net-sftp
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 2.1.2
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 2.1.2
83
+ - !ruby/object:Gem::Dependency
84
+ name: ostruct
44
85
  requirement: !ruby/object:Gem::Requirement
45
86
  requirements:
46
87
  - - ">="
47
88
  - !ruby/object:Gem::Version
48
89
  version: '0'
49
- type: :development
90
+ type: :runtime
50
91
  prerelease: false
51
92
  version_requirements: !ruby/object:Gem::Requirement
52
93
  requirements:
@@ -54,47 +95,47 @@ dependencies:
54
95
  - !ruby/object:Gem::Version
55
96
  version: '0'
56
97
  - !ruby/object:Gem::Dependency
57
- name: minitest
98
+ name: danger
58
99
  requirement: !ruby/object:Gem::Requirement
59
100
  requirements:
60
101
  - - ">="
61
102
  - !ruby/object:Gem::Version
62
- version: 5.0.0
103
+ version: '0'
63
104
  type: :development
64
105
  prerelease: false
65
106
  version_requirements: !ruby/object:Gem::Requirement
66
107
  requirements:
67
108
  - - ">="
68
109
  - !ruby/object:Gem::Version
69
- version: 5.0.0
110
+ version: '0'
70
111
  - !ruby/object:Gem::Dependency
71
- name: minitest-reporters
112
+ name: minitest
72
113
  requirement: !ruby/object:Gem::Requirement
73
114
  requirements:
74
115
  - - ">="
75
116
  - !ruby/object:Gem::Version
76
- version: '0'
117
+ version: 5.0.0
77
118
  type: :development
78
119
  prerelease: false
79
120
  version_requirements: !ruby/object:Gem::Requirement
80
121
  requirements:
81
122
  - - ">="
82
123
  - !ruby/object:Gem::Version
83
- version: '0'
124
+ version: 5.0.0
84
125
  - !ruby/object:Gem::Dependency
85
- name: rainbow
126
+ name: minitest-reporters
86
127
  requirement: !ruby/object:Gem::Requirement
87
128
  requirements:
88
- - - "~>"
129
+ - - ">="
89
130
  - !ruby/object:Gem::Version
90
- version: 2.2.2
131
+ version: '0'
91
132
  type: :development
92
133
  prerelease: false
93
134
  version_requirements: !ruby/object:Gem::Requirement
94
135
  requirements:
95
- - - "~>"
136
+ - - ">="
96
137
  - !ruby/object:Gem::Version
97
- version: 2.2.2
138
+ version: '0'
98
139
  - !ruby/object:Gem::Dependency
99
140
  name: rake
100
141
  requirement: !ruby/object:Gem::Requirement
@@ -115,14 +156,14 @@ dependencies:
115
156
  requirements:
116
157
  - - "~>"
117
158
  - !ruby/object:Gem::Version
118
- version: 0.49.1
159
+ version: 0.52.0
119
160
  type: :development
120
161
  prerelease: false
121
162
  version_requirements: !ruby/object:Gem::Requirement
122
163
  requirements:
123
164
  - - "~>"
124
165
  - !ruby/object:Gem::Version
125
- version: 0.49.1
166
+ version: 0.52.0
126
167
  - !ruby/object:Gem::Dependency
127
168
  name: mocha
128
169
  requirement: !ruby/object:Gem::Requirement
@@ -180,6 +221,8 @@ executables: []
180
221
  extensions: []
181
222
  extra_rdoc_files: []
182
223
  files:
224
+ - ".docker/Dockerfile"
225
+ - ".docker/ubuntu_setup.sh"
183
226
  - ".github/dependabot.yml"
184
227
  - ".github/release-drafter.yml"
185
228
  - ".github/workflows/ci.yml"
@@ -199,7 +242,7 @@ files:
199
242
  - README.md
200
243
  - RELEASING.md
201
244
  - Rakefile
202
- - Vagrantfile
245
+ - docker-compose.yml
203
246
  - examples/images/example_output.png
204
247
  - examples/images/logo.png
205
248
  - examples/simple_connection.rb
@@ -214,6 +257,8 @@ files:
214
257
  - lib/sshkit/backends/local.rb
215
258
  - lib/sshkit/backends/netssh.rb
216
259
  - lib/sshkit/backends/netssh/known_hosts.rb
260
+ - lib/sshkit/backends/netssh/scp_transfer.rb
261
+ - lib/sshkit/backends/netssh/sftp_transfer.rb
217
262
  - lib/sshkit/backends/printer.rb
218
263
  - lib/sshkit/backends/skipper.rb
219
264
  - lib/sshkit/color.rb
@@ -240,15 +285,16 @@ files:
240
285
  - lib/sshkit/runners/sequential.rb
241
286
  - lib/sshkit/version.rb
242
287
  - sshkit.gemspec
243
- - test/boxes.json
288
+ - test/functional/backends/netssh_transfer_tests.rb
244
289
  - test/functional/backends/test_local.rb
245
290
  - test/functional/backends/test_netssh.rb
246
- - test/functional/test_ssh_server_comes_up_for_functional_tests.rb
291
+ - test/functional/backends/test_netssh_scp.rb
292
+ - test/functional/backends/test_netssh_sftp.rb
247
293
  - test/helper.rb
248
294
  - test/known_hosts/github
249
295
  - test/known_hosts/github_hash
250
296
  - test/known_hosts/github_ip
251
- - test/support/vagrant_wrapper.rb
297
+ - test/support/docker_wrapper.rb
252
298
  - test/unit/backends/test_abstract.rb
253
299
  - test/unit/backends/test_connection_pool.rb
254
300
  - test/unit/backends/test_local.rb
@@ -276,7 +322,6 @@ licenses:
276
322
  - MIT
277
323
  metadata:
278
324
  changelog_uri: https://github.com/capistrano/sshkit/releases
279
- post_install_message:
280
325
  rdoc_options: []
281
326
  require_paths:
282
327
  - lib
@@ -284,27 +329,27 @@ required_ruby_version: !ruby/object:Gem::Requirement
284
329
  requirements:
285
330
  - - ">="
286
331
  - !ruby/object:Gem::Version
287
- version: '0'
332
+ version: '2.5'
288
333
  required_rubygems_version: !ruby/object:Gem::Requirement
289
334
  requirements:
290
335
  - - ">="
291
336
  - !ruby/object:Gem::Version
292
337
  version: '0'
293
338
  requirements: []
294
- rubygems_version: 3.4.7
295
- signing_key:
339
+ rubygems_version: 3.7.2
296
340
  specification_version: 4
297
341
  summary: SSHKit makes it easy to write structured, testable SSH commands in Ruby
298
342
  test_files:
299
- - test/boxes.json
343
+ - test/functional/backends/netssh_transfer_tests.rb
300
344
  - test/functional/backends/test_local.rb
301
345
  - test/functional/backends/test_netssh.rb
302
- - test/functional/test_ssh_server_comes_up_for_functional_tests.rb
346
+ - test/functional/backends/test_netssh_scp.rb
347
+ - test/functional/backends/test_netssh_sftp.rb
303
348
  - test/helper.rb
304
349
  - test/known_hosts/github
305
350
  - test/known_hosts/github_hash
306
351
  - test/known_hosts/github_ip
307
- - test/support/vagrant_wrapper.rb
352
+ - test/support/docker_wrapper.rb
308
353
  - test/unit/backends/test_abstract.rb
309
354
  - test/unit/backends/test_connection_pool.rb
310
355
  - test/unit/backends/test_local.rb
data/Vagrantfile DELETED
@@ -1,20 +0,0 @@
1
- VAGRANTFILE_API_VERSION = "2"
2
-
3
- Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
4
- config.vm.box = 'hashicorp/precise64'
5
- config.vm.provision "shell", inline: <<-SHELL
6
- echo 'ClientAliveInterval 3' >> /etc/ssh/sshd_config
7
- echo 'ClientAliveCountMax 3' >> /etc/ssh/sshd_config
8
- service ssh restart
9
- SHELL
10
-
11
- json_config_path = File.join("test", "boxes.json")
12
- list = File.open(json_config_path).read
13
- list = JSON.parse(list)
14
-
15
- list.each do |vm|
16
- config.vm.define vm["name"] do |web|
17
- web.vm.network "forwarded_port", guest: 22, host: vm["port"]
18
- end
19
- end
20
- end
data/test/boxes.json DELETED
@@ -1,17 +0,0 @@
1
- [
2
- {
3
- "name": "one",
4
- "port": 3001,
5
- "user": "vagrant",
6
- "password": "vagrant",
7
- "hostname": "localhost"
8
- },
9
- {
10
- "name": "two",
11
- "port": 3002
12
- },
13
- {
14
- "name": "three",
15
- "port": 3003
16
- }
17
- ]
@@ -1,24 +0,0 @@
1
- require 'helper'
2
-
3
- module SSHKit
4
-
5
- class TestHost < FunctionalTest
6
-
7
- def host
8
- @_host ||= Host.new('')
9
- end
10
-
11
- def test_that_it_works
12
- assert true
13
- end
14
-
15
- def test_creating_a_user_gives_us_back_his_private_key_as_a_string
16
- skip 'It is not safe to create an user for non vagrant envs' unless VagrantWrapper.running?
17
- keys = create_user_with_key(:peter)
18
- assert_equal [:one, :two, :three], keys.keys
19
- assert keys.values.all?
20
- end
21
-
22
- end
23
-
24
- end
@@ -1,64 +0,0 @@
1
- class VagrantWrapper
2
- class << self
3
- def hosts
4
- @vm_hosts ||= begin
5
- result = {}
6
-
7
- boxes = boxes_list
8
-
9
- unless running?
10
- boxes.map! do |box|
11
- box['user'] = ENV['USER']
12
- box['port'] = '22'
13
- box
14
- end
15
- end
16
-
17
- boxes.each do |vm|
18
- result[vm['name']] = vm_host(vm)
19
- end
20
-
21
- result
22
- end
23
- end
24
-
25
- def running?
26
- @running ||= begin
27
- status = `#{vagrant_binary} status`
28
- status.include?('running')
29
- end
30
- end
31
-
32
- def boxes_list
33
- json_config_path = File.join('test', 'boxes.json')
34
- boxes = File.open(json_config_path).read
35
- JSON.parse(boxes)
36
- end
37
-
38
- def vagrant_binary
39
- 'vagrant'
40
- end
41
-
42
- private
43
-
44
- def vm_host(vm)
45
- host_options = {
46
- user: vm['user'] || 'vagrant',
47
- hostname: vm['hostname'] || 'localhost',
48
- port: vm['port'] || '22',
49
- password: vm['password'] || 'vagrant',
50
- ssh_options: host_verify_options
51
- }
52
-
53
- SSHKit::Host.new(host_options)
54
- end
55
-
56
- def host_verify_options
57
- if Net::SSH::Version::MAJOR >= 5
58
- { verify_host_key: :never }
59
- else
60
- { paranoid: false }
61
- end
62
- end
63
- end
64
- end