here_or_there 0.1.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 +7 -0
- data/lib/here_or_there/local.rb +14 -0
- data/lib/here_or_there/remote.rb +71 -0
- data/lib/here_or_there/response.rb +29 -0
- data/lib/here_or_there/version.rb +3 -0
- data/lib/here_or_there.rb +21 -0
- data/spec/here_or_there/local_spec.rb +41 -0
- data/spec/here_or_there/remote_spec.rb +116 -0
- data/spec/here_or_there/response_spec.rb +57 -0
- data/spec/here_or_there_spec.rb +29 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/support/capture.rb +59 -0
- data/spec/support/stubbed_session.rb +17 -0
- metadata +78 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 028df86fad5122406b9777794a31fd0b3618ad5d
|
4
|
+
data.tar.gz: 8b492ae31ae4df58236da68b478e99ece562e4a3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fcaeba290157c9d4b63fc0058849b4b9a2d9939aa5f04e51fbc1be8d97db6c8d55f145e5ddd842838f7bd17e19280ee0b46ae1a7a6b9b6bae653c4d498e5d6ad
|
7
|
+
data.tar.gz: 02b3273e0e0e7bab4eedee8af30d2b917c75a5b185d2662993d13bebba5e42c3afb65a6bf93087693a946cd4f2dc17e8ad4f8e37805e18839750914d94f5d5ac
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module HereOrThere
|
2
|
+
module Remote
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def session options={}
|
6
|
+
sessions.fetch(options) { add_session(options) }
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def sessions
|
12
|
+
@_sessions ||= {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_session options
|
16
|
+
sessions[options] = SSH.new( options )
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
class SSH
|
22
|
+
attr_reader :hostname, :user, :options
|
23
|
+
attr_reader :session
|
24
|
+
|
25
|
+
def initialize options
|
26
|
+
@options = options.dup
|
27
|
+
@hostname = @options.delete(:hostname)
|
28
|
+
@user = @options.delete(:user)
|
29
|
+
end
|
30
|
+
|
31
|
+
def run command
|
32
|
+
stdout, stderr, status = [ '', '', false ]
|
33
|
+
|
34
|
+
open_session
|
35
|
+
|
36
|
+
session.exec! command do |channel, response_type, response_data|
|
37
|
+
|
38
|
+
if response_type == :stdout
|
39
|
+
stdout = response_data
|
40
|
+
status = true
|
41
|
+
else
|
42
|
+
stderr = response_data
|
43
|
+
end
|
44
|
+
|
45
|
+
return Response.new( stdout, stderr, status )
|
46
|
+
end
|
47
|
+
|
48
|
+
# catch that odd state where no data is returned
|
49
|
+
# but the execution is successful
|
50
|
+
return Response.new( '', '', true )
|
51
|
+
|
52
|
+
rescue Net::SSH::AuthenticationFailed
|
53
|
+
close_session
|
54
|
+
return Response.new( '', 'Authentication failed when connecting to remote', false )
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def open_session
|
60
|
+
unless session && !session.closed?
|
61
|
+
@session = Net::SSH.start hostname, user, options
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def close_session
|
66
|
+
session.close unless !session || session.closed?
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module HereOrThere
|
2
|
+
class Response
|
3
|
+
attr_reader :stdout, :stderr, :status
|
4
|
+
|
5
|
+
def initialize stdout, stderr, status
|
6
|
+
@stdout = stdout
|
7
|
+
@stderr = stderr
|
8
|
+
@status = status
|
9
|
+
end
|
10
|
+
|
11
|
+
def [] key
|
12
|
+
case key
|
13
|
+
when 0 then stdout
|
14
|
+
when 1 then stderr
|
15
|
+
when 2 then status
|
16
|
+
else
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def success?
|
22
|
+
if status.respond_to? :success?
|
23
|
+
status.success?
|
24
|
+
else
|
25
|
+
status
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# util
|
2
|
+
require 'open3'
|
3
|
+
require 'net/ssh'
|
4
|
+
|
5
|
+
# gem
|
6
|
+
require 'here_or_there/version'
|
7
|
+
require 'here_or_there/response'
|
8
|
+
require 'here_or_there/local'
|
9
|
+
require 'here_or_there/remote'
|
10
|
+
|
11
|
+
module HereOrThere
|
12
|
+
|
13
|
+
def run_local command
|
14
|
+
Local.new.run command
|
15
|
+
end
|
16
|
+
|
17
|
+
def run_remote command, options={}
|
18
|
+
Remote.session( options ).run( command )
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HereOrThere::Local do
|
4
|
+
context "when not given a block" do
|
5
|
+
|
6
|
+
it "returns a Response instance" do
|
7
|
+
ret = HereOrThere::Local.new.run( 'spec/fixtures/hello_stdout')
|
8
|
+
expect( ret.is_a? HereOrThere::Response ).to be_true
|
9
|
+
end
|
10
|
+
it "returns stdout as return.stdout" do
|
11
|
+
ret = HereOrThere::Local.new.run( 'spec/fixtures/hello_stdout' )
|
12
|
+
expect( ret.stdout ).to eq "Hello Stdout\n"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "returns stderr as return.stderr" do
|
16
|
+
ret = HereOrThere::Local.new.run( 'spec/fixtures/hello_stderr' )
|
17
|
+
expect( ret.stderr ).to eq "Hello Stderr\n"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "returns a successful status for a successful command" do
|
21
|
+
ret_succ = HereOrThere::Local.new.run( 'spec/fixtures/hello_stdout' )
|
22
|
+
expect( ret_succ.success? ).to be_true
|
23
|
+
end
|
24
|
+
|
25
|
+
it "returns an unsuccessful status for an unsuccessful command" do
|
26
|
+
ret_err = HereOrThere::Local.new.run( 'spec/fixtures/hello_stderr' )
|
27
|
+
expect( ret_err.success? ).to be_false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "when given a block" do
|
32
|
+
it "yields Response" do
|
33
|
+
ret = ""
|
34
|
+
HereOrThere::Local.new.run( 'spec/fixtures/hello_stdout' ) do |response|
|
35
|
+
ret = response
|
36
|
+
end
|
37
|
+
|
38
|
+
expect( ret.class ).to eq HereOrThere::Response
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HereOrThere::Remote do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
Net::SSH.stub( start: StubbedSession.new )
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "::session" do
|
10
|
+
|
11
|
+
before :each do
|
12
|
+
if HereOrThere::Remote.send(:instance_variable_defined?, :@_sessions)
|
13
|
+
HereOrThere::Remote.send(:remove_instance_variable, :@_sessions)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it "creates an SSH object" do
|
18
|
+
expect(
|
19
|
+
HereOrThere::Remote.session( hostname: 'foo', user: 'bar' ).is_a?(HereOrThere::Remote::SSH)
|
20
|
+
).to be_true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "doesn't recreate an instance" do
|
24
|
+
first_instance = HereOrThere::Remote.session( hostname: 'foo', user: 'bar' )
|
25
|
+
expect( HereOrThere::Remote.session( hostname: 'foo', user: 'bar' ) ).to eq first_instance
|
26
|
+
end
|
27
|
+
|
28
|
+
it "creates a new instance for uniq options" do
|
29
|
+
first_instance = HereOrThere::Remote.session( hostname: 'foo', user: 'bar' )
|
30
|
+
expect( HereOrThere::Remote.session( hostname: 'wu', user: 'tang' ) ).not_to eq first_instance
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
describe HereOrThere::Remote::SSH do
|
36
|
+
|
37
|
+
before :each do
|
38
|
+
@ssh = HereOrThere::Remote::SSH.new( hostname: 'foo', user: 'bar' )
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#run" do
|
42
|
+
it "returns a response object" do
|
43
|
+
expect( @ssh.run("foo").is_a? HereOrThere::Response ).to be_true
|
44
|
+
end
|
45
|
+
|
46
|
+
context "when response is stdout" do
|
47
|
+
|
48
|
+
before :each do
|
49
|
+
StubbedSession.any_instance.stub(:exec!).and_yield("foo", :stdout, "hello stdout")
|
50
|
+
end
|
51
|
+
|
52
|
+
it "assigns response_data to Response.stdout" do
|
53
|
+
expect( @ssh.run("foo").stdout ).to eq "hello stdout"
|
54
|
+
end
|
55
|
+
|
56
|
+
it "responds with a successful response object" do
|
57
|
+
expect( @ssh.run("foo") ).to be_success
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
context "when response is stderr" do
|
63
|
+
|
64
|
+
before :each do
|
65
|
+
StubbedSession.any_instance.stub(:exec!).and_yield("foo", :stderr, "hello stderr")
|
66
|
+
end
|
67
|
+
|
68
|
+
it "assigns response_data to Response.stderr" do
|
69
|
+
expect( @ssh.run("foo").stderr ).to eq "hello stderr"
|
70
|
+
end
|
71
|
+
|
72
|
+
it "responds with an unsuccessful response object" do
|
73
|
+
expect( @ssh.run("foo") ).not_to be_success
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
context "when the block isn't called" do
|
79
|
+
# this happens when there is an empty response
|
80
|
+
# and no error from the remote
|
81
|
+
|
82
|
+
before :each do
|
83
|
+
StubbedSession.any_instance.stub(:exec!).and_return(nil)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "returns an empty successful response" do
|
87
|
+
resp = @ssh.run('foo')
|
88
|
+
|
89
|
+
expect( resp ).to be_success
|
90
|
+
expect( resp.stdout ).to eq ''
|
91
|
+
expect( resp.stderr ).to eq ''
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context "when raises Net::SSH::AuthenticationFailed" do
|
96
|
+
|
97
|
+
before :each do
|
98
|
+
StubbedSession.any_instance.stub(:exec!).and_raise(Net::SSH::AuthenticationFailed)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "returns an unsucessful response with err as stderr" do
|
102
|
+
resp = @ssh.run("foo")
|
103
|
+
expect( resp ).not_to be_success
|
104
|
+
expect( resp.stderr ).to eq "Authentication failed when connecting to remote"
|
105
|
+
end
|
106
|
+
|
107
|
+
it "closes the session" do
|
108
|
+
this_session = @ssh.session
|
109
|
+
@ssh.run("foo")
|
110
|
+
expect( @ssh.session ).not_to eq this_session
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HereOrThere::Response do
|
4
|
+
let(:response) { HereOrThere::Response.new( 'stdout', 'stderr', 'status' ) }
|
5
|
+
|
6
|
+
describe "#stdout" do
|
7
|
+
it "returns the stdout value" do
|
8
|
+
expect( response.stdout ).to eq 'stdout'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#stderr" do
|
13
|
+
it "returns the stderr value" do
|
14
|
+
expect( response.stderr ).to eq 'stderr'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#status" do
|
19
|
+
it "returns the status value" do
|
20
|
+
expect( response.status ).to eq 'status'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#[]" do
|
25
|
+
it "returns stdout for [0]" do
|
26
|
+
expect( response[0] ).to eq 'stdout'
|
27
|
+
end
|
28
|
+
it "returns stderr for [1]" do
|
29
|
+
expect( response[1] ).to eq 'stderr'
|
30
|
+
end
|
31
|
+
it "returns status for [2]" do
|
32
|
+
expect( response[2] ).to eq 'status'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#success?" do
|
37
|
+
context "when status responds to success? (an open3 response)" do
|
38
|
+
it "is truthy when process is success" do
|
39
|
+
ret_succ = HereOrThere::Local.new.run( 'spec/fixtures/hello_stdout' )
|
40
|
+
expect( ret_succ ).to be_success
|
41
|
+
end
|
42
|
+
it "is falsy when status returns err" do
|
43
|
+
ret_err = HereOrThere::Local.new.run( 'spec/fixtures/hello_stderr' )
|
44
|
+
expect( ret_err ).not_to be_success
|
45
|
+
end
|
46
|
+
end
|
47
|
+
context "when status is a boolean (a ssh response)" do
|
48
|
+
it "is truthy when status is true" do
|
49
|
+
expect( HereOrThere::Response.new( 'stdout', 'stderr', true ) ).to be_success
|
50
|
+
end
|
51
|
+
it "is falsy when status is false" do
|
52
|
+
expect( HereOrThere::Response.new( 'stdout', 'stderr', false ) ).not_to be_success
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HereOrThere do
|
4
|
+
include HereOrThere
|
5
|
+
|
6
|
+
describe "#run_local" do
|
7
|
+
it "passes the command to a Local instance" do
|
8
|
+
HereOrThere::Local.any_instance.should_receive(:run).with("foo")
|
9
|
+
|
10
|
+
run_local('foo')
|
11
|
+
end
|
12
|
+
it "returns a response object" do
|
13
|
+
expect( run_local('spec/fixtures/hello_stdout').is_a? HereOrThere::Response ).to be_true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#run_remote" do
|
18
|
+
it "passes the command to a SSH instance" do
|
19
|
+
HereOrThere::Remote::SSH.any_instance.should_receive(:run).with('ls')
|
20
|
+
|
21
|
+
run_remote( 'ls', hostname: 'foo', user: 'bar' )
|
22
|
+
end
|
23
|
+
it "returns a response object" do
|
24
|
+
HereOrThere::Remote::SSH.any_instance.stub( session: StubbedSession.new )
|
25
|
+
expect( run_remote( 'ls', hostname: 'foo', user: 'bar').is_a? HereOrThere::Response ).to be_true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# utils
|
2
|
+
# nice to have for debugging -- uncomment in gemfile to use
|
3
|
+
# require 'pry'
|
4
|
+
# require 'byebug'
|
5
|
+
|
6
|
+
# rspec support
|
7
|
+
require 'support/capture'
|
8
|
+
require 'support/stubbed_session'
|
9
|
+
|
10
|
+
# library
|
11
|
+
require 'here_or_there'
|
12
|
+
|
13
|
+
describe "support" do
|
14
|
+
|
15
|
+
describe Capture do
|
16
|
+
describe "#stdout" do
|
17
|
+
it "returns a string representation fo what is sent to stdout inside the given block" do
|
18
|
+
out = Capture.stdout { $stdout.puts "hello"; $stdout.puts "world" }
|
19
|
+
expect( out ).to eq "hello\nworld\n"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#stderr" do
|
24
|
+
it "returns a string representation fo what is sent to stderr inside the given block" do
|
25
|
+
out = Capture.stderr { $stderr.puts "hello"; $stderr.puts "world" }
|
26
|
+
expect( out ).to eq "hello\nworld\n"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
describe "fixtures" do
|
35
|
+
|
36
|
+
describe "hello_stdout" do
|
37
|
+
it "puts hello stdout to stdout" do
|
38
|
+
stdout, stderr, status = Open3.capture3('spec/fixtures/hello_stdout')
|
39
|
+
expect( stdout ).to eq "Hello Stdout\n"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "returns success code" do
|
43
|
+
stdout, stderr, status = Open3.capture3('spec/fixtures/hello_stdout')
|
44
|
+
expect( status.success? ).to be_true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "hello_stderr" do
|
49
|
+
it "puts hello stderr to stderr" do
|
50
|
+
stdout, stderr, status = Open3.capture3('spec/fixtures/hello_stderr')
|
51
|
+
expect( stderr ).to eq "Hello Stderr\n"
|
52
|
+
end
|
53
|
+
|
54
|
+
it "returns error code" do
|
55
|
+
stdout, stderr, status = Open3.capture3('spec/fixtures/hello_stderr')
|
56
|
+
expect( status.success? ).to be_false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Capture
|
2
|
+
|
3
|
+
class << self
|
4
|
+
def stdout &block
|
5
|
+
StdOut.new.capture(&block).read
|
6
|
+
end
|
7
|
+
|
8
|
+
def stderr &block
|
9
|
+
StdErr.new.capture(&block).read
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class StdOut
|
14
|
+
attr_reader :orig_stdout
|
15
|
+
attr_reader :new_stdout
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@orig_stdout = $stdout
|
19
|
+
@new_stdout = StringIO.open('','w+')
|
20
|
+
end
|
21
|
+
|
22
|
+
def capture &block
|
23
|
+
$stdout = new_stdout
|
24
|
+
yield
|
25
|
+
$stdout = orig_stdout
|
26
|
+
|
27
|
+
return self
|
28
|
+
end
|
29
|
+
|
30
|
+
def read
|
31
|
+
new_stdout.rewind
|
32
|
+
new_stdout.read
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class StdErr
|
37
|
+
attr_reader :orig_stderr
|
38
|
+
attr_reader :new_stderr
|
39
|
+
|
40
|
+
def initialize
|
41
|
+
@orig_stderr = $stderr
|
42
|
+
@new_stderr = StringIO.open('','w+')
|
43
|
+
end
|
44
|
+
|
45
|
+
def capture &block
|
46
|
+
$stderr = new_stderr
|
47
|
+
yield
|
48
|
+
$stderr = orig_stderr
|
49
|
+
|
50
|
+
return self
|
51
|
+
end
|
52
|
+
|
53
|
+
def read
|
54
|
+
new_stderr.rewind
|
55
|
+
new_stderr.read
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: here_or_there
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Steven Sloan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-10-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: net-ssh
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.6'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.6'
|
27
|
+
description: A unified interface for running local or remote commands. Provides a
|
28
|
+
dependable & identical response from both types of command.
|
29
|
+
email:
|
30
|
+
- stevenosloan@gmail.com
|
31
|
+
executables: []
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- lib/here_or_there/local.rb
|
36
|
+
- lib/here_or_there/remote.rb
|
37
|
+
- lib/here_or_there/response.rb
|
38
|
+
- lib/here_or_there/version.rb
|
39
|
+
- lib/here_or_there.rb
|
40
|
+
- spec/here_or_there/local_spec.rb
|
41
|
+
- spec/here_or_there/remote_spec.rb
|
42
|
+
- spec/here_or_there/response_spec.rb
|
43
|
+
- spec/here_or_there_spec.rb
|
44
|
+
- spec/spec_helper.rb
|
45
|
+
- spec/support/capture.rb
|
46
|
+
- spec/support/stubbed_session.rb
|
47
|
+
homepage: http://github.com/stevenosloan/here_or_there
|
48
|
+
licenses:
|
49
|
+
- MIT
|
50
|
+
metadata: {}
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options: []
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - '>='
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0'
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
requirements: []
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 2.0.5
|
68
|
+
signing_key:
|
69
|
+
specification_version: 4
|
70
|
+
summary: Unified interface for running local and remote commands
|
71
|
+
test_files:
|
72
|
+
- spec/here_or_there/local_spec.rb
|
73
|
+
- spec/here_or_there/remote_spec.rb
|
74
|
+
- spec/here_or_there/response_spec.rb
|
75
|
+
- spec/here_or_there_spec.rb
|
76
|
+
- spec/spec_helper.rb
|
77
|
+
- spec/support/capture.rb
|
78
|
+
- spec/support/stubbed_session.rb
|