Skip to content

Commit

Permalink
adds executable tests for README examples; removes CWI hanging pry
Browse files Browse the repository at this point in the history
  • Loading branch information
gruis committed Mar 26, 2013
1 parent 12597fd commit 3b3b5f8
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 21 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
readme.*.rb
tags

*.gem
Expand Down
1 change: 0 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
source "http://rubygems.org"

gem "em-ssh", :path => File.expand_path("../", __FILE__)
gem "pry"
gemspec

group :development do
Expand Down
8 changes: 0 additions & 8 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,10 @@ GEM
remote: http://rubygems.org/
specs:
bluecloth (2.1.0)
coderay (1.0.8)
diff-lcs (1.1.3)
eventmachine (1.0.1)
highline (1.6.13)
method_source (0.8.1)
net-ssh (2.6.2)
pry (0.9.10)
coderay (~> 1.0.5)
method_source (~> 0.8)
slop (~> 3.3.1)
rspec (2.6.0)
rspec-core (~> 2.6.0)
rspec-expectations (~> 2.6.0)
Expand All @@ -28,7 +22,6 @@ GEM
diff-lcs (~> 1.1.2)
rspec-mocks (2.6.0)
ruby-termios (0.9.6)
slop (3.3.3)
yard (0.7.3)

PLATFORMS
Expand All @@ -38,7 +31,6 @@ DEPENDENCIES
bluecloth
em-ssh!
highline
pry
rspec (> 2.2.0)
rspec-core (< 2.7.0)
ruby-termios
Expand Down
24 changes: 13 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ Em-ssh is not associated with the Jamis Buck's [net-ssh](http://net-ssh.github.c
##Synopsis

