systemu 2.4.2 → 2.5.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 CHANGED
@@ -4,7 +4,8 @@ NAME
4
4
 
5
5
  SYNOPSIS
6
6
 
7
- univeral capture of stdout and stderr and handling of child process pid for windows, *nix, etc.
7
+ universal capture of stdout and stderr and handling of child process pid for
8
+ windows, *nix, etc.
8
9
 
9
10
  URIS
10
11
 
data/lib/systemu.rb CHANGED
@@ -1,4 +1,5 @@
1
- # vim: ts=2:sw=2:sts=2:et:fdm=marker
1
+ # encoding: utf-8
2
+
2
3
  require 'tmpdir'
3
4
  require 'socket'
4
5
  require 'fileutils'
@@ -13,7 +14,7 @@ class SystemUniversal
13
14
  #
14
15
  # constants
15
16
  #
16
- SystemUniversal::VERSION = '2.4.2' unless SystemUniversal.send(:const_defined?, :VERSION)
17
+ SystemUniversal::VERSION = '2.5.0' unless SystemUniversal.send(:const_defined?, :VERSION)
17
18
  def SystemUniversal.version() SystemUniversal::VERSION end
18
19
  def version() SystemUniversal::VERSION end
19
20
  #
@@ -76,7 +77,7 @@ class SystemUniversal
76
77
  line = pipe.gets
77
78
  case line
78
79
  when %r/^pid: \d+$/
79
- cid = Integer line[%r/\d+/]
80
+ cid = Integer line[%r/\d+/]
80
81
  else
81
82
  begin
82
83
  buf = pipe.read
@@ -120,12 +121,12 @@ class SystemUniversal
120
121
  SystemUniversal.quote(*args, &block)
121
122
  end
122
123
 
123
- def new_thread cid, block
124
+ def new_thread cid, block
124
125
  q = Queue.new
125
- Thread.new(cid) do |cid|
126
- current = Thread.current
126
+ Thread.new(cid) do |cid|
127
+ current = Thread.current
127
128
  current.abort_on_exception = true
128
- q.push current
129
+ q.push current
129
130
  block.call cid
130
131
  end
131
132
  q.pop
@@ -150,10 +151,10 @@ class SystemUniversal
150
151
  c['argv'] = @argv
151
152
  c['env'] = @env
152
153
  c['cwd'] = @cwd
153
- c['stdin'] = stdin
154
- c['stdout'] = stdout
155
- c['stderr'] = stderr
156
- c['program'] = program
154
+ c['stdin'] = stdin
155
+ c['stdout'] = stdout
156
+ c['stderr'] = stderr
157
+ c['program'] = program
157
158
  open(config, 'w'){|f| Marshal.dump(c, f)}
158
159
 
159
160
  open(program, 'w'){|f| f.write child_program(config)}
@@ -171,6 +172,8 @@ class SystemUniversal
171
172
 
172
173
  def child_program config
173
174
  <<-program
175
+ # encoding: utf-8
176
+
174
177
  PIPE = STDOUT.dup
175
178
  begin
176
179
  config = Marshal.load(IO.read('#{ config }'))
@@ -190,7 +193,7 @@ class SystemUniversal
190
193
  STDERR.reopen stderr
191
194
 
192
195
  PIPE.puts "pid: \#{ Process.pid }"
193
- PIPE.flush ### the process is ready yo!
196
+ PIPE.flush ### the process is ready yo!
194
197
  PIPE.close
195
198
 
196
199
  exec *argv
@@ -221,9 +224,9 @@ class SystemUniversal
221
224
  tmp = File.join d, "systemu_#{ @host }_#{ @ppid }_#{ @pid }_#{ rand }_#{ i += 1 }"
222
225
 
223
226
  begin
224
- Dir.mkdir tmp
227
+ Dir.mkdir tmp
225
228
  rescue Errno::EEXIST
226
- raise if i >= max
229
+ raise if i >= max
227
230
  next
228
231
  end
229
232
 
@@ -232,7 +235,7 @@ class SystemUniversal
232
235
  begin
233
236
  b.call tmp
234
237
  ensure
235
- FileUtils.rm_rf tmp unless SystemU.turd
238
+ FileUtils.rm_rf tmp unless SystemU.turd
236
239
  end
