net-ssh-shell 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.
- data/.gitignore +4 -0
- data/CHANGELOG.md +10 -0
- data/Gemfile +3 -0
- data/README.rdoc +3 -3
- data/Rakefile +3 -28
- data/lib/net/ssh/shell.rb +65 -35
- data/lib/net/ssh/shell/process.rb +38 -30
- data/lib/net/ssh/shell/subshell.rb +12 -14
- data/lib/net/ssh/shell/version.rb +6 -21
- data/net-ssh-shell.gemspec +17 -27
- metadata +33 -46
- data/CHANGELOG.rdoc +0 -3
- data/Manifest +0 -8
data/.gitignore
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
## 0.2.0 (unreleased)
|
2
|
+
|
3
|
+
- Loosen regex on `on_stdout` [GH-1]
|
4
|
+
- Capture stderr from shell. This won't capture the stderr of the processes
|
5
|
+
running. Instead it will just capture any error output from the shell process.
|
6
|
+
- Ability to specify the default process class to use for `Shell#execute`
|
7
|
+
|
8
|
+
## 0.1.0 (October 24, 2010)
|
9
|
+
|
10
|
+
- Initial release
|
data/Gemfile
ADDED
data/README.rdoc
CHANGED
@@ -41,12 +41,12 @@ If you want to use any of the Rake tasks, you'll need:
|
|
41
41
|
* Echoe (for the Rakefile)
|
42
42
|
|
43
43
|
== INSTALL:
|
44
|
-
|
44
|
+
|
45
|
+
This gem is available from RubyGems, so you can install it using the "gem" command:
|
45
46
|
|
46
47
|
* gem install net-ssh-shell
|
47
|
-
ERROR: could not find gem net-ssh-shell locally or in a repository
|
48
48
|
|
49
|
-
|
49
|
+
If you'd like to build the gem for yourself from source:
|
50
50
|
* git clone http://github.com/jedi4ever/net-ssh-shell.git
|
51
51
|
* cd net-ssh-shell
|
52
52
|
* gem install echoe
|
data/Rakefile
CHANGED
@@ -1,28 +1,3 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
|
4
|
-
require 'echoe'
|
5
|
-
rescue LoadError
|
6
|
-
abort "You'll need to have `echoe' installed to use Net::SSH::Shell's Rakefile"
|
7
|
-
end
|
8
|
-
|
9
|
-
version = Net::SSH::Shell::Version::STRING.dup
|
10
|
-
if ENV['SNAPSHOT'].to_i == 1
|
11
|
-
version << "." << Time.now.utc.strftime("%Y%m%d%H%M%S")
|
12
|
-
end
|
13
|
-
|
14
|
-
Echoe.new('net-ssh-shell', version) do |p|
|
15
|
-
p.changelog = "CHANGELOG.rdoc"
|
16
|
-
|
17
|
-
p.author = "Jamis Buck"
|
18
|
-
p.email = "jamis@jamisbuck.org"
|
19
|
-
p.summary = "A simple library to aid with stateful shell interactions"
|
20
|
-
p.url = "http://net-ssh.rubyforge.org/shell"
|
21
|
-
|
22
|
-
p.dependencies = ["net-ssh >=2.0.9"]
|
23
|
-
|
24
|
-
p.need_zip = true
|
25
|
-
p.include_rakefile = true
|
26
|
-
|
27
|
-
p.rdoc_pattern = /^(lib|README.rdoc|CHANGELOG.rdoc)/
|
28
|
-
end
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
Bundler::GemHelper.install_tasks
|
data/lib/net/ssh/shell.rb
CHANGED
@@ -11,6 +11,7 @@ module Net
|
|
11
11
|
attr_reader :state
|
12
12
|
attr_reader :shell
|
13
13
|
attr_reader :processes
|
14
|
+
attr_accessor :default_process_class
|
14
15
|
|
15
16
|
def initialize(session, shell=:default)
|
16
17
|
@session = session
|
@@ -18,6 +19,8 @@ module Net
|
|
18
19
|
@state = :closed
|
19
20
|
@processes = []
|
20
21
|
@when_open = []
|
22
|
+
@on_process_run = nil
|
23
|
+
@default_process_class = Net::SSH::Shell::Process
|
21
24
|
open
|
22
25
|
end
|
23
26
|
|
@@ -26,6 +29,7 @@ module Net
|
|
26
29
|
@state = :opening
|
27
30
|
@channel = session.open_channel(&method(:open_succeeded))
|
28
31
|
@channel.on_open_failed(&method(:open_failed))
|
32
|
+
@channel.on_request('exit-status', &method(:on_exit_status))
|
29
33
|
end
|
30
34
|
when_open(&callback) if callback
|
31
35
|
self
|
@@ -60,11 +64,23 @@ module Net
|
|
60
64
|
!open? && !closed?
|
61
65
|
end
|
62
66
|
|
63
|
-
def
|
64
|
-
|
65
|
-
|
67
|
+
def on_process_run(&callback)
|
68
|
+
@on_process_run = callback
|
69
|
+
end
|
70
|
+
|
71
|
+
def execute(command, *args, &callback)
|
72
|
+
# The class is an optional second argument.
|
73
|
+
klass = default_process_class
|
74
|
+
klass = args.shift if args.first.is_a?(Class)
|
75
|
+
|
76
|
+
# The properties are expected to be the next argument.
|
77
|
+
props = {}
|
78
|
+
props = args.shift if args.first.is_a?(Hash)
|
79
|
+
|
80
|
+
process = klass.new(self, command, props, callback)
|
66
81
|
processes << process
|
67
|
-
|
82
|
+
run_next_process if processes.length == 1
|
83
|
+
process
|
68
84
|
end
|
69
85
|
|
70
86
|
def subshell(command, &callback)
|
@@ -72,9 +88,9 @@ module Net
|
|
72
88
|
end
|
73
89
|
|
74
90
|
def execute!(command, &callback)
|
75
|
-
execute(command, &callback)
|
91
|
+
process = execute(command, &callback)
|
76
92
|
wait!
|
77
|
-
|
93
|
+
process
|
78
94
|
end
|
79
95
|
|
80
96
|
def busy?
|
@@ -92,7 +108,7 @@ module Net
|
|
92
108
|
def child_finished(child)
|
93
109
|
channel.on_close(&method(:on_channel_close)) if !channel.nil?
|
94
110
|
processes.delete(child)
|
95
|
-
|
111
|
+
run_next_process
|
96
112
|
end
|
97
113
|
|
98
114
|
def separator
|
@@ -109,41 +125,55 @@ module Net
|
|
109
125
|
|
110
126
|
private
|
111
127
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
128
|
+
def run_next_process
|
129
|
+
if processes.any?
|
130
|
+
process = processes.first
|
131
|
+
@on_process_run.call(self, process) if @on_process_run
|
132
|
+
process.run
|
116
133
|
end
|
134
|
+
end
|
117
135
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
136
|
+
def open_succeeded(channel)
|
137
|
+
@state = :pty
|
138
|
+
channel.on_close(&method(:on_channel_close))
|
139
|
+
channel.request_pty(:modes => { Net::SSH::Connection::Term::ECHO => 0 }, &method(:pty_requested))
|
140
|
+
end
|
141
|
+
|
142
|
+
def open_failed(channel, code, description)
|
143
|
+
@state = :closed
|
144
|
+
raise "could not open channel for process manager (#{description}, ##{code})"
|
145
|
+
end
|
122
146
|
|
123
|
-
|
124
|
-
|
125
|
-
raise "
|
126
|
-
if shell == :default
|
127
|
-
channel.send_channel_request("shell", &method(:shell_requested))
|
128
|
-
else
|
129
|
-
channel.exec(shell, &method(:shell_requested))
|
130
|
-
end
|
147
|
+
def on_exit_status(channel, data)
|
148
|
+
unless data.read_long == 0
|
149
|
+
raise "the shell exited unexpectedly"
|
131
150
|
end
|
151
|
+
end
|
132
152
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
channel.
|
153
|
+
def pty_requested(channel, success)
|
154
|
+
@state = :shell
|
155
|
+
raise "could not request pty for process manager" unless success
|
156
|
+
if shell == :default
|
157
|
+
channel.send_channel_request("shell", &method(:shell_requested))
|
158
|
+
else
|
159
|
+
channel.exec(shell, &method(:shell_requested))
|
138
160
|
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def shell_requested(channel, success)
|
164
|
+
@state = :initializing
|
165
|
+
raise "could not request shell for process manager" unless success
|
166
|
+
channel.on_data(&method(:look_for_initialization_done))
|
167
|
+
channel.send_data "export PS1=; echo #{separator} $?\n"
|
168
|
+
end
|
139
169
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
end
|
170
|
+
def look_for_initialization_done(channel, data)
|
171
|
+
if data.include?(separator)
|
172
|
+
@state = :open
|
173
|
+
@when_open.each { |callback| callback.call(self) }
|
174
|
+
@when_open.clear
|
146
175
|
end
|
176
|
+
end
|
147
177
|
end
|
148
178
|
end
|
149
179
|
end
|
@@ -155,6 +185,6 @@ class Net::SSH::Connection::Session
|
|
155
185
|
def shell(*args)
|
156
186
|
shell = Net::SSH::Shell.new(self, *args)
|
157
187
|
yield shell if block_given?
|
158
|
-
|
188
|
+
shell
|
159
189
|
end
|
160
190
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module Net; module SSH; class Shell
|
2
|
-
|
3
2
|
class Process
|
4
3
|
attr_reader :state
|
5
4
|
attr_reader :command
|
@@ -8,12 +7,13 @@ module Net; module SSH; class Shell
|
|
8
7
|
attr_reader :exit_status
|
9
8
|
attr_reader :properties
|
10
9
|
|
11
|
-
def initialize(manager, command, callback)
|
10
|
+
def initialize(manager, command, properties, callback)
|
12
11
|
@command = command
|
13
12
|
@manager = manager
|
14
13
|
@callback = callback
|
15
|
-
@properties =
|
16
|
-
@on_output =
|
14
|
+
@properties = properties
|
15
|
+
@on_output = nil
|
16
|
+
@on_error_output = nil
|
17
17
|
@on_finish = nil
|
18
18
|
@state = :new
|
19
19
|
end
|
@@ -36,14 +36,16 @@ module Net; module SSH; class Shell
|
|
36
36
|
manager.open do
|
37
37
|
state = :running
|
38
38
|
manager.channel.on_data(&method(:on_stdout))
|
39
|
-
|
39
|
+
manager.channel.on_extended_data(&method(:on_stderr))
|
40
|
+
manager.channel.on_close(&method(:on_close))
|
41
|
+
|
42
|
+
callback.call(self) if callback
|
40
43
|
|
41
44
|
cmd = command.dup
|
42
45
|
cmd << ";" if cmd !~ /[;&]$/
|
43
46
|
cmd << " DONTEVERUSETHIS=$?; echo #{manager.separator} $DONTEVERUSETHIS; echo \"exit $DONTEVERUSETHIS\"|sh"
|
44
47
|
|
45
48
|
send_data(cmd + "\n")
|
46
|
-
callback.call(self) if callback
|
47
49
|
end
|
48
50
|
end
|
49
51
|
|
@@ -75,38 +77,44 @@ module Net; module SSH; class Shell
|
|
75
77
|
@on_output = callback
|
76
78
|
end
|
77
79
|
|
80
|
+
def on_error_output(&callback)
|
81
|
+
@on_error_output = callback
|
82
|
+
end
|
83
|
+
|
78
84
|
def on_finish(&callback)
|
79
85
|
@on_finish = callback
|
80
86
|
end
|
81
87
|
|
82
|
-
|
88
|
+
protected
|
83
89
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
end
|
90
|
+
def output!(data)
|
91
|
+
@on_output.call(self, data) if @on_output
|
92
|
+
end
|
88
93
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
end
|
94
|
+
def on_stdout(ch, data)
|
95
|
+
if data.strip =~ /#{manager.separator} (\d+)$/
|
96
|
+
before = $`
|
97
|
+
output!(before) unless before.empty?
|
98
|
+
finished!($1)
|
99
|
+
else
|
100
|
+
output!(data)
|
97
101
|
end
|
102
|
+
end
|
98
103
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
end
|
104
|
+
def on_stderr(ch, type, data)
|
105
|
+
@on_error_output.call(self, data) if @on_error_output
|
106
|
+
end
|
103
107
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
manager.child_finished(self)
|
109
|
-
end
|
110
|
-
end
|
108
|
+
def on_close(ch)
|
109
|
+
manager.on_channel_close(ch)
|
110
|
+
finished!(-1)
|
111
|
+
end
|
111
112
|
|
113
|
+
def finished!(status)
|
114
|
+
@state = :finished
|
115
|
+
@exit_status = status.to_i
|
116
|
+
@on_finish.call(self) if @on_finish
|
117
|
+
manager.child_finished(self)
|
118
|
+
end
|
119
|
+
end
|
112
120
|
end; end; end
|
@@ -1,23 +1,21 @@
|
|
1
1
|
require 'net/ssh/shell/process'
|
2
2
|
|
3
3
|
module Net; module SSH; class Shell
|
4
|
-
|
5
4
|
class Subshell < Process
|
6
|
-
|
5
|
+
protected
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
7
|
+
def on_stdout(ch, data)
|
8
|
+
if !output!(data)
|
9
|
+
ch.on_data(&method(:look_for_finalize_initializer))
|
10
|
+
ch.send_data("export PS1=; echo #{manager.separator} $?\n")
|
13
11
|
end
|
12
|
+
end
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
14
|
+
def look_for_finalize_initializer(ch, data)
|
15
|
+
if data =~ /#{manager.separator} (\d+)/
|
16
|
+
ch.on_close(&@master_onclose)
|
17
|
+
finished!($1)
|
20
18
|
end
|
19
|
+
end
|
21
20
|
end
|
22
|
-
|
23
|
-
end; end; end
|
21
|
+
end; end; end
|
@@ -1,22 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
# The major component of the library's version
|
7
|
-
MAJOR = 0
|
8
|
-
|
9
|
-
# The minor component of the library's version
|
10
|
-
MINOR = 1
|
11
|
-
|
12
|
-
# The tiny component of the library's version
|
13
|
-
TINY = 0
|
14
|
-
|
15
|
-
# The library's version as a Version instance
|
16
|
-
CURRENT = new(MAJOR, MINOR, TINY)
|
17
|
-
|
18
|
-
# The library's version as a String instance
|
19
|
-
STRING = CURRENT.to_s
|
1
|
+
module Net
|
2
|
+
module SSH
|
3
|
+
class Shell
|
4
|
+
VERSION = "0.2.0"
|
5
|
+
end
|
20
6
|
end
|
21
|
-
end
|
22
|
-
|
7
|
+
end
|
data/net-ssh-shell.gemspec
CHANGED
@@ -1,33 +1,23 @@
|
|
1
|
-
|
1
|
+
require File.expand_path("../lib/net/ssh/shell/version", __FILE__)
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
|
-
s.name
|
5
|
-
s.version
|
4
|
+
s.name = "net-ssh-shell"
|
5
|
+
s.version = Net::SSH::Shell::VERSION
|
6
|
+
s.platform = Gem::Platform::RUBY
|
7
|
+
s.authors = ["Jamis Buck"]
|
8
|
+
s.email = ["jamis@jamisbuck.org"]
|
9
|
+
s.homepage = "http://github.com/mitchellh/net-ssh-shell"
|
10
|
+
s.summary = "A simple library to aid with stateful shell interactions"
|
11
|
+
s.description = "A simple library to aid with stateful shell interactions"
|
6
12
|
|
7
|
-
s.required_rubygems_version =
|
8
|
-
s.
|
9
|
-
s.date = %q{2010-10-25}
|
10
|
-
s.description = %q{A simple library to aid with stateful shell interactions}
|
11
|
-
s.email = %q{jamis@jamisbuck.org}
|
12
|
-
s.extra_rdoc_files = ["CHANGELOG.rdoc", "lib/net/ssh/shell/process.rb", "lib/net/ssh/shell/subshell.rb", "lib/net/ssh/shell/version.rb", "lib/net/ssh/shell.rb", "README.rdoc"]
|
13
|
-
s.files = ["CHANGELOG.rdoc", "lib/net/ssh/shell/process.rb", "lib/net/ssh/shell/subshell.rb", "lib/net/ssh/shell/version.rb", "lib/net/ssh/shell.rb", "Rakefile", "README.rdoc", "Manifest", "net-ssh-shell.gemspec"]
|
14
|
-
s.homepage = %q{http://net-ssh.rubyforge.org/shell}
|
15
|
-
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Net-ssh-shell", "--main", "README.rdoc"]
|
16
|
-
s.require_paths = ["lib"]
|
17
|
-
s.rubyforge_project = %q{net-ssh-shell}
|
18
|
-
s.rubygems_version = %q{1.3.7}
|
19
|
-
s.summary = %q{A simple library to aid with stateful shell interactions}
|
13
|
+
s.required_rubygems_version = ">= 1.3.6"
|
14
|
+
s.rubyforge_project = "net-ssh-shell"
|
20
15
|
|
21
|
-
|
22
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
23
|
-
s.specification_version = 3
|
16
|
+
s.add_dependency "net-ssh", "~> 2.1.0"
|
24
17
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
else
|
31
|
-
s.add_dependency(%q<net-ssh>, [">= 2.0.9"])
|
32
|
-
end
|
18
|
+
s.add_development_dependency "rake"
|
19
|
+
|
20
|
+
s.files = `git ls-files`.split("\n")
|
21
|
+
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
22
|
+
s.require_path = 'lib'
|
33
23
|
end
|
metadata
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: net-ssh-shell
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 1
|
9
|
-
- 0
|
10
|
-
version: 0.1.0
|
4
|
+
prerelease:
|
5
|
+
version: 0.2.0
|
11
6
|
platform: ruby
|
12
7
|
authors:
|
13
8
|
- Jamis Buck
|
@@ -15,60 +10,56 @@ autorequire:
|
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
12
|
|
18
|
-
date:
|
19
|
-
default_executable:
|
13
|
+
date: 2011-06-13 00:00:00 Z
|
20
14
|
dependencies:
|
21
15
|
- !ruby/object:Gem::Dependency
|
22
16
|
name: net-ssh
|
23
|
-
prerelease: false
|
24
17
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
18
|
none: false
|
26
19
|
requirements:
|
27
|
-
- -
|
20
|
+
- - ~>
|
28
21
|
- !ruby/object:Gem::Version
|
29
|
-
|
30
|
-
segments:
|
31
|
-
- 2
|
32
|
-
- 0
|
33
|
-
- 9
|
34
|
-
version: 2.0.9
|
22
|
+
version: 2.1.0
|
35
23
|
type: :runtime
|
24
|
+
prerelease: false
|
36
25
|
version_requirements: *id001
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rake
|
28
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *id002
|
37
37
|
description: A simple library to aid with stateful shell interactions
|
38
|
-
email:
|
38
|
+
email:
|
39
|
+
- jamis@jamisbuck.org
|
39
40
|
executables: []
|
40
41
|
|
41
42
|
extensions: []
|
42
43
|
|
43
|
-
extra_rdoc_files:
|
44
|
-
|
45
|
-
- lib/net/ssh/shell/process.rb
|
46
|
-
- lib/net/ssh/shell/subshell.rb
|
47
|
-
- lib/net/ssh/shell/version.rb
|
48
|
-
- lib/net/ssh/shell.rb
|
49
|
-
- README.rdoc
|
44
|
+
extra_rdoc_files: []
|
45
|
+
|
50
46
|
files:
|
51
|
-
-
|
47
|
+
- .gitignore
|
48
|
+
- CHANGELOG.md
|
49
|
+
- Gemfile
|
50
|
+
- README.rdoc
|
51
|
+
- Rakefile
|
52
|
+
- lib/net/ssh/shell.rb
|
52
53
|
- lib/net/ssh/shell/process.rb
|
53
54
|
- lib/net/ssh/shell/subshell.rb
|
54
55
|
- lib/net/ssh/shell/version.rb
|
55
|
-
- lib/net/ssh/shell.rb
|
56
|
-
- Rakefile
|
57
|
-
- README.rdoc
|
58
|
-
- Manifest
|
59
56
|
- net-ssh-shell.gemspec
|
60
|
-
|
61
|
-
homepage: http://net-ssh.rubyforge.org/shell
|
57
|
+
homepage: http://github.com/mitchellh/net-ssh-shell
|
62
58
|
licenses: []
|
63
59
|
|
64
60
|
post_install_message:
|
65
|
-
rdoc_options:
|
66
|
-
|
67
|
-
- --inline-source
|
68
|
-
- --title
|
69
|
-
- Net-ssh-shell
|
70
|
-
- --main
|
71
|
-
- README.rdoc
|
61
|
+
rdoc_options: []
|
62
|
+
|
72
63
|
require_paths:
|
73
64
|
- lib
|
74
65
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -76,7 +67,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
76
67
|
requirements:
|
77
68
|
- - ">="
|
78
69
|
- !ruby/object:Gem::Version
|
79
|
-
hash:
|
70
|
+
hash: -9612031956568265
|
80
71
|
segments:
|
81
72
|
- 0
|
82
73
|
version: "0"
|
@@ -85,15 +76,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
85
76
|
requirements:
|
86
77
|
- - ">="
|
87
78
|
- !ruby/object:Gem::Version
|
88
|
-
|
89
|
-
segments:
|
90
|
-
- 1
|
91
|
-
- 2
|
92
|
-
version: "1.2"
|
79
|
+
version: 1.3.6
|
93
80
|
requirements: []
|
94
81
|
|
95
82
|
rubyforge_project: net-ssh-shell
|
96
|
-
rubygems_version: 1.
|
83
|
+
rubygems_version: 1.8.5
|
97
84
|
signing_key:
|
98
85
|
specification_version: 3
|
99
86
|
summary: A simple library to aid with stateful shell interactions
|
data/CHANGELOG.rdoc
DELETED