```ruby
require "em-ssh"
EM.run do
EM::Ssh.start(host, user, :password => password) do |connection|
connection.errback do |err|
$stderr.puts "#{err} (#{err.class})"
EM.stop
end
connection.callback do |ssh|
# capture all stderr and stdout output from a remote process
Expand Down Expand Up @@ -76,7 +78,7 @@ EM.run do
EM.stop
end
shell.errback do |err|
puts "error: #{err} (#{err.class})"
$stderr.puts "error: #{err} (#{err.class})"
EM.stop
end
end
Expand All @@ -93,7 +95,7 @@ commands = ["uname -a", "uptime", "ifconfig"]
EM.run do
EM::Ssh::Shell.new(host, user, "") do |shell|
shell.errback do |err|
puts "error: #{err} (#{err.class})"
$stderr.puts "error: #{err} (#{err.class})"
EM.stop
end

Expand All @@ -107,19 +109,19 @@ EM.run do
end

mys.callback do
puts("waiting for: #{waitstr.inspect}")
$stderr.puts("waiting for: #{waitstr.inspect}")
# When given a block, Shell#expect does not 'block'
mys.expect(waitstr) do
puts "sending #{command.inspect} and waiting for #{waitstr.inspect}"
$stderr.puts "sending #{command.inspect} and waiting for #{waitstr.inspect}"
mys.expect(waitstr, command) do |result|
puts "#{mys} result: '#{result}'"
$stderr.puts "#{mys} result: '#{result}'"
mys.close
end
end
end

mys.errback do |err|
puts "subshell error: #{err} (#{err.class})"
$stderr.puts "subshell error: #{err} (#{err.class})"
mys.close
end

Expand All @@ -138,8 +140,8 @@ require 'em-ssh/shell'
EM.run do
EM::Ssh::Shell.new(host, user, "") do |shell|
shell.errback do |err|
puts "error: #{err} (#{err.class})"
puts err.backtrace
$stderr.puts "error: #{err} (#{err.class})"
$stderr.puts err.backtrace
EM.stop
end

Expand All @@ -155,16 +157,16 @@ EM.run do
EM.stop if commands.empty?
end
mys.errback do |err|
puts "subshell error: #{err} (#{err.class})"
$stderr.puts "subshell error: #{err} (#{err.class})"
mys.close
end

mys.expect(waitstr)
result = mys.expect(waitstr, command)
puts "#{mys} result: '#{result.inspect}'"
$stderr.puts "#{mys} result: '#{result.inspect}'"
result
end
puts "split result: #{sresult.inspect} +++"
$stderr.puts "split result: #{sresult.inspect} +++"
}.resume

end
Expand Down
55 changes: 55 additions & 0 deletions readme/1.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env ruby
require File.expand_path("../arg-parser", __FILE__)

host, user = require_host_user

require "em-ssh"
EM.run do
EM::Ssh.start(host, user) do |connection|
connection.errback do |err|
$stderr.puts "#{err} (#{err.class})"
EM.stop
end
connection.callback do |ssh|
# capture all stderr and stdout output from a remote process
ssh.exec!('uname -a').tap {|r| puts "\nuname: #{r}"}

# capture only stdout matching a particular pattern
stdout = ""
ssh.exec!("ls -l /home") do |channel, stream, data|
stdout << data if stream == :stdout
end
puts "\n#{stdout}"

# run multiple processes in parallel to completion
ssh.exec('ping -c 1 www.google.com')
ssh.exec('ping -c 1 www.yahoo.com')
ssh.exec('ping -c 1 www.rakuten.co.jp')

#open a new channel and configure a minimal set of callbacks, then wait for the channel to finishes (closees).
channel = ssh.open_channel do |ch|
ch.exec "/usr/local/bin/ruby /path/to/file.rb" do |ch, success|
raise "could not execute command" unless success

# "on_data" is called when the process writes something to stdout
ch.on_data do |c, data|
$stdout.print data
end

# "on_extended_data" is called when the process writes something to stderr
ch.on_extended_data do |c, type, data|
$stderr.print data
end

ch.on_close { puts "done!" }
end
end

channel.wait

ssh.close
EM.stop
end
end
end

21 changes: 21 additions & 0 deletions readme/2.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env ruby
require File.expand_path("../arg-parser", __FILE__)

host, user = require_host_user

require 'em-ssh/shell'
EM.run do
EM::Ssh::Shell.new(host, user, "") do |shell|
shell.callback do
shell.expect(Regexp.escape('~]$ '))
$stderr.puts shell.expect(Regexp.escape('~]$ '),'uname -a')
$stderr.puts shell.expect(Regexp.escape('~]$ '), '/sbin/ifconfig -a')
EM.stop
end
shell.errback do |err|
$stderr.puts "error: #{err} (#{err.class})"
EM.stop
end
end
end

46 changes: 46 additions & 0 deletions readme/3.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/usr/bin/env ruby
require File.expand_path("../arg-parser", __FILE__)

host, user = require_host_user

require 'em-ssh/shell'

waitstr = Regexp.escape('~]$ ')
commands = ["uname -a", "uptime", "ifconfig"]
EM.run do
EM::Ssh::Shell.new(host, user, "") do |shell|
shell.errback do |err|
$stderr.puts "error: #{err} (#{err.class})"
EM.stop
end

shell.callback do
commands.clone.each do |command|
mys = shell.split # provides a second session over the same connection

mys.on(:closed) do
commands.delete(command)
EM.stop if commands.empty?
end

mys.callback do
$stderr.puts("waiting for: #{waitstr.inspect}")
# When given a block, Shell#expect does not 'block'
mys.expect(waitstr) do
$stderr.puts "sending #{command.inspect} and waiting for #{waitstr.inspect}"
mys.expect(waitstr, command) do |result|
$stderr.puts "#{mys} result: '#{result}'"
mys.close
end
end
end

mys.errback do |err|
$stderr.puts "subshell error: #{err} (#{err.class})"
mys.close
end

end
end
end
end
46 changes: 46 additions & 0 deletions readme/4.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/usr/bin/env ruby
require "em-ssh"
require File.expand_path("../arg-parser", __FILE__)

host, user = require_host_user

waitstr = Regexp.escape('~]$ ')
commands = ["uname -a", "uptime", "ifconfig"]

require 'em-ssh/shell'
EM.run do
EM::Ssh::Shell.new(host, user, "") do |shell|
shell.errback do |err|
$stderr.puts "error: #{err} (#{err.class})"
$stderr.puts err.backtrace
EM.stop
end

shell.callback do
commands.clone.each do |command|
Fiber.new {
# When given a block Shell#split will close the Shell after
# the block returns. If a block is given it must be called
# within a Fiber.
sresult = shell.split do |mys|
mys.on(:closed) do
commands.delete(command)
EM.stop if commands.empty?
end
mys.errback do |err|
$stderr.puts "subshell error: #{err} (#{err.class})"
mys.close
end

mys.expect(waitstr)
result = mys.expect(waitstr, command)
$stderr.puts "#{mys} result: '#{result.inspect}'"
result
end
$stderr.puts "split result: #{sresult.inspect} +++"
}.resume

end
end
end
end
17 changes: 17 additions & 0 deletions readme/arg-parser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
require "optparse"

def require_host_user
summary =<<-SUMM
A simple utility corresponding to a usage example in the
[em-ssh](https://github.com/simulacre/em-ssh/) README. It requries a
single argument user@host. You use must have an authorized ssh public
key on the target host. After logging in a few non-destructive commands
will be executed.
SUMM

host = nil
user = nil
user,host = ARGV[0].split("@") if ARGV[0]
abort "Usage: #{File.basename($0)} user@host\n\n#{summary}" if ARGV.include?("-h") || host.nil? || user.nil?
[host, user]
end

0 comments on commit 3b3b5f8

Please sign in to comment.