237
240
  else
238
241
  tmp
@@ -260,36 +263,39 @@ end
260
263
  if defined? JRUBY_VERSION
261
264
  require 'jruby'
262
265
  java_import org.jruby.RubyProcess
263
-
266
+
264
267
  class SystemUniversal
265
268
  def systemu
266
269
  split_argv = JRuby::PathHelper.smart_split_command @argv
267
270
  process = java.lang.Runtime.runtime.exec split_argv.to_java(:string)
268
-
271
+
269
272
  stdout, stderr = [process.input_stream, process.error_stream].map do |stream|
270
273
  StreamReader.new(stream)
271
274
  end
272
275
 
273
276
  exit_code = process.wait_for
277
+ field = process.get_class.get_declared_field("pid")
278
+ field.set_accessible(true)
279
+ pid = field.get(process)
274
280
  [
275
- RubyProcess::RubyStatus.new_process_status(JRuby.runtime, exit_code),
276
- stdout.join,
281
+ RubyProcess::RubyStatus.new_process_status(JRuby.runtime, exit_code, pid),
282
+ stdout.join,
277
283
  stderr.join
278
284
  ]
279
285
  end
280
-
286
+
281
287
  class StreamReader
282
288
  def initialize(stream)
283
289
  @data = ""
284
290
  @thread = Thread.new do
285
291
  reader = java.io.BufferedReader.new java.io.InputStreamReader.new(stream)
286
-
292
+
287
293
  while line = reader.read_line
288
294
  @data << line << "\n"
289
295
  end
290
296
  end
291
297
  end
292
-
298
+
293
299
  def join
294
300
  @thread.join
295
301
  @data
@@ -297,7 +303,7 @@ if defined? JRUBY_VERSION
297
303
  end
298
304
  end
299
305
  end
300
-
306
+
301
307
 
302
308
 
303
309
  SystemU = SystemUniversal unless defined? SystemU
@@ -333,20 +339,20 @@ if $0 == __FILE__
333
339
  # sleep
334
340
  #
335
341
  sleep = %q( ruby -e" p(sleep(1)) " )
336
- status, stdout, stderr = systemu sleep
342
+ status, stdout, stderr = systemu sleep
337
343
  p [status, stdout, stderr]
338
344
 
339
345
  sleep = %q( ruby -e" p(sleep(42)) " )
340
346
  status, stdout, stderr = systemu(sleep){|cid| Process.kill 9, cid}
341
347
  p [status, stdout, stderr]
342
348
  #
343
- # env
349
+ # env
344
350
  #
345
351
  env = %q( ruby -e" p ENV['A'] " )
346
- status, stdout, stderr = systemu env, :env => {'A' => 42}
352
+ status, stdout, stderr = systemu env, :env => {'A' => 42}
347
353
  p [status, stdout, stderr]
348
354
  #
349
- # cwd
355
+ # cwd
350
356
  #
351
357
  env = %q( ruby -e" p Dir.pwd " )
352
358
  status, stdout, stderr = systemu env, :cwd => Dir.tmpdir
data/systemu.gemspec CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  Gem::Specification::new do |spec|
5
5
  spec.name = "systemu"
6
- spec.version = "2.4.2"
6
+ spec.version = "2.5.0"
7
7
  spec.platform = Gem::Platform::RUBY
8
8
  spec.summary = "systemu"
9
9
  spec.description = "description: systemu kicks the ass"
@@ -22,7 +22,10 @@ Gem::Specification::new do |spec|
22
22
  "samples/d.rb",
23
23
  "samples/e.rb",
24
24
  "samples/f.rb",
25
- "systemu.gemspec"]
25
+ "systemu.gemspec",
26
+ "test",
27
+ "test/systemu_test.rb",
28
+ "test/testing.rb"]
26
29
 
27
30
  spec.executables = []
28
31
 
