terminator 0.4.4 → 1.0.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.
- 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')
|