blue_shell 0.6 → 0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/blue_shell/bash.rb +28 -5
- data/lib/blue_shell/version.rb +1 -1
- data/spec/blue_shell_spec.rb +16 -0
- metadata +2 -2
data/lib/blue_shell/bash.rb
CHANGED
@@ -9,14 +9,33 @@ module BlueShell
|
|
9
9
|
|
10
10
|
attr_reader :out, :err, :exit
|
11
11
|
|
12
|
+
def initialize
|
13
|
+
@hooks = { stderr: [], stdout: [] }
|
14
|
+
@executing = false
|
15
|
+
end
|
16
|
+
|
17
|
+
# Add a lambda to execute on every line of stdout. The lambda
|
18
|
+
# should accept one parameter, a string, the line of output.
|
19
|
+
# @example Pushing to the console
|
20
|
+
# lambda { |line| puts line }
|
21
|
+
# @param [Symbol] the stream to hook into (:stderr or :stdout)
|
22
|
+
# @param [Lambda] the code to execute
|
23
|
+
def add_hook(type, lambda)
|
24
|
+
# TODO: This should be a custom error
|
25
|
+
raise "May not add hooks while executing." if @executing
|
26
|
+
|
27
|
+
@hooks[type] << lambda
|
28
|
+
end
|
29
|
+
|
12
30
|
# Execute the given command. Will block until the command completes.
|
13
31
|
# param [String] the command to execute in bash
|
14
32
|
# param [Integer] the number of seconds to wait for it to complete
|
15
33
|
def execute!(command, timeout = 30)
|
16
|
-
# Executing via a file seems clunky, but it is
|
34
|
+
# Executing via a file seems clunky, but it is a good way to
|
17
35
|
# ensure everything happens exactly as we expect it to without
|
18
36
|
# trying to deal with escaping the world properly.
|
19
37
|
file = Tempfile.new('command')
|
38
|
+
|
20
39
|
begin
|
21
40
|
file << command
|
22
41
|
file.flush
|
@@ -28,8 +47,8 @@ module BlueShell
|
|
28
47
|
@err = []
|
29
48
|
|
30
49
|
# Must have a sink for stdout for the proc to exit
|
31
|
-
out_thread = read_thread(proc.getInputStream, @out)
|
32
|
-
err_thread = read_thread(proc.getErrorStream, @err)
|
50
|
+
out_thread = read_thread(:stdout, proc.getInputStream, @out)
|
51
|
+
err_thread = read_thread(:stderr, proc.getErrorStream, @err)
|
33
52
|
|
34
53
|
out_thread.join
|
35
54
|
err_thread.join
|
@@ -37,6 +56,9 @@ module BlueShell
|
|
37
56
|
@out = @out.join("\n")
|
38
57
|
@err = @err.join("\n")
|
39
58
|
|
59
|
+
# Noticed some cases where the join isn't good enough in the wild.
|
60
|
+
proc.waitFor
|
61
|
+
|
40
62
|
@exit = proc.exitValue
|
41
63
|
end
|
42
64
|
ensure
|
@@ -45,13 +67,14 @@ module BlueShell
|
|
45
67
|
end
|
46
68
|
end
|
47
69
|
|
48
|
-
def read_thread(stream, sink)
|
49
|
-
Thread.new(stream, sink) do |stream, sink|
|
70
|
+
def read_thread(type, stream, sink)
|
71
|
+
Thread.new(@hooks[type], stream, sink) do |hooks, stream, sink|
|
50
72
|
line = nil
|
51
73
|
br = BufferedReader.new(InputStreamReader.new(stream))
|
52
74
|
|
53
75
|
while(line = br.readLine) do
|
54
76
|
sink << line
|
77
|
+
hooks.each { |hook| hook.call(line) }
|
55
78
|
end
|
56
79
|
end
|
57
80
|
end
|
data/lib/blue_shell/version.rb
CHANGED
data/spec/blue_shell_spec.rb
CHANGED
@@ -25,4 +25,20 @@ describe BlueShell::Bash do
|
|
25
25
|
@shell.execute!("ls -l /")
|
26
26
|
@shell.out.must_include "\n"
|
27
27
|
end
|
28
|
+
|
29
|
+
it "should execute stdout hooks" do
|
30
|
+
me = nil
|
31
|
+
|
32
|
+
@shell.add_hook(:stdout, lambda { |line| me = line })
|
33
|
+
@shell.execute!("echo hello")
|
34
|
+
me.must_equal "hello"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should execute stderr hooks" do
|
38
|
+
me = nil
|
39
|
+
|
40
|
+
@shell.add_hook(:stderr, lambda { |line| me = line })
|
41
|
+
@shell.execute!("omg")
|
42
|
+
me.must_include "omg: command not found"
|
43
|
+
end
|
28
44
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blue_shell
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.7'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-11-
|
12
|
+
date: 2012-11-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: minitest
|