sshkit-interactive 0.1.0 → 0.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: 2908a10617b2c1d702b525f2540b89aaf9e6d6d3
4
- data.tar.gz: 97199152d548f65b98d6658044e56f52f7ffc4ff
3
+ metadata.gz: 2b9f9fe3a0df465a8ce537cde0a15dd59a8c757a
4
+ data.tar.gz: 8d66b61a1c46fec1547fd4aeaa0bd99396daba00
5
5
  SHA512:
6
- metadata.gz: cb3dbb43f59ee5a5b41fce160adb41a77754265ca938c9fd5960a1f1082f86e0a2ea6d1bb99568cfcdba4cf4571a45b3e87b01e1352349e2a6225ee37c383802
7
- data.tar.gz: 4590d048ab511003cb780828173e4a79d13b501c65f66099897f914ae9f9a2e3112353b145c4c8b7f7ebaaf67dce2e693792baa6e74554a5810453f59247960b
6
+ metadata.gz: c7c4f24a202860ae9b4543fd05c16531b64daea2718a39a3ac8e906bc5470271de288e09badaf8ee6d34310ebed65388f67f138bd75c86a1f7bc9ae07e5ffa70
7
+ data.tar.gz: 1c344d7c66e3fe33ebfe57ad387d073238c1d6f621595dda8fea50b7c85dd5e6d53eb122274628d367065816fcbf3bed2a96e1570af2c08ced4d94285573c97b
@@ -0,0 +1,31 @@
1
+ sudo: false
2
+
3
+ language: ruby
4
+
5
+ rvm:
6
+ - ruby-2.2.5
7
+ - ruby-2.3.1
8
+ - rbx-2.5.8
9
+ - jruby-1.7
10
+ - jruby-9.1.2.0
11
+
12
+ gemfile:
13
+ - spec/gemfiles/net-ssh2_8.gemfile
14
+ - spec/gemfiles/net-ssh2_9.gemfile
15
+ - spec/gemfiles/net-ssh3_0.gemfile
16
+ - spec/gemfiles/net-ssh3_1.gemfile
17
+ - spec/gemfiles/net-ssh3_2.gemfile
18
+
19
+ matrix:
20
+ exclude:
21
+ - rvm: jruby-1.7
22
+ gemfile: spec/gemfiles/net-ssh3_0.gemfile
23
+ - rvm: jruby-1.7
24
+ gemfile: spec/gemfiles/net-ssh3_1.gemfile
25
+ - rvm: jruby-1.7
26
+ gemfile: spec/gemfiles/net-ssh3_2.gemfile
27
+
28
+ before_install:
29
+ - gem install bundler -v '~> 1.13'
30
+
31
+ script: bundle exec rake spec
@@ -0,0 +1,7 @@
1
+ # Change Log
2
+
3
+ ## 0.2.0 (2016-09-16)
4
+ ### Feature
5
+ - add DSL for interactive command invocation (`run_interactively`)
6
+
7
+ ## 0.1.0 (2015-01-02) (Initial release)
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # SSHKit::Interactive
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/sshkit-interactive.svg)](http://badge.fury.io/rb/sshkit-interactive) [![Build Status](https://travis-ci.org/afeld/sshkit-interactive.svg?branch=master)](https://travis-ci.org/afeld/sshkit-interactive)
4
+
3
5
  An [SSHKit](https://github.com/capistrano/sshkit) [backend](https://github.com/capistrano/sshkit/tree/master/test/unit/backends) that allows you to execute interactive commands on your servers. Remote commands that you might want to use this for:
4
6
 
5
7
  * A Rails console
@@ -27,30 +29,52 @@ require 'sshkit/interactive'
27
29
 
28
30
  ## Usage
29
31
 
30
- From SSHKit, use the [interactive backend](lib/sshkit/interactive/backend.rb) (which makes a system call to `ssh` under the hood), then execute commands as normal.
32
+ Running interactive commands will make a system call to `ssh` under the hood.
33
+
34
+ ### DSL
35
+
36
+ Using the DSL, simply put the command within the `run_interactively` block. In Capistrano, it might look something like this:
31
37
 
32
38
  ```ruby
33
- SSHKit.config.backend = SSHKit::Interactive::Backend
34
- hosts = %w{my.server.com}
35
- on hosts do |host|
36
- execute(:vim)
39
+ namespace :rails do
40
+ desc "Run Rails console"
41
+ task :console do
42
+ run_interactively primary(:app) do
43
+ execute(:rails, :console)
44
+ end
45
+ end
37
46
  end
38
47
  ```
39
48
 
40
- Note that you will probably only want to execute on a single host. In Capistrano, it might look something like this:
49
+ It is also possible to set directory and user the Capistrano way:
41
50
 
42
51
  ```ruby
43
52
  namespace :rails do
44
53
  desc "Run Rails console"
45
54
  task :console do
46
- SSHKit.config.backend = SSHKit::Interactive::Backend
47
- on primary(:app) do |host|
48
- execute(:rails, :console)
55
+ run_interactively primary(:app) do
56
+ within current_path do
57
+ as user: :foobar do
58
+ execute(:rails, :console)
59
+ end
60
+ end
49
61
  end
50
62
  end
51
63
  end
52
64
  ```
53
65
 
66
+ ### Manually setting the backend
67
+
68
+ Use the [interactive backend](lib/sshkit/interactive/backend.rb) and execute commands as normal:
69
+
70
+ ```ruby
71
+ SSHKit.config.backend = SSHKit::Interactive::Backend
72
+ hosts = %w{my.server.com}
73
+ on hosts do |host|
74
+ execute(:vim)
75
+ end
76
+ ```
77
+
54
78
  ## Contributing
55
79
 
56
80
  1. [Fork it](https://github.com/afeld/sshkit-interactive/fork)
data/Rakefile CHANGED
@@ -1,2 +1,4 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
2
 
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new
@@ -3,9 +3,10 @@ require 'sshkit'
3
3
  require_relative 'interactive/version'
4
4
  require_relative 'interactive/command'
5
5
  require_relative 'interactive/backend'
6
+ require_relative 'interactive/dsl'
6
7
 
7
8
  module SSHKit
8
9
  module Interactive
9
- # Your code goes here...
10
+ Unsupported = Class.new(SSHKit::StandardError)
10
11
  end
11
12
  end
@@ -1,4 +1,3 @@
1
- # based on https://github.com/jetthoughts/j-cap-recipes/blob/be9dffe279b7bee816c9bafcb3633109096b20d5/lib/sshkit/backends/ssh_command.rb
2
1
  module SSHKit
3
2
  module Interactive
4
3
  class Backend < SSHKit::Backend::Printer
@@ -6,18 +5,50 @@ module SSHKit
6
5
  instance_exec(host, &@block)
7
6
  end
8
7
 
9
- def within(directory, &block)
10
- (@pwd ||= []).push directory.to_s
8
+ def within(directory, &_block)
9
+ (@pwd ||= []).push(directory.to_s)
10
+
11
11
  yield
12
12
  ensure
13
13
  @pwd.pop
14
14
  end
15
15
 
16
- def execute(*args, &block)
17
- remote_command = command(*args)
18
- output << remote_command
19
- Command.new(host, remote_command).execute
16
+ def as(who, &_block)
17
+ if who.is_a?(Hash)
18
+ @user = who[:user] || who['user']
19
+ @group = who[:group] || who['group']
20
+ else
21
+ @user = who
22
+ @group = nil
23
+ end
24
+
25
+ raise SSHKit::Interactive::Unsupported, 'Setting group (through `as`) is currently not supported' unless @group.nil?
26
+
27
+ yield
28
+ ensure
29
+ remove_instance_variable(:@user)
30
+ remove_instance_variable(:@group)
20
31
  end
32
+
33
+ def execute(*args)
34
+ super
35
+
36
+ options = args.extract_options!
37
+ cmd = Command.new(host, command(args, options))
38
+
39
+ debug(cmd.to_s)
40
+
41
+ cmd.execute
42
+ end
43
+
44
+ def _unsupported_operation(*args)
45
+ raise SSHKit::Backend::MethodUnavailableError, 'SSHKit::Interactive does not support this operation.'
46
+ end
47
+
48
+ alias :upload! :_unsupported_operation
49
+ alias :download! :_unsupported_operation
50
+ alias :test :_unsupported_operation
51
+ alias :capture :_unsupported_operation
21
52
  end
22
53
  end
23
54
  end
@@ -3,66 +3,94 @@ module SSHKit
3
3
  class Command
4
4
  attr_reader :host, :remote_command
5
5
 
6
- # remote_command can be an SSHKit::Command or a String
7
- def initialize(host, remote_command=nil)
8
- @host = host
6
+ # Instantiate new interactive SSHKit command wrapper.
7
+ #
8
+ # @param host [SSHKit::Host] the host to run `remote_command` on.
9
+ # @param remote_command [SSHKit::Command] the command to run on `host`.
10
+ def initialize(host, remote_command = nil)
11
+ @host = host
9
12
  @remote_command = remote_command
10
13
  end
11
14
 
15
+ # Run the command on the remote host via SSH binary.
16
+ def execute
17
+ system(to_s)
18
+ end
19
+
20
+ # SSH command arguments
21
+ def ssh_cmd_args
22
+ args = []
23
+
24
+ args << '-t'
25
+ args << '-A' if forward_agent?
26
+ args << "-p #{port}" if port
27
+ args << "-l #{user}" if user
28
+ args << %Q{-o "PreferredAuthentications #{auth_methods_str}"} if auth_methods.count > 0
29
+ args << %Q{-o "ProxyCommand #{proxy_command}"} if proxy
30
+ args << %Q{-o "HostName #{host_name}"} if host_name
31
+
32
+ keys.each do |key|
33
+ args << "-i #{key}"
34
+ end
35
+
36
+ args
37
+ end
38
+
39
+ # Complete command
40
+ def to_s
41
+ [
42
+ :ssh,
43
+ *ssh_cmd_args,
44
+ host.hostname,
45
+ "\"#{remote_command_str}\""
46
+ ].reject(&:empty?).join(' ')
47
+ end
48
+
49
+ private
50
+
51
+ # available options: http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start
12
52
  def netssh_options
13
- self.host.netssh_options
53
+ host.netssh_options
14
54
  end
15
55
 
16
56
  def user
17
- self.host.user
57
+ host.user
18
58
  end
19
59
 
20
- def hostname
21
- self.host.hostname
60
+ def port
61
+ netssh_options[:port]
22
62
  end
23
63
 
24
- def options
25
- opts = []
26
- opts << '-A' if netssh_options[:forward_agent]
27
- if netssh_options[:keys]
28
- netssh_options[:keys].each do |k|
29
- opts << "-i #{k}"
30
- end
31
- end
32
- opts << "-l #{user}" if user
33
- opts << %{-o "PreferredAuthentications #{netssh_options[:auth_methods].join(',')}"} if netssh_options[:auth_methods]
34
- opts << %{-o "ProxyCommand #{netssh_options[:proxy].command_line_template}"} if netssh_options[:proxy]
35
- opts << "-p #{netssh_options[:port]}" if netssh_options[:port]
36
- opts << '-t' if self.remote_command
64
+ def forward_agent?
65
+ !!netssh_options[:forward_agent]
66
+ end
37
67
 
38
- opts
68
+ def host_name
69
+ netssh_options[:host_name]
39
70
  end
40
71
 
41
- def options_str
42
- self.options.join(' ')
72
+ def keys
73
+ netssh_options[:keys] || []
43
74
  end
44
75
 
45
- def remote_command_str
46
- if self.remote_command
47
- %{"#{self.remote_command}"}
48
- else
49
- ''
50
- end
76
+ def auth_methods
77
+ netssh_options[:auth_methods] || []
51
78
  end
52
79
 
53
- def to_s
54
- parts = [
55
- 'ssh',
56
- self.options_str,
57
- self.hostname,
58
- self.remote_command_str
59
- ]
60
-
61
- parts.reject(&:empty?).join(' ')
80
+ def auth_methods_str
81
+ auth_methods.join(',')
62
82
  end
63
83
 
64
- def execute
65
- system(self.to_s)
84
+ def proxy
85
+ netssh_options[:proxy]
86
+ end
87
+
88
+ def proxy_command
89
+ proxy.command_line_template
90
+ end
91
+
92
+ def remote_command_str
93
+ %Q{\\$SHELL -l -c \\"#{remote_command.to_command}\\"}
66
94
  end
67
95
  end
68
96
  end
@@ -0,0 +1,22 @@
1
+ module SSHKit
2
+ module Interactive
3
+ module DSL
4
+ # run commands interactively
5
+ def run_interactively(host, &block)
6
+ Thread.current[:run_interactively] = true
7
+
8
+ SSHKit::Interactive::Backend.new(host, &block).run
9
+ ensure
10
+ Thread.current[:run_interactively] = false
11
+ end
12
+
13
+ def on(*args)
14
+ raise SSHKit::Interactive::Unsupported, 'Switching host in interactive mode is not possible' if Thread.current[:run_interactively]
15
+
16
+ super
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ include SSHKit::Interactive::DSL
@@ -1,5 +1,5 @@
1
1
  module SSHKit
2
2
  module Interactive
3
- VERSION = '0.1.0'
3
+ VERSION = '0.2.0'
4
4
  end
5
5
  end
@@ -1,10 +1,53 @@
1
1
  describe SSHKit::Interactive::Backend do
2
2
  describe '#execute' do
3
- it "does a system call with the SSH command" do
4
- host = SSHKit::Host.new('example.com')
5
- backend = SSHKit::Interactive::Backend.new(host)
6
- expect_any_instance_of(SSHKit::Interactive::Command).to receive(:system).with('ssh -A -t example.com "/usr/bin/env ls"')
3
+ let(:host) { SSHKit::Host.new('example.com') }
4
+ let(:backend) { SSHKit::Interactive::Backend.new(host) }
5
+
6
+ it 'does a system call with the SSH command' do
7
+ expect_system_call('ssh -t -A example.com "\\$SHELL -l -c \\"/usr/bin/env ls\\""')
7
8
  backend.execute('ls')
8
9
  end
10
+
11
+ it 'respects the specified directory' do
12
+ backend.within('/var/log') do
13
+ expect_system_call('ssh -t -A example.com "\\$SHELL -l -c \\"cd /var/log && /usr/bin/env ls\\""')
14
+ backend.execute('ls')
15
+ end
16
+ end
17
+
18
+ it 'respects the specified user' do
19
+ backend.as('deployer') do
20
+ expect_system_call('ssh -t -A example.com "\\$SHELL -l -c \\"sudo -u deployer -- sh -c \'/usr/bin/env ls\'\\""')
21
+ backend.execute('ls')
22
+ end
23
+ end
24
+
25
+ it 'respects the specified group' do
26
+ expect {
27
+ backend.as(user: :user, group: :group) do
28
+ backend.execute('ls')
29
+ end
30
+ }.to raise_error(SSHKit::Interactive::Unsupported)
31
+ end
32
+
33
+ it 'respects the specified env'
34
+
35
+ describe 'prevents calling unsupported operations' do
36
+ it '#upload!' do
37
+ expect { backend.upload!(:a, :b) }.to raise_error(::SSHKit::Backend::MethodUnavailableError)
38
+ end
39
+
40
+ it '#download!' do
41
+ expect { backend.download!(:a, :b) }.to raise_error(::SSHKit::Backend::MethodUnavailableError)
42
+ end
43
+
44
+ it '#test' do
45
+ expect { backend.test(:true) }.to raise_error(::SSHKit::Backend::MethodUnavailableError)
46
+ end
47
+
48
+ it '#capture' do
49
+ expect { backend.capture(:ls) }.to raise_error(::SSHKit::Backend::MethodUnavailableError)
50
+ end
51
+ end
9
52
  end
10
53
  end
@@ -1,72 +1,104 @@
1
1
  describe SSHKit::Interactive::Command do
2
- describe '#options_str' do
3
- def command_options_str(host)
2
+ describe '#ssh_cmd_args' do
3
+ def command_args(host)
4
4
  command = SSHKit::Interactive::Command.new(host)
5
- command.options_str
5
+ command.ssh_cmd_args
6
6
  end
7
7
 
8
- it "handles a simple hostname" do
8
+ it 'handles a simple hostname' do
9
9
  host = SSHKit::Host.new('example.com')
10
- expect(command_options_str(host)).to eq('-A')
10
+
11
+ expect(command_args(host)).to include('-A')
11
12
  end
12
13
 
13
- it "handles a username and port" do
14
+ it 'handles a username and port' do
14
15
  host = SSHKit::Host.new('someuser@example.com:2222')
15
- expect(command_options_str(host)).to eq('-A -l someuser -p 2222')
16
+
17
+ expect(command_args(host)).to include('-A')
18
+ expect(command_args(host)).to include('-l someuser')
19
+ expect(command_args(host)).to include('-p 2222')
16
20
  end
17
21
 
18
- it "handles a proxy" do
22
+ it 'handles a proxy' do
19
23
  host = SSHKit::Host.new('someuser@example.com:2222')
20
24
  host.ssh_options = {
21
25
  proxy: Net::SSH::Proxy::Command.new('ssh mygateway.com -W %h:%p')
22
26
  }
23
27
 
24
- expect(command_options_str(host)).to eq('-A -l someuser -o "ProxyCommand ssh mygateway.com -W %h:%p" -p 2222')
28
+ expect(command_args(host)).to include('-A')
29
+ expect(command_args(host)).to include('-l someuser')
30
+ expect(command_args(host)).to include('-p 2222')
31
+ expect(command_args(host)).to include('-o "ProxyCommand ssh mygateway.com -W %h:%p"')
25
32
  end
26
33
 
27
- it "handles keys option" do
34
+ it 'handles keys option' do
28
35
  host = SSHKit::Host.new('example.com')
29
36
  host.ssh_options = { keys: %w(/home/user/.ssh/id_rsa) }
30
37
 
31
- expect(command_options_str(host)).to eq('-A -i /home/user/.ssh/id_rsa')
38
+ expect(command_args(host)).to include('-A')
39
+ expect(command_args(host)).to include('-i /home/user/.ssh/id_rsa')
32
40
  end
33
41
 
34
- # TODO split into separate tests
35
- it "handles extra options" do
36
- host = SSHKit::Host.new('someuser@example.com:2222')
37
- host.keys = ["~/.ssh/some_key_here"]
38
- host.ssh_options = {
39
- port: 3232,
40
- keys: %w(/home/user/.ssh/id_rsa),
41
- forward_agent: false,
42
- auth_methods: %w(publickey password)
43
- }
42
+ it 'handles keys on host' do
43
+ host = SSHKit::Host.new('example.com')
44
+ host.keys = ['~/.ssh/some_key_here']
45
+
46
+ expect(command_args(host)).to include('-A')
47
+ expect(command_args(host)).to include('-i ~/.ssh/some_key_here')
48
+ end
49
+
50
+ it 'handles a host_name' do
51
+ host = SSHKit::Host.new('example.com')
52
+ host.ssh_options = { host_name: 'foo.bar' }
53
+
54
+ expect(command_args(host)).to include('-A')
55
+ expect(command_args(host)).to include('-o "HostName foo.bar"')
56
+ end
57
+
58
+ it 'handles disabled forward agent' do
59
+ host = SSHKit::Host.new('example.com')
60
+ host.ssh_options = { forward_agent: false }
44
61
 
45
- expect(command_options_str(host)).to eq('-i /home/user/.ssh/id_rsa -l someuser -o "PreferredAuthentications publickey,password" -p 3232')
62
+ expect(command_args(host)).not_to include('-A')
46
63
  end
47
64
 
48
- it "handles a password"
65
+ it 'handles auth methods' do
66
+ host = SSHKit::Host.new('example.com:2222')
67
+ host.ssh_options = { auth_methods: %w(publickey password) }
68
+
69
+ expect(command_args(host)).to include('-o "PreferredAuthentications publickey,password"')
70
+ end
71
+
72
+ it 'handles port option' do
73
+ host = SSHKit::Host.new('example.com:2222')
74
+ host.ssh_options = { port: 3232 }
75
+
76
+ expect(command_args(host)).to include('-p 3232')
77
+ end
49
78
  end
50
79
 
51
80
  describe '#to_s' do
52
- it "includes options" do
53
- host = SSHKit::Host.new('example.com')
54
- command = SSHKit::Interactive::Command.new(host)
55
- expect(command).to receive(:options_str).and_return('-A -B -C')
56
- expect(command.to_s).to eq('ssh -A -B -C example.com')
81
+ let(:host) { SSHKit::Host.new('example.com') }
82
+ let(:command) { SSHKit::Command.new(:ls) }
83
+
84
+ it 'includes options' do
85
+ cmd = SSHKit::Interactive::Command.new(host, command)
86
+
87
+ expect(cmd).to receive(:ssh_cmd_args).and_return(%w(-A -B -C))
88
+ expect(cmd.to_s).to eq('ssh -A -B -C example.com "\\$SHELL -l -c \\"/usr/bin/env ls\\""')
57
89
  end
58
90
 
59
- it "excludes options if they're blank" do
60
- host = SSHKit::Host.new('example.com')
61
- command = SSHKit::Interactive::Command.new(host)
62
- expect(command).to receive(:options_str).and_return('')
63
- expect(command.to_s).to eq('ssh example.com')
91
+ it 'excludes options if they\'re blank' do
92
+ cmd = SSHKit::Interactive::Command.new(host, command)
93
+
94
+ expect(cmd).to receive(:ssh_cmd_args).and_return([])
95
+ expect(cmd.to_s).to eq('ssh example.com "\\$SHELL -l -c \\"/usr/bin/env ls\\""')
64
96
  end
65
97
 
66
- it "accepts a remote command" do
67
- host = SSHKit::Host.new('example.com')
68
- command = SSHKit::Interactive::Command.new(host, 'ls')
69
- expect(command.to_s).to eq('ssh -A -t example.com "ls"')
98
+ it 'accepts a remote command' do
99
+ cmd = SSHKit::Interactive::Command.new(host, command)
100
+
101
+ expect(cmd.to_s).to eq('ssh -t -A example.com "\\$SHELL -l -c \\"/usr/bin/env ls\\""')
70
102
  end
71
103
  end
72
104
  end
@@ -0,0 +1,25 @@
1
+ describe SSHKit::Interactive::DSL do
2
+ describe '#run_interactively' do
3
+ include SSHKit::Interactive::DSL
4
+
5
+ let(:host) { SSHKit::Host.new('example.com') }
6
+
7
+ it 'will execute interactively' do
8
+ expect_system_call('ssh -t -A example.com "\\$SHELL -l -c \\"/usr/bin/env ls\\""')
9
+
10
+ run_interactively host do
11
+ execute(:ls)
12
+ end
13
+ end
14
+
15
+ it 'does not support switching hosts' do
16
+ expect {
17
+ run_interactively host do
18
+ on host do
19
+ execute(:ls)
20
+ end
21
+ end
22
+ }.to raise_error(SSHKit::Interactive::Unsupported)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+
4
+ gem 'net-ssh', '~> 2.8.0'
5
+
6
+ # Specify your gem's dependencies in sshkit-interactive.gemspec
7
+ gemspec path: '../..'
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+
4
+ gem 'net-ssh', '~> 2.9.0'
5
+
6
+ # Specify your gem's dependencies in sshkit-interactive.gemspec
7
+ gemspec path: '../..'
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+
4
+ gem 'net-ssh', '~> 3.0.0'
5
+
6
+ # Specify your gem's dependencies in sshkit-interactive.gemspec
7
+ gemspec path: '../..'
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+
4
+ gem 'net-ssh', '~> 3.1.0'
5
+
6
+ # Specify your gem's dependencies in sshkit-interactive.gemspec
7
+ gemspec path: '../..'
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+
4
+ gem 'net-ssh', '~> 3.2.0'
5
+
6
+ # Specify your gem's dependencies in sshkit-interactive.gemspec
7
+ gemspec path: '../..'
@@ -92,4 +92,13 @@ RSpec.configure do |config|
92
92
  # as the one that triggered the failure.
93
93
  Kernel.srand config.seed
94
94
  =end
95
+
96
+ config.before(:each) do
97
+ # block all system calls
98
+ allow_any_instance_of(SSHKit::Interactive::Command).to receive(:system)
99
+
100
+ def expect_system_call(command)
101
+ expect_any_instance_of(SSHKit::Interactive::Command).to receive(:system).with(command)
102
+ end
103
+ end
95
104
  end
@@ -4,22 +4,22 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'sshkit/interactive/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "sshkit-interactive"
7
+ spec.name = 'sshkit-interactive'
8
8
  spec.version = SSHKit::Interactive::VERSION
9
- spec.authors = ["Aidan Feldman"]
10
- spec.email = ["aidan.feldman@gmail.com"]
9
+ spec.authors = ['Aidan Feldman']
10
+ spec.email = ['aidan.feldman@gmail.com']
11
11
  spec.summary = %q{An SSHKit backend that allows you to execute interactive commands on your servers. }
12
- spec.homepage = "https://github.com/afeld/sshkit-interactive"
13
- spec.license = "MIT"
12
+ spec.homepage = 'https://github.com/afeld/sshkit-interactive'
13
+ spec.license = 'MIT'
14
14
 
15
15
  spec.files = `git ls-files -z`.split("\x0")
16
16
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
- spec.require_paths = ["lib"]
18
+ spec.require_paths = ['lib']
19
19
 
20
- spec.add_dependency "sshkit", "~> 1.6"
20
+ spec.add_dependency 'sshkit', '~> 1.9'
21
21
 
22
- spec.add_development_dependency "bundler", "~> 1.7"
23
- spec.add_development_dependency "rake", "~> 10.0"
24
- spec.add_development_dependency "rspec", "~> 3.1"
22
+ spec.add_development_dependency 'bundler', '~> 1.13'
23
+ spec.add_development_dependency 'rake', '~> 11.0'
24
+ spec.add_development_dependency 'rspec', '~> 3.5'
25
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sshkit-interactive
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aidan Feldman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-02 00:00:00.000000000 Z
11
+ date: 2016-09-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sshkit
@@ -16,56 +16,56 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.6'
19
+ version: '1.9'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.6'
26
+ version: '1.9'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.7'
33
+ version: '1.13'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.7'
40
+ version: '1.13'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '10.0'
47
+ version: '11.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '10.0'
54
+ version: '11.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '3.1'
61
+ version: '3.5'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '3.1'
68
+ version: '3.5'
69
69
  description:
70
70
  email:
71
71
  - aidan.feldman@gmail.com
@@ -75,6 +75,8 @@ extra_rdoc_files: []
75
75
  files:
76
76
  - ".gitignore"
77
77
  - ".rspec"
78
+ - ".travis.yml"
79
+ - CHANGELOG.md
78
80
  - Gemfile
79
81
  - LICENSE.txt
80
82
  - README.md
@@ -82,9 +84,16 @@ files:
82
84
  - lib/sshkit/interactive.rb
83
85
  - lib/sshkit/interactive/backend.rb
84
86
  - lib/sshkit/interactive/command.rb
87
+ - lib/sshkit/interactive/dsl.rb
85
88
  - lib/sshkit/interactive/version.rb
86
89
  - spec/backend_spec.rb
87
90
  - spec/command_spec.rb
91
+ - spec/dsl_spec.rb
92
+ - spec/gemfiles/net-ssh2_8.gemfile
93
+ - spec/gemfiles/net-ssh2_9.gemfile
94
+ - spec/gemfiles/net-ssh3_0.gemfile
95
+ - spec/gemfiles/net-ssh3_1.gemfile
96
+ - spec/gemfiles/net-ssh3_2.gemfile
88
97
  - spec/spec_helper.rb
89
98
  - sshkit-interactive.gemspec
90
99
  homepage: https://github.com/afeld/sshkit-interactive
@@ -107,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
107
116
  version: '0'
108
117
  requirements: []
109
118
  rubyforge_project:
110
- rubygems_version: 2.4.5
119
+ rubygems_version: 2.5.1
111
120
  signing_key:
112
121
  specification_version: 4
113
122
  summary: An SSHKit backend that allows you to execute interactive commands on your
@@ -115,4 +124,10 @@ summary: An SSHKit backend that allows you to execute interactive commands on yo
115
124
  test_files:
116
125
  - spec/backend_spec.rb
117
126
  - spec/command_spec.rb
127
+ - spec/dsl_spec.rb
128
+ - spec/gemfiles/net-ssh2_8.gemfile
129
+ - spec/gemfiles/net-ssh2_9.gemfile
130
+ - spec/gemfiles/net-ssh3_0.gemfile
131
+ - spec/gemfiles/net-ssh3_1.gemfile
132
+ - spec/gemfiles/net-ssh3_2.gemfile
118
133
  - spec/spec_helper.rb