simple_shell 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -55,9 +55,20 @@ provides you with a sub shell for location shifts
55
55
  lets you specify the environment
56
56
 
57
57
  shell = SimpleShell.new(Dir.pwd, { 'MY_ENV' => 'my env' })
58
- shell.echo '${MY_ENV}'
58
+ shell.do "echo ${MY_ENV}"
59
59
  => 'my env'
60
60
 
61
+ Provides parameter escaping
62
+
63
+ shell = SimpleShell.new(Dir.pwd, { 'MY_ENV' => "You wont see me" })
64
+ shell.echo '${MY_ENV}'
65
+ => '${MY_ENV}'
66
+
67
+ shell.ls "-la", "/path/to/list"
68
+ => total 87694
69
+ => drwxr-xr-x 106 john doe 45056 Jan 15 08:43 ./
70
+ => ...
71
+
61
72
  == Contributing to SimpleShell
62
73
 
63
74
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.1
1
+ 1.1.0
data/lib/simple_shell.rb CHANGED
@@ -16,8 +16,20 @@ require 'open3'
16
16
  # end
17
17
  # puts commands.first.out
18
18
  #
19
+ # === Handling stdout and stderr
20
+ #
21
+ # shell = SimpleShell.new
22
+ # shell.stdout_handler = ->(line) {
23
+ # do_something(line)
24
+ # }
25
+ #
26
+ # shell.do("./long_running.sh")
27
+ #
28
+ # Off course the same goes for ```shell.stderr_handler```
29
+ #
19
30
  class SimpleShell
20
- attr_reader :commands
31
+ attr_reader :commands, :base, :env
32
+ attr_accessor :stdout_handler, :stderr_handler
21
33
 
22
34
  def self.noisy
23
35
  @noisy ||= false
@@ -76,7 +88,7 @@ class SimpleShell
76
88
  def system(*args, &block)
77
89
  command = nil
78
90
  Dir.chdir(@base) do
79
- command = Command.new(@base, @env)
91
+ command = Command.new(self)
80
92
  command.execute(*args, &block)
81
93
  end
82
94
 
@@ -113,9 +125,10 @@ class SimpleShell
113
125
  class Command
114
126
  attr_reader :out, :err, :S
115
127
 
116
- def initialize(base, env={})
117
- @base = base
118
- @env = env
128
+ def initialize(shell)
129
+ @shell = shell
130
+ @base = shell.base
131
+ @env = shell.env || {}
119
132
 
120
133
  @out = ""
121
134
  @err = ""
@@ -126,16 +139,34 @@ class SimpleShell
126
139
  $stderr.puts("#{@env} #{command}, #{args}, #{@base}") if SimpleShell.noisy
127
140
 
128
141
  Open3.popen3(@env, "#{command}", *(args.collect { |a| "#{a}" }) , :chdir => @base) do |stdin, stdout, stderr, thread|
142
+
143
+ threads = []
144
+ if @shell.stdout_handler
145
+ threads << Thread.new(@shell.stdout_handler, stdout) do |handler, io|
146
+ while(line = io.gets)
147
+ handler.call(line)
148
+ end
149
+ end
150
+ end
151
+
152
+ if @shell.stderr_handler
153
+ threads << Thread.new(@shell.stderr_handler, stderr) do |handler, io|
154
+ while(line = io.gets)
155
+ handler.call(line)
156
+ end
157
+ end
158
+ end
159
+
129
160
  if block_given?
130
161
  yield stdin
131
162
  end
132
163
 
133
164
  stdin.close
134
165
 
135
- # TODO : perhaps use blocks to put stuff into stdin
166
+ threads.collect(&:join)
136
167
 
137
- @out = stdout.read.chomp
138
- @err = stderr.read.chomp
168
+ @out = @shell.stdout_handler ? nil : stdout.read.chomp
169
+ @err = @shell.stderr_handler ? nil : stderr.read.chomp
139
170
  @S = thread.value rescue 0
140
171
  end
141
172
  end
data/simple_shell.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "simple_shell"
8
- s.version = "1.0.1"
8
+ s.version = "1.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Hartog C. de Mik"]
12
- s.date = "2012-02-06"
12
+ s.date = "2013-01-15"
13
13
  s.description = "A very simple, smart & elegant shell operations gem"
14
14
  s.email = "hartog@organisedminds.com"
15
15
  s.extra_rdoc_files = [
@@ -28,12 +28,15 @@ Gem::Specification.new do |s|
28
28
  "lib/simple_shell.rb",
29
29
  "simple_shell.gemspec",
30
30
  "spec/simple_shell_spec.rb",
31
- "spec/spec_helper.rb"
31
+ "spec/spec_helper.rb",
32
+ "spec/support/echo.sh",
33
+ "spec/support/echo_stderr.sh",
34
+ "spec/support/long_running.sh"
32
35
  ]
33
36
  s.homepage = "http://github.com/coffeeaddict/simple_shell"
34
37
  s.licenses = ["MIT"]
35
38
  s.require_paths = ["lib"]
36
- s.rubygems_version = "1.8.10"
39
+ s.rubygems_version = "1.8.11"
37
40
  s.summary = "A very simple shell operations gem"