@@ -0,0 +1,64 @@
1
+
2
+ Testing SystemU do
3
+
4
+ ##
5
+ #
6
+ testing 'that simple usage works' do
7
+ status, stdout, stderr = assert{ systemu :bin/:ls }
8
+ assert{ status == 0 }
9
+ assert{ stdout['lib'] }
10
+ assert{ stderr.strip.empty? }
11
+ end
12
+
13
+ testing 'program with stdin' do
14
+ stdin = '42'
15
+ status, stdout, stderr = assert{ systemu :bin/:cat, :stdin => stdin }
16
+ assert{ status == 0 }
17
+ assert{ stdout == stdin }
18
+ end
19
+
20
+ end
21
+
22
+
23
+
24
+
25
+
26
+ BEGIN {
27
+
28
+ # silly hax to build commands we can shell out to on any platform. since
29
+ # tests might run on windoze we assume only that 'ruby' is available and build
30
+ # other command-line programs from it.
31
+ #
32
+ module Kernel
33
+ private
34
+ def bin(which, options = {}, &block)
35
+ case which.to_s
36
+ when 'ls'
37
+ %| ruby -e'puts Dir.glob("*").sort' |
38
+
39
+ when 'cat'
40
+ %| ruby -e'STDOUT.write(ARGF.read)' |
41
+
42
+ when 'find'
43
+ %| ruby -e'puts Dir.glob("**/**").sort' |
44
+ end
45
+ end
46
+ end
47
+
48
+ # just let's us write: :bin/:ls
49
+ #
50
+ class Symbol
51
+ def / other, options = {}, &block
52
+ eval "#{ self }(:#{ other }, options, &block)"
53
+ end
54
+ end
55
+
56
+ testdir = File.dirname(File.expand_path(__FILE__))
57
+ rootdir = File.dirname(testdir)
58
+ libdir = File.join(rootdir, 'lib')
59
+ require File.join(libdir, 'systemu')
60
+ require File.join(testdir, 'testing')
61
+
62
+
63
+ Dir.chdir(rootdir)
64
+ }
data/test/testing.rb ADDED
@@ -0,0 +1,195 @@
1
+ require 'test/unit'
2
+
3
+ testdir = File.expand_path(File.dirname(__FILE__))
4
+ rootdir = File.dirname(testdir)
5
+ libdir = File.join(rootdir, 'lib')
6
+
7
+ STDOUT.sync = true
8
+
9
+ $:.unshift(testdir) unless $:.include?(testdir)
10
+ $:.unshift(libdir) unless $:.include?(libdir)
11
+ $:.unshift(rootdir) unless $:.include?(rootdir)
12
+
13
+ class Testing
14
+ class Slug < ::String
15
+ def Slug.for(*args)
16
+ string = args.flatten.compact.join('-')
17
+ words = string.to_s.scan(%r/\w+/)
18
+ words.map!{|word| word.gsub %r/[^0-9a-zA-Z_-]/, ''}
19
+ words.delete_if{|word| word.nil? or word.strip.empty?}
20
+ new(words.join('-').downcase)
21
+ end
22
+ end
23
+
24
+ class Context
25
+ attr_accessor :name
26
+
27
+ def initialize(name, *args)
28
+ @name = name
29
+ end
30
+
31
+ def to_s
32
+ Slug.for(name)
33
+ end
34
+ end
35
+ end
36
+
37
+ def Testing(*args, &block)
38
+ Class.new(::Test::Unit::TestCase) do
39
+
40
+ ## class methods
41
+ #
42
+ class << self
43
+ def contexts
44
+ @contexts ||= []
45
+ end
46
+
47
+ def context(*args, &block)
48
+ return contexts.last if(args.empty? and block.nil?)
49
+
50
+ context = Testing::Context.new(*args)
51
+ contexts.push(context)
52
+
53
+ begin
54
+ block.call(context)
55
+ ensure
56
+ contexts.pop
57
+ end
58
+ end
59
+
60
+ def slug_for(*args)
61
+ string = [context, args].flatten.compact.join('-')
62
+ words = string.to_s.scan(%r/\w+/)
63
+ words.map!{|word| word.gsub %r/[^0-9a-zA-Z_-]/, ''}
64
+ words.delete_if{|word| word.nil? or word.strip.empty?}
65
+ words.join('-').downcase.sub(/_$/, '')
66
+ end
67
+
68
+ def name() const_get(:Name) end
69
+
70
+ def testno()
71
+ '%05d' % (@testno ||= 0)
72
+ ensure
73
+ @testno += 1
74
+ end
75
+
76
+ def testing(*args, &block)
77
+ method = ["test", testno, slug_for(*args)].delete_if{|part| part.empty?}.join('_')
78
+ define_method(method, &block)
79
+ end
80
+
81
+ def test(*args, &block)
82
+ testing(*args, &block)
83
+ end
84
+
85
+ def setup(&block)
86
+ define_method(:setup, &block) if block
87
+ end
88
+
89
+ def teardown(&block)
90
+ define_method(:teardown, &block) if block
91
+ end
92
+
93
+ def prepare(&block)
94
+ @prepare ||= []
95
+ @prepare.push(block) if block
96
+ @prepare
97
+ end
98
+
99
+ def cleanup(&block)
100
+ @cleanup ||= []
101
+ @cleanup.push(block) if block
102
+ @cleanup
103
+ end
104
+ end
105
+
106
+ ## configure the subclass!
107
+ #
108
+ const_set(:Testno, '0')
109
+ slug = slug_for(*args).gsub(%r/-/,'_')
110
+ name = ['TESTING', '%03d' % const_get(:Testno), slug].delete_if{|part| part.empty?}.join('_')
111
+ name = name.upcase!
112
+ const_set(:Name, name)
113
+ const_set(:Missing, Object.new.freeze)
114
+
115
+ ## instance methods
116
+ #
117
+ alias_method('__assert__', 'assert')
118
+
119
+ def assert(*args, &block)
120
+ if args.size == 1 and args.first.is_a?(Hash)
121
+ options = args.first
122
+ expected = getopt(:expected, options){ missing }
123
+ actual = getopt(:actual, options){ missing }
124
+ if expected == missing and actual == missing
125
+ actual, expected, *ignored = options.to_a.flatten
126
+ end
127
+ expected = expected.call() if expected.respond_to?(:call)
128
+ actual = actual.call() if actual.respond_to?(:call)
129
+ assert_equal(expected, actual)
130
+ end
131
+
132
+ if block
133
+ label = "assert(#{ args.join(' ') })"
134
+ result = nil
135
+ assert_nothing_raised{ result = block.call }
136
+ __assert__(result, label)
137
+ result
138
+ else
139
+ result = args.shift
140
+ label = "assert(#{ args.join(' ') })"
141
+ __assert__(result, label)
142
+ result
143
+ end
144
+ end
145
+
146
+ def missing
147
+ self.class.const_get(:Missing)
148
+ end
149
+
150
+ def getopt(opt, hash, options = nil, &block)
151
+ [opt.to_s, opt.to_s.to_sym].each do |key|
152
+ return hash[key] if hash.has_key?(key)
153
+ end
154
+ default =
155
+ if block
156
+ block.call
157
+ else
158
+ options.is_a?(Hash) ? options[:default] : nil
159
+ end
160
+ return default
161
+ end
162
+
163
+ def subclass_of exception
164
+ class << exception
165
+ def ==(other) super or self > other end
166
+ end
167
+ exception
168
+ end
169
+
170
+ ##
171
+ #
172
+ module_eval(&block)
173
+
174
+ self.setup()
175
+ self.prepare.each{|b| b.call()}
176
+
177
+ at_exit{
178
+ self.teardown()
179
+ self.cleanup.each{|b| b.call()}
180
+ }
181
+
182
+ self
183
+ end
184
+ end
185
+
186
+
187
+ if $0 == __FILE__
188
+
189
+ Testing 'Testing' do
190
+ testing('foo'){ assert true }
191
+ test{ assert true }
192
+ p instance_methods.grep(/test/)
193
+ end
194
+
195
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: systemu
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.2
4
+ version: 2.5.0
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: 2011-12-12 00:00:00.000000000 Z
12
+ date: 2012-03-13 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: ! 'description: systemu kicks the ass'
15
15
  email: ara.t.howard@gmail.com
@@ -29,6 +29,8 @@ files:
29
29
  - samples/e.rb
30
30
  - samples/f.rb
31
31
  - systemu.gemspec
32
+ - test/systemu_test.rb
33
+ - test/testing.rb
32
34
  homepage: https://github.com/ahoward/systemu
33
35
  licenses: []
34
36
  post_install_message: