terminator 0.4.4 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/README +27 -69
- data/README.tmpl +27 -0
- data/Rakefile +392 -0
- data/doc/created.rid +1 -1
- data/lib/terminator.rb +31 -20
- data/samples/e.rb +1 -2
- data/terminator.gemspec +69 -0
- metadata +42 -56
- data/gemspec.rb +0 -39
- data/install.rb +0 -215
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NTlkMmUwNjVjYTk5MDUzNzZiYWQ4MTNiMjdiZTUyNWUxNTY5OWFkYQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZjZiYjdmZTg4YmIwYmZjNTZlMzQ3OWUxZWJkMjFkMzk1ZmMzNzQ5Zg==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
Mzc3NWNjNWNiNGZkNjhkZGVjYmQxNjBiM2I1ODg4NmNlNmIxOGI0MTM3NDNm
|
10
|
+
MzhlODIyNTc4ZGM1NDNjZWE3ZmM3NWM2ZWQzYTg1MzFjZjQxMTMzYzM3M2Mx
|
11
|
+
MDU1OGM1OTllNTljMDNiN2U5MzY0NzcxYWZkN2Q0NWY5N2UyNDE=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MjcwZjYyMTg0ZTA5ZWNjNWNhZTllOWNhMmI4ZGE2OGZiYmM5NjdmODk3Mjhj
|
14
|
+
NDM2ZGMwOTdhMzdmZTRlMjA3OWU5NjQ3OTkxMjg4ODhiZjY4ZWJiNGNiYjlj
|
15
|
+
YWJiODFkZTc0MzE1YTdlYjAwM2MwZmViZjRkOTUyM2IyMmQ5OTI=
|
data/README
CHANGED
@@ -1,58 +1,10 @@
|
|
1
1
|
NAME
|
2
|
-
|
2
|
+
terminator
|
3
3
|
|
4
4
|
SYNOPSIS
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
DESCRIPTION
|
10
|
-
Terminator is a solution to the problem of 'how am I meant to kill a
|
11
|
-
system call in Ruby!?'
|
12
|
-
|
13
|
-
Ruby (at least MRI) uses green threads to "multitask". This means that
|
14
|
-
there is really only ever one ruby process running which then splits up
|
15
|
-
it's processor time between all of it's threads internally.
|
16
|
-
|
17
|
-
The processor then only has to deal with one ruby process and the ruby
|
18
|
-
process deals with all it's threads. There are pros and cons to this
|
19
|
-
method, but that is not the point of this library.
|
20
|
-
|
21
|
-
The point is, that if you make a system call to an external resource from
|
22
|
-
ruby, then the kernel will go and make that call for ruby and NOT COME BACK
|
23
|
-
to ruby until that system call completes or fails. This can take a very
|
24
|
-
long time and is why your feeble attempts at using ruby's internal "Timeout"
|
25
|
-
command has failed miserably at timing out your external web service, database
|
26
|
-
or network connections.
|
27
|
-
|
28
|
-
You see, Ruby just doesn't get a chance to do anything as the kernel goes
|
29
|
-
"I'm not going to talk to you again until your system calls complete". Sort
|
30
|
-
of a no win situation for Ruby.
|
31
|
-
|
32
|
-
That's where Terminator comes in. Like Arnie, he will come back. No matter
|
33
|
-
what, and complete his mission, unless he gets aborted before his timeout,
|
34
|
-
you can trust Terminator to thoroughly and without remorse, nuke your
|
35
|
-
misbehaving and timing out ruby processes efficiently, and quickly.
|
36
|
-
|
37
|
-
HOW IT WORKS
|
38
|
-
Basically we create a new terminator ruby process, separate to the existing
|
39
|
-
running ruby process that has a simple command of sleep for x seconds, and then
|
40
|
-
do a process TERM on the PID of the original ruby process that created it.
|
41
|
-
|
42
|
-
If your process finishes before the timeout, it will kill the Terminator first.
|
43
|
-
|
44
|
-
So really it is a race of who is going to win?
|
45
|
-
|
46
|
-
Word of warning though. Terminator is not subtle. Don't expect it to split
|
47
|
-
hairs. Trying to give a process that takes about 1 second to complete, a
|
48
|
-
2 second terminator... well... odds are 50/50 on who is going to make it.
|
49
|
-
|
50
|
-
If you have a 1 second process, give it 3 seconds to complete. Arnie doesn't
|
51
|
-
much care for casualties of war.
|
52
|
-
|
53
|
-
Another word of warning, if using Terminator inside a loop, it is possible
|
54
|
-
to exceed your open file limit. I have safely tested looping 1000 times
|
55
|
-
|
5
|
+
an external timeout mechanism based on processes and signals. safe on
|
6
|
+
windows. safe for system calls. safe for minors.
|
7
|
+
|
56
8
|
INSTALL
|
57
9
|
gem install terminator
|
58
10
|
|
@@ -61,14 +13,11 @@ URIS
|
|
61
13
|
http://rubyforge.org/projects/codeforpeople
|
62
14
|
|
63
15
|
HISTORY
|
16
|
+
1.0.0
|
17
|
+
cleanup for 1.9
|
18
|
+
|
64
19
|
0.4.2
|
65
|
-
|
66
|
-
0.4.3
|
67
|
-
* added some extra specs and test cases (mikel)
|
68
|
-
0.4.4
|
69
|
-
* made terminator loop safe. 1000.times { Terminator.timeout(1) do true; end }
|
70
|
-
now works (mikel)
|
71
|
-
* added more test cases (mikel)
|
20
|
+
initial version with
|
72
21
|
|
73
22
|
AUTHORS
|
74
23
|
ara.t.howard - ara.t.howard@gmail.com
|
@@ -88,8 +37,17 @@ SAMPLES
|
|
88
37
|
|
89
38
|
~ > ruby samples/a.rb
|
90
39
|
|
91
|
-
samples/a.rb:3:
|
92
|
-
from
|
40
|
+
samples/a.rb:3:in `<main>': Timeout out after 2.0s (Terminator::Error)
|
41
|
+
from /Users/ahoward/git/ahoward/terminator/lib/terminator.rb:127:in `eval'
|
42
|
+
from /Users/ahoward/git/ahoward/terminator/lib/terminator.rb:127:in `block in terminate'
|
43
|
+
from /Users/ahoward/git/ahoward/terminator/lib/terminator.rb:129:in `call'
|
44
|
+
from /Users/ahoward/git/ahoward/terminator/lib/terminator.rb:129:in `block in terminate'
|
45
|
+
from samples/a.rb:4:in `call'
|
46
|
+
from samples/a.rb:4:in `sleep'
|
47
|
+
from samples/a.rb:4:in `block in <main>'
|
48
|
+
from /Users/ahoward/git/ahoward/terminator/lib/terminator.rb:136:in `call'
|
49
|
+
from /Users/ahoward/git/ahoward/terminator/lib/terminator.rb:136:in `terminate'
|
50
|
+
from samples/a.rb:3:in `<main>'
|
93
51
|
|
94
52
|
|
95
53
|
<========< samples/b.rb >========>
|
@@ -141,8 +99,8 @@ SAMPLES
|
|
141
99
|
|
142
100
|
~ > ruby samples/d.rb
|
143
101
|
|
144
|
-
signaled @
|
145
|
-
woke up @
|
102
|
+
signaled @ 1376702274
|
103
|
+
woke up @ 1376702275
|
146
104
|
|
147
105
|
|
148
106
|
<========< samples/e.rb >========>
|
@@ -150,7 +108,7 @@ SAMPLES
|
|
150
108
|
~ > cat samples/e.rb
|
151
109
|
|
152
110
|
require 'terminator'
|
153
|
-
|
111
|
+
|
154
112
|
puts "Looping 1000 times on the terminator..."
|
155
113
|
success = false
|
156
114
|
1.upto(1000) do |i|
|
@@ -158,12 +116,12 @@ SAMPLES
|
|
158
116
|
Terminator.terminate(1) do
|
159
117
|
success = true
|
160
118
|
end
|
161
|
-
print "\b\b\b#{i}"
|
162
119
|
end
|
163
|
-
puts "\
|
120
|
+
puts "\nsuccess!" if success
|
164
121
|
|
165
122
|
~ > ruby samples/e.rb
|
166
|
-
|
123
|
+
|
167
124
|
Looping 1000 times on the terminator...
|
168
|
-
|
169
|
-
|
125
|
+
|
126
|
+
success!
|
127
|
+
|
data/README.tmpl
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
NAME
|
2
|
+
terminator
|
3
|
+
|
4
|
+
SYNOPSIS
|
5
|
+
an external timeout mechanism based on processes and signals. safe on
|
6
|
+
windows. safe for system calls. safe for minors.
|
7
|
+
|
8
|
+
INSTALL
|
9
|
+
gem install terminator
|
10
|
+
|
11
|
+
URIS
|
12
|
+
http://codeforpeople.com/lib/ruby
|
13
|
+
http://rubyforge.org/projects/codeforpeople
|
14
|
+
|
15
|
+
HISTORY
|
16
|
+
1.0.0
|
17
|
+
cleanup for 1.9
|
18
|
+
|
19
|
+
0.4.2
|
20
|
+
initial version with
|
21
|
+
|
22
|
+
AUTHORS
|
23
|
+
ara.t.howard - ara.t.howard@gmail.com
|
24
|
+
mikel lindsaar - raasdnil@gmail.com
|
25
|
+
|
26
|
+
SAMPLES
|
27
|
+
@samples
|
data/Rakefile
ADDED
@@ -0,0 +1,392 @@
|
|
1
|
+
This.rubyforge_project = 'codeforpeople'
|
2
|
+
This.author = "Ara T. Howard"
|
3
|
+
This.email = "ara.t.howard@gmail.com"
|
4
|
+
This.homepage = "https://github.com/ahoward/#{ This.lib }"
|
5
|
+
|
6
|
+
|
7
|
+
task :default do
|
8
|
+
puts((Rake::Task.tasks.map{|task| task.name.gsub(/::/,':')} - ['default']).sort)
|
9
|
+
end
|
10
|
+
|
11
|
+
task :test do
|
12
|
+
run_tests!
|
13
|
+
end
|
14
|
+
|
15
|
+
namespace :test do
|
16
|
+
task(:unit){ run_tests!(:unit) }
|
17
|
+
task(:functional){ run_tests!(:functional) }
|
18
|
+
task(:integration){ run_tests!(:integration) }
|
19
|
+
end
|
20
|
+
|
21
|
+
def run_tests!(which = nil)
|
22
|
+
which ||= '**'
|
23
|
+
test_dir = File.join(This.dir, "test")
|
24
|
+
test_glob ||= File.join(test_dir, "#{ which }/**_test.rb")
|
25
|
+
test_rbs = Dir.glob(test_glob).sort
|
26
|
+
|
27
|
+
div = ('=' * 119)
|
28
|
+
line = ('-' * 119)
|
29
|
+
|
30
|
+
test_rbs.each_with_index do |test_rb, index|
|
31
|
+
testno = index + 1
|
32
|
+
command = "#{ File.basename(This.ruby) } -I ./lib -I ./test/lib #{ test_rb }"
|
33
|
+
|
34
|
+
puts
|
35
|
+
say(div, :color => :cyan, :bold => true)
|
36
|
+
say("@#{ testno } => ", :bold => true, :method => :print)
|
37
|
+
say(command, :color => :cyan, :bold => true)
|
38
|
+
say(line, :color => :cyan, :bold => true)
|
39
|
+
|
40
|
+
system(command)
|
41
|
+
|
42
|
+
say(line, :color => :cyan, :bold => true)
|
43
|
+
|
44
|
+
status = $?.exitstatus
|
45
|
+
|
46
|
+
if status.zero?
|
47
|
+
say("@#{ testno } <= ", :bold => true, :color => :white, :method => :print)
|
48
|
+
say("SUCCESS", :color => :green, :bold => true)
|
49
|
+
else
|
50
|
+
say("@#{ testno } <= ", :bold => true, :color => :white, :method => :print)
|
51
|
+
say("FAILURE", :color => :red, :bold => true)
|
52
|
+
end
|
53
|
+
say(line, :color => :cyan, :bold => true)
|
54
|
+
|
55
|
+
exit(status) unless status.zero?
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
task :gemspec do
|
61
|
+
ignore_extensions = ['git', 'svn', 'tmp', /sw./, 'bak', 'gem']
|
62
|
+
ignore_directories = ['pkg', 'db']
|
63
|
+
ignore_files = ['test/log', 'test/db.yml', 'a.rb', 'b.rb'] + Dir['db/*'] + %w'db'
|
64
|
+
|
65
|
+
shiteless =
|
66
|
+
lambda do |list|
|
67
|
+
list.delete_if do |entry|
|
68
|
+
next unless test(?e, entry)
|
69
|
+
extension = File.basename(entry).split(%r/[.]/).last
|
70
|
+
ignore_extensions.any?{|ext| ext === extension}
|
71
|
+
end
|
72
|
+
list.delete_if do |entry|
|
73
|
+
next unless test(?d, entry)
|
74
|
+
dirname = File.expand_path(entry)
|
75
|
+
ignore_directories.any?{|dir| File.expand_path(dir) == dirname}
|
76
|
+
end
|
77
|
+
list.delete_if do |entry|
|
78
|
+
next unless test(?f, entry)
|
79
|
+
filename = File.expand_path(entry)
|
80
|
+
ignore_files.any?{|file| File.expand_path(file) == filename}
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
lib = This.lib
|
85
|
+
object = This.object
|
86
|
+
version = This.version
|
87
|
+
files = shiteless[Dir::glob("**/**")]
|
88
|
+
executables = shiteless[Dir::glob("bin/*")].map{|exe| File.basename(exe)}
|
89
|
+
#has_rdoc = true #File.exist?('doc')
|
90
|
+
test_files = test(?e, "test/#{ lib }.rb") ? "test/#{ lib }.rb" : nil
|
91
|
+
summary = object.respond_to?(:summary) ? object.summary : "summary: #{ lib } kicks the ass"
|
92
|
+
description = object.respond_to?(:description) ? object.description : "description: #{ lib } kicks the ass"
|
93
|
+
license = object.respond_to?(:license) ? object.license : "same as ruby's"
|
94
|
+
|
95
|
+
if This.extensions.nil?
|
96
|
+
This.extensions = []
|
97
|
+
extensions = This.extensions
|
98
|
+
%w( Makefile configure extconf.rb ).each do |ext|
|
99
|
+
extensions << ext if File.exists?(ext)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
extensions = [extensions].flatten.compact
|
103
|
+
|
104
|
+
# TODO
|
105
|
+
if This.dependencies.nil?
|
106
|
+
dependencies = []
|
107
|
+
else
|
108
|
+
case This.dependencies
|
109
|
+
when Hash
|
110
|
+
dependencies = This.dependencies.values
|
111
|
+
when Array
|
112
|
+
dependencies = This.dependencies
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
template =
|
117
|
+
if test(?e, 'gemspec.erb')
|
118
|
+
Template{ IO.read('gemspec.erb') }
|
119
|
+
else
|
120
|
+
Template {
|
121
|
+
<<-__
|
122
|
+
## <%= lib %>.gemspec
|
123
|
+
#
|
124
|
+
|
125
|
+
Gem::Specification::new do |spec|
|
126
|
+
spec.name = <%= lib.inspect %>
|
127
|
+
spec.version = <%= version.inspect %>
|
128
|
+
spec.platform = Gem::Platform::RUBY
|
129
|
+
spec.summary = <%= lib.inspect %>
|
130
|
+
spec.description = <%= description.inspect %>
|
131
|
+
spec.license = <%= license.inspect %>
|
132
|
+
|
133
|
+
spec.files =\n<%= files.sort.pretty_inspect %>
|
134
|
+
spec.executables = <%= executables.inspect %>
|
135
|
+
|
136
|
+
spec.require_path = "lib"
|
137
|
+
|
138
|
+
spec.test_files = <%= test_files.inspect %>
|
139
|
+
|
140
|
+
<% dependencies.each do |lib_version| %>
|
141
|
+
spec.add_dependency(*<%= Array(lib_version).flatten.inspect %>)
|
142
|
+
<% end %>
|
143
|
+
|
144
|
+
spec.extensions.push(*<%= extensions.inspect %>)
|
145
|
+
|
146
|
+
spec.rubyforge_project = <%= This.rubyforge_project.inspect %>
|
147
|
+
spec.author = <%= This.author.inspect %>
|
148
|
+
spec.email = <%= This.email.inspect %>
|
149
|
+
spec.homepage = <%= This.homepage.inspect %>
|
150
|
+
end
|
151
|
+
__
|
152
|
+
}
|
153
|
+
end
|
154
|
+
|
155
|
+
Fu.mkdir_p(This.pkgdir)
|
156
|
+
gemspec = "#{ lib }.gemspec"
|
157
|
+
open(gemspec, "w"){|fd| fd.puts(template)}
|
158
|
+
This.gemspec = gemspec
|
159
|
+
end
|
160
|
+
|
161
|
+
task :gem => [:clean, :gemspec] do
|
162
|
+
Fu.mkdir_p(This.pkgdir)
|
163
|
+
before = Dir['*.gem']
|
164
|
+
cmd = "gem build #{ This.gemspec }"
|
165
|
+
`#{ cmd }`
|
166
|
+
after = Dir['*.gem']
|
167
|
+
gem = ((after - before).first || after.first) or abort('no gem!')
|
168
|
+
Fu.mv(gem, This.pkgdir)
|
169
|
+
This.gem = File.join(This.pkgdir, File.basename(gem))
|
170
|
+
end
|
171
|
+
|
172
|
+
task :readme do
|
173
|
+
samples = ''
|
174
|
+
prompt = '~ > '
|
175
|
+
lib = This.lib
|
176
|
+
version = This.version
|
177
|
+
|
178
|
+
Dir['sample*/*'].sort.each do |sample|
|
179
|
+
samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
|
180
|
+
|
181
|
+
cmd = "cat #{ sample }"
|
182
|
+
samples << Util.indent(prompt + cmd, 2) << "\n\n"
|
183
|
+
samples << Util.indent(`#{ cmd }`, 4) << "\n"
|
184
|
+
|
185
|
+
cmd = "ruby #{ sample }"
|
186
|
+
samples << Util.indent(prompt + cmd, 2) << "\n\n"
|
187
|
+
|
188
|
+
cmd = "ruby -e'STDOUT.sync=true; exec %(ruby -I ./lib #{ sample })'"
|
189
|
+
samples << Util.indent(`#{ cmd } 2>&1`, 4) << "\n"
|
190
|
+
end
|
191
|
+
|
192
|
+
template =
|
193
|
+
if test(?e, 'readme.erb')
|
194
|
+
Template{ IO.read('readme.erb') }
|
195
|
+
else
|
196
|
+
Template {
|
197
|
+
<<-__
|
198
|
+
NAME
|
199
|
+
#{ lib }
|
200
|
+
|
201
|
+
DESCRIPTION
|
202
|
+
|
203
|
+
INSTALL
|
204
|
+
gem install #{ lib }
|
205
|
+
|
206
|
+
SAMPLES
|
207
|
+
#{ samples }
|
208
|
+
__
|
209
|
+
}
|
210
|
+
end
|
211
|
+
|
212
|
+
open("README", "w"){|fd| fd.puts template}
|
213
|
+
end
|
214
|
+
|
215
|
+
|
216
|
+
task :clean do
|
217
|
+
Dir[File.join(This.pkgdir, '**/**')].each{|entry| Fu.rm_rf(entry)}
|
218
|
+
end
|
219
|
+
|
220
|
+
|
221
|
+
task :release => [:clean, :gemspec, :gem] do
|
222
|
+
gems = Dir[File.join(This.pkgdir, '*.gem')].flatten
|
223
|
+
raise "which one? : #{ gems.inspect }" if gems.size > 1
|
224
|
+
raise "no gems?" if gems.size < 1
|
225
|
+
|
226
|
+
cmd = "gem push #{ This.gem }"
|
227
|
+
puts cmd
|
228
|
+
puts
|
229
|
+
system(cmd)
|
230
|
+
abort("cmd(#{ cmd }) failed with (#{ $?.inspect })") unless $?.exitstatus.zero?
|
231
|
+
|
232
|
+
cmd = "rubyforge login && rubyforge add_release #{ This.rubyforge_project } #{ This.lib } #{ This.version } #{ This.gem }"
|
233
|
+
puts cmd
|
234
|
+
puts
|
235
|
+
system(cmd)
|
236
|
+
abort("cmd(#{ cmd }) failed with (#{ $?.inspect })") unless $?.exitstatus.zero?
|
237
|
+
end
|
238
|
+
|
239
|
+
|
240
|
+
|
241
|
+
|
242
|
+
|
243
|
+
BEGIN {
|
244
|
+
# support for this rakefile
|
245
|
+
#
|
246
|
+
$VERBOSE = nil
|
247
|
+
|
248
|
+
require 'ostruct'
|
249
|
+
require 'erb'
|
250
|
+
require 'fileutils'
|
251
|
+
require 'rbconfig'
|
252
|
+
require 'pp'
|
253
|
+
|
254
|
+
# fu shortcut
|
255
|
+
#
|
256
|
+
Fu = FileUtils
|
257
|
+
|
258
|
+
# cache a bunch of stuff about this rakefile/environment
|
259
|
+
#
|
260
|
+
This = OpenStruct.new
|
261
|
+
|
262
|
+
This.file = File.expand_path(__FILE__)
|
263
|
+
This.dir = File.dirname(This.file)
|
264
|
+
This.pkgdir = File.join(This.dir, 'pkg')
|
265
|
+
|
266
|
+
# grok lib
|
267
|
+
#
|
268
|
+
lib = ENV['LIB']
|
269
|
+
unless lib
|
270
|
+
lib = File.basename(Dir.pwd).sub(/[-].*$/, '')
|
271
|
+
end
|
272
|
+
This.lib = lib
|
273
|
+
|
274
|
+
# grok version
|
275
|
+
#
|
276
|
+
version = ENV['VERSION']
|
277
|
+
unless version
|
278
|
+
require "./lib/#{ This.lib }"
|
279
|
+
This.name = lib.capitalize
|
280
|
+
This.object = eval(This.name)
|
281
|
+
version = This.object.send(:version)
|
282
|
+
end
|
283
|
+
This.version = version
|
284
|
+
|
285
|
+
# see if dependencies are export by the module
|
286
|
+
#
|
287
|
+
if This.object.respond_to?(:dependencies)
|
288
|
+
This.dependencies = This.object.dependencies
|
289
|
+
end
|
290
|
+
|
291
|
+
# we need to know the name of the lib an it's version
|
292
|
+
#
|
293
|
+
abort('no lib') unless This.lib
|
294
|
+
abort('no version') unless This.version
|
295
|
+
|
296
|
+
# discover full path to this ruby executable
|
297
|
+
#
|
298
|
+
c = Config::CONFIG
|
299
|
+
bindir = c["bindir"] || c['BINDIR']
|
300
|
+
ruby_install_name = c['ruby_install_name'] || c['RUBY_INSTALL_NAME'] || 'ruby'
|
301
|
+
ruby_ext = c['EXEEXT'] || ''
|
302
|
+
ruby = File.join(bindir, (ruby_install_name + ruby_ext))
|
303
|
+
This.ruby = ruby
|
304
|
+
|
305
|
+
# some utils
|
306
|
+
#
|
307
|
+
module Util
|
308
|
+
def indent(s, n = 2)
|
309
|
+
s = unindent(s)
|
310
|
+
ws = ' ' * n
|
311
|
+
s.gsub(%r/^/, ws)
|
312
|
+
end
|
313
|
+
|
314
|
+
def unindent(s)
|
315
|
+
indent = nil
|
316
|
+
s.each_line do |line|
|
317
|
+
next if line =~ %r/^\s*$/
|
318
|
+
indent = line[%r/^\s*/] and break
|
319
|
+
end
|
320
|
+
indent ? s.gsub(%r/^#{ indent }/, "") : s
|
321
|
+
end
|
322
|
+
extend self
|
323
|
+
end
|
324
|
+
|
325
|
+
# template support
|
326
|
+
#
|
327
|
+
class Template
|
328
|
+
def initialize(&block)
|
329
|
+
@block = block
|
330
|
+
@template = block.call.to_s
|
331
|
+
end
|
332
|
+
def expand(b=nil)
|
333
|
+
ERB.new(Util.unindent(@template)).result((b||@block).binding)
|
334
|
+
end
|
335
|
+
alias_method 'to_s', 'expand'
|
336
|
+
end
|
337
|
+
def Template(*args, &block) Template.new(*args, &block) end
|
338
|
+
|
339
|
+
# colored console output support
|
340
|
+
#
|
341
|
+
This.ansi = {
|
342
|
+
:clear => "\e[0m",
|
343
|
+
:reset => "\e[0m",
|
344
|
+
:erase_line => "\e[K",
|
345
|
+
:erase_char => "\e[P",
|
346
|
+
:bold => "\e[1m",
|
347
|
+
:dark => "\e[2m",
|
348
|
+
:underline => "\e[4m",
|
349
|
+
:underscore => "\e[4m",
|
350
|
+
:blink => "\e[5m",
|
351
|
+
:reverse => "\e[7m",
|
352
|
+
:concealed => "\e[8m",
|
353
|
+
:black => "\e[30m",
|
354
|
+
:red => "\e[31m",
|
355
|
+
:green => "\e[32m",
|
356
|
+
:yellow => "\e[33m",
|
357
|
+
:blue => "\e[34m",
|
358
|
+
:magenta => "\e[35m",
|
359
|
+
:cyan => "\e[36m",
|
360
|
+
:white => "\e[37m",
|
361
|
+
:on_black => "\e[40m",
|
362
|
+
:on_red => "\e[41m",
|
363
|
+
:on_green => "\e[42m",
|
364
|
+
:on_yellow => "\e[43m",
|
365
|
+
:on_blue => "\e[44m",
|
366
|
+
:on_magenta => "\e[45m",
|
367
|
+
:on_cyan => "\e[46m",
|
368
|
+
:on_white => "\e[47m"
|
369
|
+
}
|
370
|
+
def say(phrase, *args)
|
371
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
372
|
+
options[:color] = args.shift.to_s.to_sym unless args.empty?
|
373
|
+
keys = options.keys
|
374
|
+
keys.each{|key| options[key.to_s.to_sym] = options.delete(key)}
|
375
|
+
|
376
|
+
color = options[:color]
|
377
|
+
bold = options.has_key?(:bold)
|
378
|
+
|
379
|
+
parts = [phrase]
|
380
|
+
parts.unshift(This.ansi[color]) if color
|
381
|
+
parts.unshift(This.ansi[:bold]) if bold
|
382
|
+
parts.push(This.ansi[:clear]) if parts.size > 1
|
383
|
+
|
384
|
+
method = options[:method] || :puts
|
385
|
+
|
386
|
+
Kernel.send(method, parts.join)
|
387
|
+
end
|
388
|
+
|
389
|
+
# always run out of the project dir
|
390
|
+
#
|
391
|
+
Dir.chdir(This.dir)
|
392
|
+
}
|
data/doc/created.rid
CHANGED
@@ -1 +1 @@
|
|
1
|
-
Sun, 21 Sep 2008
|
1
|
+
Sun, 21 Sep 2008 11:02:40 +1000
|
data/lib/terminator.rb
CHANGED
@@ -101,48 +101,59 @@ require 'fattr'
|
|
101
101
|
# end
|
102
102
|
# #=> RuntimeError: (eval):1:in `irb_binding': Oops... I failed...
|
103
103
|
module Terminator
|
104
|
-
Version =
|
104
|
+
Version = "1.0.0"
|
105
|
+
|
106
|
+
def Terminator.version
|
107
|
+
Terminator::Version
|
108
|
+
end
|
109
|
+
|
110
|
+
def Terminator.description
|
111
|
+
"an external timeout mechanism based on processes and signals"
|
112
|
+
end
|
113
|
+
|
114
|
+
def Terminator.license
|
115
|
+
"same as ruby's"
|
116
|
+
end
|
117
|
+
|
118
|
+
def Terminator.dependencies
|
119
|
+
{
|
120
|
+
'fattr' => [ 'fattr' , ' >= 2.2' ] ,
|
121
|
+
}
|
122
|
+
end
|
105
123
|
|
106
124
|
# Terminator.terminate has two ways you can call it. You can either just specify:
|
107
125
|
#
|
108
126
|
# Terminator.terminate(seconds) { code_to_execute }
|
109
127
|
#
|
110
|
-
# where seconds is an integer number greater than or equal to 1. If you pass a float
|
111
|
-
# in on seconds, Terminator will call to_i on it and convert it to an integer. This
|
112
|
-
# is because Terminator is not a precise tool, due to it calling a new ruby instance,
|
113
|
-
# and spawning a new process, relying on split second accuracy is a folly.
|
114
|
-
#
|
115
128
|
# If you want to pass in the block, please use:
|
116
129
|
#
|
117
130
|
# Terminator.terminate(:seconds => seconds, :trap => block) { code_to_execute }
|
118
131
|
#
|
119
132
|
# Where block is an anonymous method that gets called when the timeout occurs.
|
120
133
|
def terminate options = {}, &block
|
121
|
-
options = { :seconds => Float(options)
|
122
|
-
|
123
|
-
seconds = getopt :seconds, options
|
134
|
+
options = { :seconds => Float(options) } unless Hash === options
|
124
135
|
|
125
|
-
|
136
|
+
seconds = getopt(:seconds, options)
|
126
137
|
|
127
|
-
|
138
|
+
default_trap = lambda{ eval("raise(::Terminator::Error, 'Timeout out after #{ seconds }s')", block.binding) }
|
139
|
+
actual_trap = getopt(:trap, options, default_trap)
|
140
|
+
signal_trap = lambda{|*_| actual_trap.call()}
|
128
141
|
|
129
|
-
|
142
|
+
previous_trap = Signal.trap(signal, &signal_trap)
|
130
143
|
|
131
|
-
terminator_pid = plot_to_kill
|
144
|
+
terminator_pid = plot_to_kill(pid, :in => seconds, :with => signal)
|
132
145
|
|
133
146
|
begin
|
134
147
|
block.call
|
135
|
-
nuke_terminator(terminator_pid)
|
136
148
|
ensure
|
137
|
-
|
149
|
+
nuke_terminator(terminator_pid)
|
150
|
+
Signal.trap(signal, previous_trap)
|
138
151
|
end
|
139
152
|
end
|
140
153
|
|
141
|
-
private
|
142
|
-
|
143
154
|
def nuke_terminator(pid)
|
144
155
|
Process.kill("KILL", pid) rescue nil
|
145
|
-
Process.wait(pid)
|
156
|
+
Process.wait(pid) rescue nil
|
146
157
|
end
|
147
158
|
|
148
159
|
def plot_to_kill pid, options = {}
|
@@ -152,7 +163,7 @@ module Terminator
|
|
152
163
|
end
|
153
164
|
|
154
165
|
def send_terminator(pid, seconds)
|
155
|
-
process = IO.popen(%[#{ ruby } -e'sleep #{seconds}
|
166
|
+
process = IO.popen(%[#{ ruby } -e'sleep #{seconds}; Process.kill("#{signal}", #{pid}) rescue nil;'], 'w+')
|
156
167
|
process.pid
|
157
168
|
end
|
158
169
|
|
@@ -161,7 +172,7 @@ module Terminator
|
|
161
172
|
end
|
162
173
|
|
163
174
|
fattr :ruby do
|
164
|
-
c = ::Config::CONFIG
|
175
|
+
c = (defined?(::RbConfig) ? ::RbConfig : ::Config)::CONFIG
|
165
176
|
ruby = File::join(c['bindir'], c['ruby_install_name']) << c['EXEEXT']
|
166
177
|
raise "ruby @ #{ ruby } not executable!?" unless test(?e, ruby)
|
167
178
|
ruby
|
data/samples/e.rb
CHANGED
data/terminator.gemspec
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
## terminator.gemspec
|
2
|
+
#
|
3
|
+
|
4
|
+
Gem::Specification::new do |spec|
|
5
|
+
spec.name = "terminator"
|
6
|
+
spec.version = "1.0.0"
|
7
|
+
spec.platform = Gem::Platform::RUBY
|
8
|
+
spec.summary = "terminator"
|
9
|
+
spec.description = "an external timeout mechanism based on processes and signals"
|
10
|
+
spec.license = "same as ruby's"
|
11
|
+
|
12
|
+
spec.files =
|
13
|
+
["README",
|
14
|
+
"README.tmpl",
|
15
|
+
"Rakefile",
|
16
|
+
"doc",
|
17
|
+
"doc/classes",
|
18
|
+
"doc/classes/Terminator",
|
19
|
+
"doc/classes/Terminator.html",
|
20
|
+
"doc/classes/Terminator.src",
|
21
|
+
"doc/classes/Terminator.src/M000001.html",
|
22
|
+
"doc/classes/Terminator/Error.html",
|
23
|
+
"doc/created.rid",
|
24
|
+
"doc/files",
|
25
|
+
"doc/files/lib",
|
26
|
+
"doc/files/lib/terminator_rb.html",
|
27
|
+
"doc/files/samples",
|
28
|
+
"doc/files/samples/a_rb.html",
|
29
|
+
"doc/files/samples/b_rb.html",
|
30
|
+
"doc/files/samples/c_rb.html",
|
31
|
+
"doc/files/samples/d_rb.html",
|
32
|
+
"doc/files/samples/e_rb.html",
|
33
|
+
"doc/files/spec",
|
34
|
+
"doc/files/spec/terminator_spec_rb.html",
|
35
|
+
"doc/fr_class_index.html",
|
36
|
+
"doc/fr_file_index.html",
|
37
|
+
"doc/fr_method_index.html",
|
38
|
+
"doc/index.html",
|
39
|
+
"doc/rdoc-style.css",
|
40
|
+
"gen_readme.rb",
|
41
|
+
"lib",
|
42
|
+
"lib/terminator.rb",
|
43
|
+
"samples",
|
44
|
+
"samples/a.rb",
|
45
|
+
"samples/b.rb",
|
46
|
+
"samples/c.rb",
|
47
|
+
"samples/d.rb",
|
48
|
+
"samples/e.rb",
|
49
|
+
"spec",
|
50
|
+
"spec/terminator_spec.rb",
|
51
|
+
"terminator.gemspec"]
|
52
|
+
|
53
|
+
spec.executables = []
|
54
|
+
|
55
|
+
spec.require_path = "lib"
|
56
|
+
|
57
|
+
spec.test_files = nil
|
58
|
+
|
59
|
+
|
60
|
+
spec.add_dependency(*["fattr", " >= 2.2"])
|
61
|
+
|
62
|
+
|
63
|
+
spec.extensions.push(*[])
|
64
|
+
|
65
|
+
spec.rubyforge_project = "codeforpeople"
|
66
|
+
spec.author = "Ara T. Howard"
|
67
|
+
spec.email = "ara.t.howard@gmail.com"
|
68
|
+
spec.homepage = "https://github.com/ahoward/terminator"
|
69
|
+
end
|
metadata
CHANGED
@@ -1,99 +1,85 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: terminator
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
|
-
authors:
|
6
|
+
authors:
|
7
7
|
- Ara T. Howard
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
dependencies:
|
15
|
-
- !ruby/object:Gem::Dependency
|
11
|
+
date: 2013-08-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
16
14
|
name: fattr
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ! '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.2'
|
17
20
|
type: :runtime
|
18
|
-
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
20
|
-
requirements:
|
21
|
-
- -
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version:
|
24
|
-
|
25
|
-
description:
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.2'
|
27
|
+
description: an external timeout mechanism based on processes and signals
|
26
28
|
email: ara.t.howard@gmail.com
|
27
29
|
executables: []
|
28
|
-
|
29
30
|
extensions: []
|
30
|
-
|
31
31
|
extra_rdoc_files: []
|
32
|
-
|
33
|
-
|
34
|
-
-
|
35
|
-
-
|
36
|
-
- doc/classes/Terminator
|
37
|
-
- doc/classes/Terminator/Error.html
|
32
|
+
files:
|
33
|
+
- README
|
34
|
+
- README.tmpl
|
35
|
+
- Rakefile
|
38
36
|
- doc/classes/Terminator.html
|
39
|
-
- doc/classes/Terminator.src
|
40
37
|
- doc/classes/Terminator.src/M000001.html
|
38
|
+
- doc/classes/Terminator/Error.html
|
41
39
|
- doc/created.rid
|
42
|
-
- doc/files
|
43
|
-
- doc/files/lib
|
44
40
|
- doc/files/lib/terminator_rb.html
|
45
|
-
- doc/files/samples
|
46
41
|
- doc/files/samples/a_rb.html
|
47
42
|
- doc/files/samples/b_rb.html
|
48
43
|
- doc/files/samples/c_rb.html
|
49
44
|
- doc/files/samples/d_rb.html
|
50
45
|
- doc/files/samples/e_rb.html
|
51
|
-
- doc/files/spec
|
52
46
|
- doc/files/spec/terminator_spec_rb.html
|
53
47
|
- doc/fr_class_index.html
|
54
48
|
- doc/fr_file_index.html
|
55
49
|
- doc/fr_method_index.html
|
56
50
|
- doc/index.html
|
57
51
|
- doc/rdoc-style.css
|
58
|
-
- gemspec.rb
|
59
52
|
- gen_readme.rb
|
60
|
-
- install.rb
|
61
|
-
- lib
|
62
53
|
- lib/terminator.rb
|
63
|
-
- README
|
64
|
-
- samples
|
65
54
|
- samples/a.rb
|
66
55
|
- samples/b.rb
|
67
56
|
- samples/c.rb
|
68
57
|
- samples/d.rb
|
69
58
|
- samples/e.rb
|
70
|
-
- spec
|
71
59
|
- spec/terminator_spec.rb
|
72
|
-
|
73
|
-
homepage:
|
60
|
+
- terminator.gemspec
|
61
|
+
homepage: https://github.com/ahoward/terminator
|
62
|
+
licenses:
|
63
|
+
- same as ruby's
|
64
|
+
metadata: {}
|
74
65
|
post_install_message:
|
75
66
|
rdoc_options: []
|
76
|
-
|
77
|
-
require_paths:
|
67
|
+
require_paths:
|
78
68
|
- lib
|
79
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
-
requirements:
|
81
|
-
- -
|
82
|
-
- !ruby/object:Gem::Version
|
83
|
-
version:
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
version: "0"
|
90
|
-
version:
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ! '>='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ! '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
91
79
|
requirements: []
|
92
|
-
|
93
80
|
rubyforge_project: codeforpeople
|
94
|
-
rubygems_version:
|
81
|
+
rubygems_version: 2.0.3
|
95
82
|
signing_key:
|
96
|
-
specification_version:
|
83
|
+
specification_version: 4
|
97
84
|
summary: terminator
|
98
85
|
test_files: []
|
99
|
-
|
data/gemspec.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
#! /usr/bin/env gem build
|
2
|
-
#:stopdoc:
|
3
|
-
|
4
|
-
lib, version = File::basename(File::dirname(File::expand_path(__FILE__))).split %r/-/, 2
|
5
|
-
|
6
|
-
require 'rubygems'
|
7
|
-
|
8
|
-
Gem::Specification::new do |spec|
|
9
|
-
$VERBOSE = nil
|
10
|
-
|
11
|
-
shiteless = lambda do |list|
|
12
|
-
list.delete_if do |file|
|
13
|
-
file =~ %r/\.svn/ or
|
14
|
-
file =~ %r/\.tmp/
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
spec.name = lib
|
19
|
-
spec.version = version
|
20
|
-
spec.platform = Gem::Platform::RUBY
|
21
|
-
spec.summary = lib
|
22
|
-
|
23
|
-
spec.files = shiteless[Dir::glob("**/**")]
|
24
|
-
spec.executables = shiteless[Dir::glob("bin/*")].map{|exe| File::basename exe}
|
25
|
-
|
26
|
-
spec.require_path = "lib"
|
27
|
-
|
28
|
-
spec.has_rdoc = File::exist? "doc"
|
29
|
-
spec.test_suite_file = "test/#{ lib }.rb" if File::directory? "test"
|
30
|
-
#spec.add_dependency 'lib', '>= version'
|
31
|
-
spec.add_dependency 'fattr'
|
32
|
-
|
33
|
-
spec.extensions << "extconf.rb" if File::exists? "extconf.rb"
|
34
|
-
|
35
|
-
spec.rubyforge_project = 'codeforpeople'
|
36
|
-
spec.author = "Ara T. Howard"
|
37
|
-
spec.email = "ara.t.howard@gmail.com"
|
38
|
-
spec.homepage = "http://codeforpeople.com/lib/ruby/#{ lib }/"
|
39
|
-
end
|
data/install.rb
DELETED
@@ -1,215 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
#:stopdoc:
|
3
|
-
require 'rbconfig'
|
4
|
-
require 'find'
|
5
|
-
require 'ftools'
|
6
|
-
require 'tempfile'
|
7
|
-
include Config
|
8
|
-
|
9
|
-
LIBDIR = "lib"
|
10
|
-
LIBDIR_MODE = 0644
|
11
|
-
|
12
|
-
BINDIR = "bin"
|
13
|
-
BINDIR_MODE = 0755
|
14
|
-
|
15
|
-
|
16
|
-
$srcdir = CONFIG["srcdir"]
|
17
|
-
$version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
|
18
|
-
$libdir = File.join(CONFIG["libdir"], "ruby", $version)
|
19
|
-
$archdir = File.join($libdir, CONFIG["arch"])
|
20
|
-
$site_libdir = $:.find {|x| x =~ /site_ruby$/}
|
21
|
-
$bindir = CONFIG["bindir"] || CONFIG['BINDIR']
|
22
|
-
$ruby_install_name = CONFIG['ruby_install_name'] || CONFIG['RUBY_INSTALL_NAME'] || 'ruby'
|
23
|
-
$ruby_ext = CONFIG['EXEEXT'] || ''
|
24
|
-
$ruby = File.join($bindir, ($ruby_install_name + $ruby_ext))
|
25
|
-
|
26
|
-
if !$site_libdir
|
27
|
-
$site_libdir = File.join($libdir, "site_ruby")
|
28
|
-
elsif $site_libdir !~ %r/#{Regexp.quote($version)}/
|
29
|
-
$site_libdir = File.join($site_libdir, $version)
|
30
|
-
end
|
31
|
-
|
32
|
-
def install_rb(srcdir=nil, destdir=nil, mode=nil, bin=nil)
|
33
|
-
#{{{
|
34
|
-
path = []
|
35
|
-
dir = []
|
36
|
-
Find.find(srcdir) do |f|
|
37
|
-
next unless FileTest.file?(f)
|
38
|
-
next if (f = f[srcdir.length+1..-1]) == nil
|
39
|
-
next if (/CVS$/ =~ File.dirname(f))
|
40
|
-
next if (/\.svn/ =~ File.dirname(f))
|
41
|
-
next if f =~ %r/\.lnk/
|
42
|
-
next if f =~ %r/\.svn/
|
43
|
-
next if f =~ %r/\.swp/
|
44
|
-
next if f =~ %r/\.svn/
|
45
|
-
path.push f
|
46
|
-
dir |= [File.dirname(f)]
|
47
|
-
end
|
48
|
-
for f in dir
|
49
|
-
next if f == "."
|
50
|
-
next if f == "CVS"
|
51
|
-
File::makedirs(File.join(destdir, f))
|
52
|
-
end
|
53
|
-
for f in path
|
54
|
-
next if (/\~$/ =~ f)
|
55
|
-
next if (/^\./ =~ File.basename(f))
|
56
|
-
unless bin
|
57
|
-
File::install(File.join(srcdir, f), File.join(destdir, f), mode, true)
|
58
|
-
else
|
59
|
-
from = File.join(srcdir, f)
|
60
|
-
to = File.join(destdir, f)
|
61
|
-
shebangify(from) do |sf|
|
62
|
-
$deferr.print from, " -> ", File::catname(from, to), "\n"
|
63
|
-
$deferr.printf "chmod %04o %s\n", mode, to
|
64
|
-
File::install(sf, to, mode, false)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
#}}}
|
69
|
-
end
|
70
|
-
def shebangify f
|
71
|
-
#{{{
|
72
|
-
open(f) do |fd|
|
73
|
-
buf = fd.read 42
|
74
|
-
if buf =~ %r/^\s*#\s*!.*ruby/o
|
75
|
-
ftmp = Tempfile::new("#{ $$ }_#{ File::basename(f) }")
|
76
|
-
begin
|
77
|
-
fd.rewind
|
78
|
-
ftmp.puts "#!#{ $ruby }"
|
79
|
-
while((buf = fd.read(8192)))
|
80
|
-
ftmp.write buf
|
81
|
-
end
|
82
|
-
ftmp.close
|
83
|
-
yield ftmp.path
|
84
|
-
ensure
|
85
|
-
ftmp.close!
|
86
|
-
end
|
87
|
-
else
|
88
|
-
yield f
|
89
|
-
end
|
90
|
-
end
|
91
|
-
#}}}
|
92
|
-
end
|
93
|
-
def ARGV.switch
|
94
|
-
#{{{
|
95
|
-
return nil if self.empty?
|
96
|
-
arg = self.shift
|
97
|
-
return nil if arg == '--'
|
98
|
-
if arg =~ /^-(.)(.*)/
|
99
|
-
return arg if $1 == '-'
|
100
|
-
raise 'unknown switch "-"' if $2.index('-')
|
101
|
-
self.unshift "-#{$2}" if $2.size > 0
|
102
|
-
"-#{$1}"
|
103
|
-
else
|
104
|
-
self.unshift arg
|
105
|
-
nil
|
106
|
-
end
|
107
|
-
#}}}
|
108
|
-
end
|
109
|
-
def ARGV.req_arg
|
110
|
-
#{{{
|
111
|
-
self.shift || raise('missing argument')
|
112
|
-
#}}}
|
113
|
-
end
|
114
|
-
def linkify d, linked = []
|
115
|
-
#--{{{
|
116
|
-
if test ?d, d
|
117
|
-
versioned = Dir[ File::join(d, "*-[0-9].[0-9].[0-9].rb") ]
|
118
|
-
versioned.each do |v|
|
119
|
-
src, dst = v, v.gsub(%r/\-[\d\.]+\.rb$/, '.rb')
|
120
|
-
lnk = nil
|
121
|
-
begin
|
122
|
-
if test ?l, dst
|
123
|
-
lnk = "#{ dst }.lnk"
|
124
|
-
puts "#{ dst } -> #{ lnk }"
|
125
|
-
File::rename dst, lnk
|
126
|
-
end
|
127
|
-
unless test ?e, dst
|
128
|
-
puts "#{ src } -> #{ dst }"
|
129
|
-
File::copy src, dst
|
130
|
-
linked << dst
|
131
|
-
end
|
132
|
-
ensure
|
133
|
-
if lnk
|
134
|
-
at_exit do
|
135
|
-
puts "#{ lnk } -> #{ dst }"
|
136
|
-
File::rename lnk, dst
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
linked
|
143
|
-
#--}}}
|
144
|
-
end
|
145
|
-
|
146
|
-
|
147
|
-
#
|
148
|
-
# main program
|
149
|
-
#
|
150
|
-
|
151
|
-
libdir = $site_libdir
|
152
|
-
bindir = $bindir
|
153
|
-
no_linkify = false
|
154
|
-
linked = nil
|
155
|
-
help = false
|
156
|
-
|
157
|
-
usage = <<-usage
|
158
|
-
#{ File::basename $0 }
|
159
|
-
-d, --destdir <destdir>
|
160
|
-
-l, --libdir <libdir>
|
161
|
-
-b, --bindir <bindir>
|
162
|
-
-r, --ruby <ruby>
|
163
|
-
-n, --no_linkify
|
164
|
-
-s, --sudo
|
165
|
-
-h, --help
|
166
|
-
usage
|
167
|
-
|
168
|
-
begin
|
169
|
-
while switch = ARGV.switch
|
170
|
-
case switch
|
171
|
-
when '-d', '--destdir'
|
172
|
-
libdir = ARGV.req_arg
|
173
|
-
when '-l', '--libdir'
|
174
|
-
libdir = ARGV.req_arg
|
175
|
-
when '-b', '--bindir'
|
176
|
-
bindir = ARGV.req_arg
|
177
|
-
when '-r', '--ruby'
|
178
|
-
$ruby = ARGV.req_arg
|
179
|
-
when '-n', '--no_linkify'
|
180
|
-
no_linkify = true
|
181
|
-
when '-s', '--sudo'
|
182
|
-
sudo = 'sudo'
|
183
|
-
when '-h', '--help'
|
184
|
-
help = true
|
185
|
-
else
|
186
|
-
raise "unknown switch #{switch.dump}"
|
187
|
-
end
|
188
|
-
end
|
189
|
-
rescue
|
190
|
-
STDERR.puts $!.to_s
|
191
|
-
STDERR.puts usage
|
192
|
-
exit 1
|
193
|
-
end
|
194
|
-
|
195
|
-
if help
|
196
|
-
STDOUT.puts usage
|
197
|
-
exit
|
198
|
-
end
|
199
|
-
|
200
|
-
system "#{ sudo } #{ $ruby } pre-install.rb" if test(?s, 'pre-install.rb')
|
201
|
-
|
202
|
-
unless no_linkify
|
203
|
-
linked = linkify('lib') + linkify('bin')
|
204
|
-
end
|
205
|
-
|
206
|
-
system "#{ $ruby } extconf.rb && make && #{ sudo } make install" if test(?s, 'extconf.rb')
|
207
|
-
|
208
|
-
install_rb(LIBDIR, libdir, LIBDIR_MODE)
|
209
|
-
install_rb(BINDIR, bindir, BINDIR_MODE, bin=true)
|
210
|
-
|
211
|
-
if linked
|
212
|
-
linked.each{|path| File::rm_f path}
|
213
|
-
end
|
214
|
-
|
215
|
-
system "#{ sudo } #{ $ruby } post-install.rb" if test(?s, 'post-install.rb')
|