38
41
 
39
42
  if s.respond_to? :specification_version then
@@ -1,5 +1,11 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
+ class Float
4
+ def at_least?(x)
5
+ self >= x
6
+ end
7
+ end
8
+
3
9
  describe SimpleShell do
4
10
  let (:shell) { SimpleShell.new }
5
11
 
@@ -62,6 +68,9 @@ describe SimpleShell do
62
68
  it "should be settable to noisy" do
63
69
  SimpleShell.noisy = true
64
70
  SimpleShell.noisy.should be_true
71
+
72
+ SimpleShell.noisy = false
73
+ SimpleShell.noisy.should be_false
65
74
  end
66
75
 
67
76
  it "should allow for environment setting" do
@@ -71,4 +80,56 @@ describe SimpleShell do
71
80
  shell = SimpleShell.new()
72
81
  shell.printenv.out.should_not =~ /my environment/
73
82
  end
83
+
84
+ it "should capture stdout" do
85
+ res = shell.do("./spec/support/echo.sh")
86
+ res.out.should == "hello\nworld"
87
+ end
88
+
89
+ it "should capture stderr" do
90
+ res = shell.do("./spec/support/echo_stderr.sh")
91
+ res.err.should == "goodbye\nworld"
92
+ end
93
+
94
+
95
+ describe "Handlers" do
96
+ it "should pass captured lines on stdout" do
97
+ buffer = []
98
+ shell.stdout_handler = ->(line) {
99
+ buffer << line
100
+ }
101
+
102
+ res = shell.echo "hello\nworld"
103
+ res.out.should be_nil
104
+ res.err.should be_empty
105
+
106
+ buffer.count.should == 2
107
+ end
108
+
109
+ it "should pass captured lines on stderr" do
110
+ buffer = []
111
+ shell.stderr_handler = ->(line) {
112
+ buffer << line
113
+ }
114
+
115
+ res = shell.do "./spec/support/echo_stderr.sh"
116
+ res.out.should be_empty
117
+ res.err.should be_nil
118
+
119
+ buffer.count.should == 2
120
+ end
121
+
122
+ it "should wait for long running processes" do
123
+ buffer = []
124
+ shell.stdout_handler = ->(line) {
125
+ buffer << line
126
+ }
127
+
128
+ start = Time.now
129
+ shell.do "./spec/support/long_running.sh"
130
+
131
+ (Time.now - start).should be_at_least 2
132
+ buffer.count.should == 3
133
+ end
134
+ end
74
135
  end
data/spec/spec_helper.rb CHANGED
@@ -8,5 +8,5 @@ require 'simple_shell'
8
8
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
9
 
10
10
  RSpec.configure do |config|
11
-
11
+ config.tty = true
12
12
  end
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+
3
+ echo "hello\nworld"
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+
3
+ echo "goodbye\nworld" >&2
@@ -0,0 +1,7 @@
1
+ #!/bin/sh
2
+
3
+ echo "i am"
4
+ sleep 1
5
+ echo "a long running"
6
+ sleep 1
7
+ echo "process"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_shell
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-06 00:00:00.000000000Z
12
+ date: 2013-01-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &89359440 !ruby/object:Gem::Requirement
16
+ requirement: &21277180 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 2.8.0
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *89359440
24
+ version_requirements: *21277180
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rdoc
27
- requirement: &89359170 !ruby/object:Gem::Requirement
27
+ requirement: &21308340 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '3.12'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *89359170
35
+ version_requirements: *21308340
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: bundler
38
- requirement: &89358920 !ruby/object:Gem::Requirement
38
+ requirement: &21306480 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 1.0.0
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *89358920
46
+ version_requirements: *21306480
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: jeweler
49
- requirement: &89358670 !ruby/object:Gem::Requirement
49
+ requirement: &21304760 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.8.3
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *89358670
57
+ version_requirements: *21304760
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rcov
60
- requirement: &89358390 !ruby/object:Gem::Requirement
60
+ requirement: &21302760 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *89358390
68
+ version_requirements: *21302760
69
69
  description: A very simple, smart & elegant shell operations gem
70
70
  email: hartog@organisedminds.com
71
71
  executables: []
@@ -86,6 +86,9 @@ files:
86
86
  - simple_shell.gemspec
87
87
  - spec/simple_shell_spec.rb
88
88
  - spec/spec_helper.rb
89
+ - spec/support/echo.sh
90
+ - spec/support/echo_stderr.sh
91
+ - spec/support/long_running.sh
89
92
  homepage: http://github.com/coffeeaddict/simple_shell
90
93
  licenses:
91
94
  - MIT
@@ -101,7 +104,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
101
104
  version: '0'
102
105
  segments:
103
106
  - 0
104
- hash: 737581693
107
+ hash: -4461510089210425580
105
108
  required_rubygems_version: !ruby/object:Gem::Requirement
106
109
  none: false
107
110
  requirements:
@@ -110,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
110
113
  version: '0'
111
114
  requirements: []
112
115
  rubyforge_project:
113
- rubygems_version: 1.8.10
116
+ rubygems_version: 1.8.11
114
117
  signing_key:
115
118
  specification_version: 3
116
119
  summary: A very simple shell operations gem