simple_shell 1.0.1 → 1.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.
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