sfl 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.md +28 -0
- data/lib/sfl.rb +108 -0
- metadata +56 -0
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# Spawn for Legacy
|
2
|
+
|
3
|
+
Kernel.spawn in ruby 1.9 solves all issues on asynchronous executions.[1](http://ujihisa.blogspot.com/2010/03/how-to-run-external-command.html)[2](http://ujihisa.blogspot.com/2010/03/all-about-spawn.html)
|
4
|
+
But ruby 1.8, the legacy version of MRI, is still used on many environments.
|
5
|
+
|
6
|
+
This library provides `spawn()` which is almost perfectly compatible with ruby 1.9's.
|
7
|
+
|
8
|
+
## Install
|
9
|
+
|
10
|
+
gem install sfl
|
11
|
+
|
12
|
+
## How to use
|
13
|
+
|
14
|
+
require 'rubygems'
|
15
|
+
require 'sfl'
|
16
|
+
|
17
|
+
spawn 'ls'
|
18
|
+
|
19
|
+
If your ruby is 1.9, `require 'sfl'` doesn't do anything. If your ruby is 1.8, that defines `spawn`.
|
20
|
+
|
21
|
+
## How compatible the spawn is?
|
22
|
+
|
23
|
+
(I'll put the coverage here later)
|
24
|
+
|
25
|
+
## Misc.
|
26
|
+
|
27
|
+
* At first I tried to use the name `spawn` as this gem library name, but the name was already used. The `spawn` gem library does not mean ruby 1.9's `spawn` at all.
|
28
|
+
* Ruby 1.9's `open3` library, based on `spawn`, is very useful. I would like to port `open3` to ruby 1.8 in my future.
|
data/lib/sfl.rb
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
class SFL
|
2
|
+
attr_reader :command, :environment, :argument, :option
|
3
|
+
|
4
|
+
def initialize(*cmdandarg)
|
5
|
+
raise ArgumentError if cmdandarg.size == 0
|
6
|
+
cmdandarg = cmdandarg.dup
|
7
|
+
|
8
|
+
tmp = cmdandarg.shift
|
9
|
+
if Hash === tmp
|
10
|
+
@environment = tmp
|
11
|
+
tmp = cmdandarg.shift
|
12
|
+
else
|
13
|
+
@environment = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
if String === tmp
|
17
|
+
@command = [tmp, tmp]
|
18
|
+
else
|
19
|
+
@command = tmp
|
20
|
+
end
|
21
|
+
|
22
|
+
if Hash === cmdandarg.last
|
23
|
+
@option = cmdandarg.pop
|
24
|
+
else
|
25
|
+
@option = {}
|
26
|
+
end
|
27
|
+
|
28
|
+
@argument = cmdandarg
|
29
|
+
end
|
30
|
+
|
31
|
+
def run
|
32
|
+
fork {
|
33
|
+
@environment.each do |k, v|
|
34
|
+
ENV[k] = v
|
35
|
+
end
|
36
|
+
self.class.option_parser(@option).each do |ast|
|
37
|
+
self.class.eval_ast ast
|
38
|
+
end
|
39
|
+
exec(@command, *@argument)
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def ==(o) # Mostly for rspec
|
44
|
+
instance_variables.all? do |i|
|
45
|
+
i = i[1..-1] # '@a' -> 'a'
|
46
|
+
eval "self.#{i} == o.#{i}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class << self
|
51
|
+
def option_parser(hash)
|
52
|
+
mapping = {
|
53
|
+
:out => STDOUT,
|
54
|
+
:err => STDERR,
|
55
|
+
}
|
56
|
+
result = []
|
57
|
+
chdir = hash.delete(:chdir)
|
58
|
+
if chdir
|
59
|
+
result[0] = [Dir, :chdir, chdir]
|
60
|
+
end
|
61
|
+
result += hash.map {|k, v|
|
62
|
+
right =
|
63
|
+
case v
|
64
|
+
when Symbol # :out or :err
|
65
|
+
mapping[v]
|
66
|
+
when String # filename
|
67
|
+
[File, :open, v, 'w']
|
68
|
+
when Array # filename with option
|
69
|
+
[File, :open, v[0], v[1]]
|
70
|
+
when IO
|
71
|
+
v
|
72
|
+
end
|
73
|
+
|
74
|
+
if Symbol === k
|
75
|
+
[[mapping[k], :reopen, right]]
|
76
|
+
else
|
77
|
+
# assuming k is like [:out, :err]
|
78
|
+
raise if k.size > 2
|
79
|
+
left1, left2 = *k.map {|i| mapping[i] }
|
80
|
+
[
|
81
|
+
[left1, :reopen, right],
|
82
|
+
[left2, :reopen, left1],
|
83
|
+
]
|
84
|
+
end
|
85
|
+
}.flatten(1)
|
86
|
+
result
|
87
|
+
end
|
88
|
+
|
89
|
+
def eval_ast(ast)
|
90
|
+
case ast
|
91
|
+
when Array
|
92
|
+
if ast.size > 2
|
93
|
+
eval_ast(ast[0]).send(ast[1], *ast[2..-1].map {|i| eval_ast(i) })
|
94
|
+
else
|
95
|
+
eval_ast(ast[0]).send(ast[1])
|
96
|
+
end
|
97
|
+
else
|
98
|
+
ast
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
if RUBY_VERSION < '1.9'
|
105
|
+
def spawn(*x)
|
106
|
+
SFL.new(*x).run
|
107
|
+
end
|
108
|
+
end
|
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sfl
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "1.0"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- ujihisa
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-03-07 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Spawn For Ruby 1.8
|
17
|
+
email: ujihisa at gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.md
|
24
|
+
files:
|
25
|
+
- lib/sfl.rb
|
26
|
+
- README.md
|
27
|
+
has_rdoc: true
|
28
|
+
homepage: https://github.com/ujihisa/spawn-for-legacy
|
29
|
+
licenses: []
|
30
|
+
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: "0"
|
41
|
+
version:
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
version:
|
48
|
+
requirements: []
|
49
|
+
|
50
|
+
rubyforge_project:
|
51
|
+
rubygems_version: 1.3.5
|
52
|
+
signing_key:
|
53
|
+
specification_version: 3
|
54
|
+
summary: Spawn For Ruby 1.8
|
55
|
+
test_files: []
|
56
|
+
|