sshkit 1.19.0 → 1.21.2
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 +4 -4
- data/.github/release-drafter.yml +17 -0
- data/.github/workflows/push.yml +12 -0
- data/.rubocop.yml +2 -2
- data/.travis.yml +4 -1
- data/CHANGELOG.md +1 -786
- data/Dangerfile +1 -1
- data/EXAMPLES.md +1 -0
- data/Gemfile +0 -12
- data/README.md +31 -14
- data/RELEASING.md +3 -4
- data/Rakefile +3 -6
- data/Vagrantfile +5 -0
- data/examples/simple_connection.rb +9 -0
- data/lib/sshkit/backends/abstract.rb +3 -2
- data/lib/sshkit/backends/connection_pool/cache.rb +12 -5
- data/lib/sshkit/backends/netssh.rb +2 -1
- data/lib/sshkit/command.rb +7 -2
- data/lib/sshkit/version.rb +1 -1
- data/sshkit.gemspec +3 -0
- data/test/functional/backends/test_local.rb +18 -0
- data/test/functional/backends/test_netssh.rb +16 -2
- data/test/helper.rb +1 -1
- data/test/unit/backends/test_abstract.rb +12 -0
- data/test/unit/backends/test_netssh.rb +7 -0
- data/test/unit/formatters/test_pretty.rb +1 -1
- data/test/unit/test_command.rb +5 -0
- metadata +11 -7
data/Dangerfile
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
danger.import_dangerfile(github: "capistrano/danger")
|
|
1
|
+
danger.import_dangerfile(github: "capistrano/danger", branch: "no-changelog")
|
data/EXAMPLES.md
CHANGED
data/Gemfile
CHANGED
|
@@ -2,18 +2,6 @@ source 'https://rubygems.org'
|
|
|
2
2
|
|
|
3
3
|
gemspec
|
|
4
4
|
|
|
5
|
-
platforms :rbx do
|
|
6
|
-
gem 'rubysl', '~> 2.0'
|
|
7
|
-
gem 'json'
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
# Chandler requires Ruby >= 2.1.0, but depending on the Travis environment,
|
|
11
|
-
# we may not meet that requirement. Only include the chandler gem if the Ruby
|
|
12
|
-
# requirement is met. (Chandler is used only for `rake release`; see Rakefile.)
|
|
13
|
-
if Gem::Requirement.new('>= 2.1.0').satisfied_by?(Gem::Version.new(RUBY_VERSION))
|
|
14
|
-
gem 'chandler', '>= 0.1.1'
|
|
15
|
-
end
|
|
16
|
-
|
|
17
5
|
# public_suffix 3+ requires ruby 2.1+
|
|
18
6
|
if Gem::Requirement.new('< 2.1').satisfied_by?(Gem::Version.new(RUBY_VERSION))
|
|
19
7
|
gem 'public_suffix', '< 3'
|
data/README.md
CHANGED
|
@@ -6,29 +6,31 @@ more servers.
|
|
|
6
6
|
[](https://rubygems.org/gems/sshkit)
|
|
7
7
|
[](https://travis-ci.org/capistrano/sshkit)
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Example
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
- Connect to 2 servers
|
|
12
|
+
- Execute commands as `deploy` user with `RAILS_ENV=production`
|
|
13
|
+
- Execute commands in serial (default is `:parallel`)
|
|
12
14
|
|
|
13
15
|
```ruby
|
|
14
16
|
require 'sshkit'
|
|
15
17
|
require 'sshkit/dsl'
|
|
16
18
|
include SSHKit::DSL
|
|
17
19
|
|
|
18
|
-
on
|
|
20
|
+
on ["1.example.com", "2.example.com"], in: :sequence do |host|
|
|
21
|
+
puts "Now executing on #{host}"
|
|
19
22
|
within "/opt/sites/example.com" do
|
|
20
23
|
as :deploy do
|
|
21
|
-
with
|
|
22
|
-
rake
|
|
23
|
-
runner "S3::Sync.notify"
|
|
24
|
-
execute :node, "socket_server.js"
|
|
24
|
+
with RAILS_ENV: 'production' do
|
|
25
|
+
execute :rake, "assets:precompile"
|
|
26
|
+
execute :rails, "runner", "S3::Sync.notify"
|
|
25
27
|
end
|
|
26
28
|
end
|
|
27
29
|
end
|
|
28
30
|
end
|
|
29
31
|
```
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
Many other examples are in [EXAMPLES.md](EXAMPLES.md).
|
|
32
34
|
|
|
33
35
|
## Basic usage
|
|
34
36
|
|
|
@@ -37,7 +39,7 @@ You can pass one or more hosts as parameters; this runs commands via SSH. Altern
|
|
|
37
39
|
pass `:local` to run commands locally. By default SSKit will run the commands on all hosts in
|
|
38
40
|
parallel.
|
|
39
41
|
|
|
40
|
-
|
|
42
|
+
### Running commands
|
|
41
43
|
|
|
42
44
|
All backends support the `execute(*args)`, `test(*args)` & `capture(*args)` methods
|
|
43
45
|
for executing a command. You can call any of these methods in the context of an `on()`
|
|
@@ -63,7 +65,7 @@ end
|
|
|
63
65
|
By default the `capture` methods strips whitespace. If you need to preserve whitespace
|
|
64
66
|
you can pass the `strip: false` option: `capture(:ls, '-l', strip: false)`
|
|
65
67
|
|
|
66
|
-
|
|
68
|
+
### Transferring files
|
|
67
69
|
|
|
68
70
|
All backends also support the `upload!` and `download!` methods for transferring files.
|
|
69
71
|
For the remote backend, the file is transferred with scp.
|
|
@@ -75,7 +77,7 @@ on '1.example.com' do
|
|
|
75
77
|
end
|
|
76
78
|
```
|
|
77
79
|
|
|
78
|
-
|
|
80
|
+
### Users, working directories, environment variables and umask
|
|
79
81
|
|
|
80
82
|
When running commands, you can tell SSHKit to set up the context for those
|
|
81
83
|
commands using the following methods:
|
|
@@ -113,6 +115,11 @@ the raised error.
|
|
|
113
115
|
Helpers such as `runner()` and `rake()` which expand to `execute(:rails, "runner", ...)` and
|
|
114
116
|
`execute(:rake, ...)` are convenience helpers for Ruby, and Rails based apps.
|
|
115
117
|
|
|
118
|
+
### Verbosity / Silence
|
|
119
|
+
|
|
120
|
+
- raise verbosity of a command: `execute "echo DEAD", verbosity: :ERROR`
|
|
121
|
+
- hide a command from output: `execute "echo HIDDEN", verbosity: :DEBUG`
|
|
122
|
+
|
|
116
123
|
## Parallel
|
|
117
124
|
|
|
118
125
|
Notice on the `on()` call the `in: :sequence` option, the following will do
|
|
@@ -567,10 +574,20 @@ In order to do special gymnastics with SSH, tunneling, aliasing, complex options
|
|
|
567
574
|
|
|
568
575
|
These system level files are the preferred way of setting up tunneling and proxies because the system implementations of these things are faster and better than the Ruby implementations you would get if you were to configure them through Net::SSH. In cases where it's not possible (Windows?), it should be possible to make use of the Net::SSH APIs to setup tunnels and proxy commands before deferring control to Capistrano/SSHKit..
|
|
569
576
|
|
|
570
|
-
##
|
|
577
|
+
## Proxying
|
|
571
578
|
|
|
572
|
-
|
|
579
|
+
To connect to the target host via a jump/bastion host, use a `Net::SSH::Proxy::Jump`
|
|
573
580
|
|
|
574
|
-
|
|
581
|
+
```ruby
|
|
582
|
+
host = SSHKit::Host.new(
|
|
583
|
+
hostname: 'target.host.com',
|
|
584
|
+
ssh_options: { proxy: Net::SSH::Proxy::Jump.new("proxy.bar.com") }
|
|
585
|
+
)
|
|
586
|
+
on [host] do
|
|
587
|
+
execute :echo, '1'
|
|
588
|
+
end
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
## SSHKit Related Blog Posts
|
|
575
592
|
|
|
576
593
|
[Embedded Capistrano with SSHKit](http://ryandoyle.net/posts/embedded-capistrano-with-sshkit/)
|
data/RELEASING.md
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
* You must have commit rights to the SSHKit repository.
|
|
6
6
|
* You must have push rights for the sshkit gem on rubygems.org.
|
|
7
7
|
* You must be using Ruby >= 2.1.0.
|
|
8
|
-
* Your `~/.netrc` must be configured with your GitHub credentials, [as explained here](https://github.com/mattbrictson/chandler#2-configure-netrc).
|
|
9
8
|
|
|
10
9
|
## How to release
|
|
11
10
|
|
|
@@ -13,6 +12,6 @@
|
|
|
13
12
|
2. **Ensure the tests are passing by running `rake test`.** If functional tests fail, ensure you have [Vagrant](https://www.vagrantup.com) installed and have started it with `vagrant up`.
|
|
14
13
|
3. Determine which would be the correct next version number according to [semver](http://semver.org/).
|
|
15
14
|
4. Update the version in `./lib/sshkit/version.rb`.
|
|
16
|
-
5.
|
|
17
|
-
6.
|
|
18
|
-
7.
|
|
15
|
+
5. Commit the `version.rb` change with a message like "Preparing vX.Y.Z"
|
|
16
|
+
6. Run `rake release`; this will tag, push to GitHub, and publish to rubygems.org
|
|
17
|
+
7. Update the draft release on the [GitHub releases page](https://github.com/capistrano/sshkit/releases) to point to the new tag and publish the release
|
data/Rakefile
CHANGED
|
@@ -30,10 +30,7 @@ RuboCop::RakeTask.new(:lint) do |task|
|
|
|
30
30
|
task.options = ['--lint']
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
# We assume that the person doing `rake release` has Ruby >= 2.1.
|
|
37
|
-
require "chandler/tasks"
|
|
38
|
-
Rake.application.invoke_task("chandler:push")
|
|
33
|
+
Rake::Task["release"].enhance do
|
|
34
|
+
puts "Don't forget to publish the release on GitHub!"
|
|
35
|
+
system "open https://github.com/capistrano/sshkit/releases"
|
|
39
36
|
end
|
data/Vagrantfile
CHANGED
|
@@ -2,6 +2,11 @@ VAGRANTFILE_API_VERSION = "2"
|
|
|
2
2
|
|
|
3
3
|
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
|
4
4
|
config.vm.box = 'hashicorp/precise64'
|
|
5
|
+
config.vm.provision "shell", inline: <<-SHELL
|
|
6
|
+
echo 'ClientAliveInterval 1' >> /etc/ssh/sshd_config
|
|
7
|
+
echo 'ClientAliveCountMax 1' >> /etc/ssh/sshd_config
|
|
8
|
+
service ssh restart
|
|
9
|
+
SHELL
|
|
5
10
|
|
|
6
11
|
json_config_path = File.join("test", "boxes.json")
|
|
7
12
|
list = File.open(json_config_path).read
|
|
@@ -82,9 +82,10 @@ module SSHKit
|
|
|
82
82
|
|
|
83
83
|
def within(directory, &_block)
|
|
84
84
|
(@pwd ||= []).push directory.to_s
|
|
85
|
+
escaped = Command.shellescape_except_tilde(pwd_path)
|
|
85
86
|
execute <<-EOTEST, verbosity: Logger::DEBUG
|
|
86
|
-
if test ! -d #{
|
|
87
|
-
then echo "Directory does not exist '#{
|
|
87
|
+
if test ! -d #{escaped}
|
|
88
|
+
then echo "Directory does not exist '#{escaped}'" 1>&2
|
|
88
89
|
false
|
|
89
90
|
fi
|
|
90
91
|
EOTEST
|
|
@@ -36,12 +36,12 @@ class SSHKit::Backend::ConnectionPool::Cache
|
|
|
36
36
|
def evict
|
|
37
37
|
# Peek at the first connection to see if it is still fresh. If so, we can
|
|
38
38
|
# return right away without needing to use `synchronize`.
|
|
39
|
-
first_expires_at,
|
|
40
|
-
return if first_expires_at.nil? || fresh?(first_expires_at)
|
|
39
|
+
first_expires_at, first_conn = connections.first
|
|
40
|
+
return if (first_expires_at.nil? || fresh?(first_expires_at)) && !closed?(first_conn)
|
|
41
41
|
|
|
42
42
|
connections.synchronize do
|
|
43
|
-
fresh, stale = connections.partition do |expires_at,
|
|
44
|
-
fresh?(expires_at)
|
|
43
|
+
fresh, stale = connections.partition do |expires_at, conn|
|
|
44
|
+
fresh?(expires_at) && !closed?(conn)
|
|
45
45
|
end
|
|
46
46
|
connections.replace(fresh)
|
|
47
47
|
stale.each { |_, conn| closer.call(conn) }
|
|
@@ -71,6 +71,13 @@ class SSHKit::Backend::ConnectionPool::Cache
|
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
def closed?(conn)
|
|
74
|
-
conn.respond_to?(:closed?) && conn.closed?
|
|
74
|
+
return true if conn.respond_to?(:closed?) && conn.closed?
|
|
75
|
+
# test if connection is alive
|
|
76
|
+
conn.process(0) if conn.respond_to?(:process)
|
|
77
|
+
return false
|
|
78
|
+
rescue IOError => e
|
|
79
|
+
# connection is closed by server
|
|
80
|
+
return true if e.message == 'closed stream'
|
|
81
|
+
raise
|
|
75
82
|
end
|
|
76
83
|
end
|
|
@@ -109,7 +109,8 @@ module SSHKit
|
|
|
109
109
|
message = "#{action} #{name} #{percentage.round(2)}%"
|
|
110
110
|
percentage_r = (percentage / log_percent).truncate * log_percent
|
|
111
111
|
if percentage_r > 0 && (last_name != name || last_percentage != percentage_r)
|
|
112
|
-
|
|
112
|
+
verbosity = (options[:verbosity] || :INFO).downcase # TODO: ideally reuse command.rb logic
|
|
113
|
+
public_send verbosity, message
|
|
113
114
|
last_name = name
|
|
114
115
|
last_percentage = percentage_r
|
|
115
116
|
else
|
data/lib/sshkit/command.rb
CHANGED
|
@@ -143,7 +143,7 @@ module SSHKit
|
|
|
143
143
|
|
|
144
144
|
def within(&_block)
|
|
145
145
|
return yield unless options[:in]
|
|
146
|
-
"cd #{options[:in]
|
|
146
|
+
"cd #{self.class.shellescape_except_tilde(options[:in])} && #{yield}"
|
|
147
147
|
end
|
|
148
148
|
|
|
149
149
|
def environment_hash
|
|
@@ -219,6 +219,11 @@ module SSHKit
|
|
|
219
219
|
end
|
|
220
220
|
end
|
|
221
221
|
|
|
222
|
+
# allow using home directory but escape everything else like spaces etc
|
|
223
|
+
def self.shellescape_except_tilde(file)
|
|
224
|
+
file.shellescape.gsub("\\~", "~")
|
|
225
|
+
end
|
|
226
|
+
|
|
222
227
|
private
|
|
223
228
|
|
|
224
229
|
def default_options
|
|
@@ -234,7 +239,7 @@ module SSHKit
|
|
|
234
239
|
|
|
235
240
|
def call_interaction_handler(stream_name, data, channel)
|
|
236
241
|
interaction_handler = options[:interaction_handler]
|
|
237
|
-
interaction_handler = MappingInteractionHandler.new(interaction_handler) if interaction_handler.kind_of?(Hash)
|
|
242
|
+
interaction_handler = MappingInteractionHandler.new(interaction_handler) if interaction_handler.kind_of?(Hash) or interaction_handler.kind_of?(Proc)
|
|
238
243
|
interaction_handler.on_data(self, stream_name, data, channel) if interaction_handler.respond_to?(:on_data)
|
|
239
244
|
end
|
|
240
245
|
|
data/lib/sshkit/version.rb
CHANGED
data/sshkit.gemspec
CHANGED
|
@@ -9,6 +9,9 @@ Gem::Specification.new do |gem|
|
|
|
9
9
|
gem.description = %q{A comprehensive toolkit for remotely running commands in a structured manner on groups of servers.}
|
|
10
10
|
gem.homepage = "http://github.com/capistrano/sshkit"
|
|
11
11
|
gem.license = "MIT"
|
|
12
|
+
gem.metadata = {
|
|
13
|
+
"changelog_uri" => "https://github.com/capistrano/sshkit/releases"
|
|
14
|
+
}
|
|
12
15
|
|
|
13
16
|
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
14
17
|
gem.files = `git ls-files`.split("\n")
|
|
@@ -99,6 +99,24 @@ module SSHKit
|
|
|
99
99
|
end.run
|
|
100
100
|
assert_equal("Enter Data\nCaptured SOME DATA", captured_command_result)
|
|
101
101
|
end
|
|
102
|
+
|
|
103
|
+
def test_interaction_handler_with_proc
|
|
104
|
+
captured_command_result = nil
|
|
105
|
+
Local.new do
|
|
106
|
+
command = 'echo Enter Data; read the_data; echo Captured $the_data;'
|
|
107
|
+
captured_command_result = capture(command, interaction_handler:
|
|
108
|
+
lambda { |data|
|
|
109
|
+
case data
|
|
110
|
+
when "Enter Data\n"
|
|
111
|
+
"SOME DATA\n"
|
|
112
|
+
when "Captured SOME DATA\n"
|
|
113
|
+
nil
|
|
114
|
+
end
|
|
115
|
+
}
|
|
116
|
+
)
|
|
117
|
+
end.run
|
|
118
|
+
assert_equal("Enter Data\nCaptured SOME DATA", captured_command_result)
|
|
119
|
+
end
|
|
102
120
|
end
|
|
103
121
|
end
|
|
104
122
|
end
|
|
@@ -180,7 +180,7 @@ module SSHKit
|
|
|
180
180
|
size = 25
|
|
181
181
|
fills = SecureRandom.random_bytes(1024*1024)
|
|
182
182
|
file_name = "/tmp/file-#{size}.txt"
|
|
183
|
-
File.open(file_name, '
|
|
183
|
+
File.open(file_name, 'wb') do |f|
|
|
184
184
|
(size).times {f.write(fills) }
|
|
185
185
|
end
|
|
186
186
|
file_contents = ""
|
|
@@ -188,7 +188,7 @@ module SSHKit
|
|
|
188
188
|
upload!(file_name, file_name)
|
|
189
189
|
file_contents = download!(file_name)
|
|
190
190
|
end.run
|
|
191
|
-
assert_equal File.open(file_name).read, file_contents
|
|
191
|
+
assert_equal File.open(file_name, 'rb').read, file_contents
|
|
192
192
|
end
|
|
193
193
|
|
|
194
194
|
def test_upload_via_pathname
|
|
@@ -212,6 +212,20 @@ module SSHKit
|
|
|
212
212
|
end.run
|
|
213
213
|
assert_equal("Enter Data\nCaptured SOME DATA", captured_command_result)
|
|
214
214
|
end
|
|
215
|
+
|
|
216
|
+
def test_connection_pool_keepalive
|
|
217
|
+
# ensure we enable connection pool
|
|
218
|
+
SSHKit::Backend::Netssh.pool.idle_timeout = 10
|
|
219
|
+
Netssh.new(a_host) do |_host|
|
|
220
|
+
test :false
|
|
221
|
+
end.run
|
|
222
|
+
sleep 2.5
|
|
223
|
+
captured_command_result = nil
|
|
224
|
+
Netssh.new(a_host) do |_host|
|
|
225
|
+
captured_command_result = capture(:echo, 'some_value')
|
|
226
|
+
end.run
|
|
227
|
+
assert_equal "some_value", captured_command_result
|
|
228
|
+
end
|
|
215
229
|
end
|
|
216
230
|
|
|
217
231
|
end
|
data/test/helper.rb
CHANGED
|
@@ -99,6 +99,18 @@ module SSHKit
|
|
|
99
99
|
assert_equal '/usr/bin/env cat file', backend.executed_command.to_command
|
|
100
100
|
end
|
|
101
101
|
|
|
102
|
+
def test_within_home
|
|
103
|
+
backend = ExampleBackend.new do
|
|
104
|
+
within '~/foo' do
|
|
105
|
+
execute :cat, 'file', :strip => false
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
backend.run
|
|
110
|
+
|
|
111
|
+
assert_equal 'cd ~/foo && /usr/bin/env cat file', backend.executed_command.to_command
|
|
112
|
+
end
|
|
113
|
+
|
|
102
114
|
def test_background_logs_deprecation_warnings
|
|
103
115
|
deprecation_out = ''
|
|
104
116
|
SSHKit.config.deprecation_output = deprecation_out
|
|
@@ -54,6 +54,13 @@ module SSHKit
|
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
+
def test_transfer_summarizer_uses_verbosity
|
|
58
|
+
netssh = Netssh.new(Host.new('fake'))
|
|
59
|
+
summarizer = netssh.send(:transfer_summarizer, 'Transferring', verbosity: :ERROR)
|
|
60
|
+
netssh.expects(:error).with { |msg| msg.include?('Transferring afile 15.0%') }
|
|
61
|
+
summarizer.call(nil,'afile',15,100)
|
|
62
|
+
end
|
|
63
|
+
|
|
57
64
|
if Net::SSH::Version::CURRENT >= Net::SSH::Version[3, 1, 0]
|
|
58
65
|
def test_known_hosts_for_when_all_hosts_are_recognized
|
|
59
66
|
perform_known_hosts_test('github', 'github.com')
|
|
@@ -115,7 +115,7 @@ module SSHKit
|
|
|
115
115
|
|
|
116
116
|
def test_can_write_to_output_which_just_supports_append
|
|
117
117
|
# Note output doesn't have to be an IO, it only needs to support <<
|
|
118
|
-
output = stub(:<<)
|
|
118
|
+
output = stub(:<< => nil)
|
|
119
119
|
pretty = SSHKit::Formatter::Pretty.new(output)
|
|
120
120
|
simulate_command_lifecycle(pretty)
|
|
121
121
|
end
|
data/test/unit/test_command.rb
CHANGED
|
@@ -84,6 +84,11 @@ module SSHKit
|
|
|
84
84
|
assert_equal "cd /opt/sites && /usr/bin/env ls -l", c.to_command
|
|
85
85
|
end
|
|
86
86
|
|
|
87
|
+
def test_working_in_home_directory
|
|
88
|
+
c = Command.new(:ls, '-l', in: "~/sites")
|
|
89
|
+
assert_equal "cd ~/sites && /usr/bin/env ls -l", c.to_command
|
|
90
|
+
end
|
|
91
|
+
|
|
87
92
|
def test_working_in_a_given_weird_directory
|
|
88
93
|
c = Command.new(:ls, '-l', in: "/opt/sites and stuff")
|
|
89
94
|
assert_equal "cd /opt/sites\\ and\\ stuff && /usr/bin/env ls -l", c.to_command
|
metadata
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sshkit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.21.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lee Hambley
|
|
8
8
|
- Tom Clements
|
|
9
|
-
autorequire:
|
|
9
|
+
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2021-01-18 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: net-ssh
|
|
@@ -180,6 +180,8 @@ executables: []
|
|
|
180
180
|
extensions: []
|
|
181
181
|
extra_rdoc_files: []
|
|
182
182
|
files:
|
|
183
|
+
- ".github/release-drafter.yml"
|
|
184
|
+
- ".github/workflows/push.yml"
|
|
183
185
|
- ".gitignore"
|
|
184
186
|
- ".rubocop.yml"
|
|
185
187
|
- ".rubocop_todo.yml"
|
|
@@ -199,6 +201,7 @@ files:
|
|
|
199
201
|
- Vagrantfile
|
|
200
202
|
- examples/images/example_output.png
|
|
201
203
|
- examples/images/logo.png
|
|
204
|
+
- examples/simple_connection.rb
|
|
202
205
|
- lib/core_ext/array.rb
|
|
203
206
|
- lib/core_ext/hash.rb
|
|
204
207
|
- lib/sshkit.rb
|
|
@@ -270,8 +273,9 @@ files:
|
|
|
270
273
|
homepage: http://github.com/capistrano/sshkit
|
|
271
274
|
licenses:
|
|
272
275
|
- MIT
|
|
273
|
-
metadata:
|
|
274
|
-
|
|
276
|
+
metadata:
|
|
277
|
+
changelog_uri: https://github.com/capistrano/sshkit/releases
|
|
278
|
+
post_install_message:
|
|
275
279
|
rdoc_options: []
|
|
276
280
|
require_paths:
|
|
277
281
|
- lib
|
|
@@ -286,8 +290,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
286
290
|
- !ruby/object:Gem::Version
|
|
287
291
|
version: '0'
|
|
288
292
|
requirements: []
|
|
289
|
-
rubygems_version: 3.
|
|
290
|
-
signing_key:
|
|
293
|
+
rubygems_version: 3.2.5
|
|
294
|
+
signing_key:
|
|
291
295
|
specification_version: 4
|
|
292
296
|
summary: SSHKit makes it easy to write structured, testable SSH commands in Ruby
|
|
293
297
|
test_files:
|