bj 0.0.1
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/HISTORY +2 -0
- data/README +130 -0
- data/TODO +3 -0
- data/bin/bj +478 -0
- data/gemspec.rb +29 -0
- data/install.rb +210 -0
- data/lib/bj.rb +79 -0
- data/lib/bj/api.rb +144 -0
- data/lib/bj/bj.rb +92 -0
- data/lib/bj/errors.rb +4 -0
- data/lib/bj/joblist.rb +112 -0
- data/lib/bj/logger.rb +50 -0
- data/lib/bj/runner.rb +285 -0
- data/lib/bj/stdext.rb +80 -0
- data/lib/bj/table.rb +388 -0
- data/lib/bj/util.rb +81 -0
- metadata +99 -0
data/HISTORY
ADDED
data/README
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
NAME
|
2
|
+
bj
|
3
|
+
|
4
|
+
SYNOPSIS
|
5
|
+
bj (migration_code|generate_migration|migrate|setup|run|submit|list|set|config|pid) [options]+
|
6
|
+
|
7
|
+
DESCRIPTION
|
8
|
+
________________________________
|
9
|
+
Overview
|
10
|
+
--------------------------------
|
11
|
+
|
12
|
+
Backgroundjob (Bj) is a simple to use background priority queue for rails.
|
13
|
+
Although not yet tested on windows, the design of bj is such that operation
|
14
|
+
should be possible on any operating system, including M$.
|
15
|
+
|
16
|
+
Jobs can be submitted to the queue directly using the api or from the
|
17
|
+
commandline using the 'bj' script. For example
|
18
|
+
|
19
|
+
code:
|
20
|
+
Bj.submit 'cat /etc/password'
|
21
|
+
|
22
|
+
cli:
|
23
|
+
bj submit cat /etc/password
|
24
|
+
|
25
|
+
When used from inside a rails application bj arranges that another process
|
26
|
+
will always be running in the background to process the jobs that you submit.
|
27
|
+
By using a separate process to run jobs bj does not impact the resource
|
28
|
+
utilization of your rails application at all and enables several very cool
|
29
|
+
features:
|
30
|
+
|
31
|
+
1) Bj allows you to sumbit jobs to any of your configured databases and,
|
32
|
+
in each case, spawns a separate background process to run jobs from that
|
33
|
+
queue
|
34
|
+
|
35
|
+
Bj.in :production do
|
36
|
+
Bj.submit 'production_job.exe'
|
37
|
+
end
|
38
|
+
|
39
|
+
Bj.in :development do
|
40
|
+
Bj.submit 'development_job.exe'
|
41
|
+
end
|
42
|
+
|
43
|
+
2) Although bj ensures that a process is always running to process
|
44
|
+
your jobs, you can start a proces manually. This means that any machine
|
45
|
+
capable of seeing your RAILS_ROOT can run jobs for your application, allowing
|
46
|
+
one to setup a cluster of machines doing the work of a single front end rails
|
47
|
+
applicaiton.
|
48
|
+
|
49
|
+
________________________________
|
50
|
+
Install
|
51
|
+
--------------------------------
|
52
|
+
|
53
|
+
Bj can be installed two ways: as a gem or as a plugin.
|
54
|
+
|
55
|
+
gem:
|
56
|
+
|
57
|
+
1) $sudo gem install bj
|
58
|
+
2) bj setup ./rails_root/
|
59
|
+
|
60
|
+
plugin:
|
61
|
+
|
62
|
+
1) ./script/plugin install http://codeforpeople.rubyforge.org/svn/rails/plugins/bj
|
63
|
+
2) ./script/bj setup
|
64
|
+
|
65
|
+
________________________________
|
66
|
+
Api
|
67
|
+
--------------------------------
|
68
|
+
|
69
|
+
submit jobs for background processing. 'jobs' can be a string or array of
|
70
|
+
strings. options are applied to each job in the 'jobs', and the list of
|
71
|
+
submitted jobs is always returned. options (string or symbol) can be
|
72
|
+
|
73
|
+
:rails_env => production|development|key_in_database_yml
|
74
|
+
when given this keyword causes bj to submit jobs to the
|
75
|
+
specified database. default is RAILS_ENV.
|
76
|
+
|
77
|
+
:priority => any number, including negative ones. default is zero.
|
78
|
+
|
79
|
+
:tag => a tag added to the job. simply makes searching easier.
|
80
|
+
|
81
|
+
:env => a hash specifying any additional environment vars the background
|
82
|
+
process should have.
|
83
|
+
|
84
|
+
:stdin => any stdin the background process should have.
|
85
|
+
|
86
|
+
eg:
|
87
|
+
|
88
|
+
jobs = Bj.submit 'echo foobar', :tag => 'simple job'
|
89
|
+
|
90
|
+
jobs = Bj.submit '/bin/cat', :stdin => 'in the hat'
|
91
|
+
|
92
|
+
jobs = Bj.submit './script/runner ./scripts/a.rb', :rails_env => 'production'
|
93
|
+
|
94
|
+
when jobs are run, they are run in RAILS_ROOT. various attributes are
|
95
|
+
available *only* once the job has finished. you can check whether or not a
|
96
|
+
job is finished by using the #finished method, which simple does a reload and
|
97
|
+
checks to see if the exit_status is non-nil.
|
98
|
+
|
99
|
+
eg:
|
100
|
+
|
101
|
+
jobs = Bj.submit list_of_jobs, :tag => 'important'
|
102
|
+
...
|
103
|
+
|
104
|
+
jobs.each do |job|
|
105
|
+
if job.finished?
|
106
|
+
p job.exit_status
|
107
|
+
p job.stdout
|
108
|
+
p job.stderr
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
See lib/bj/api.rb for more details.
|
113
|
+
|
114
|
+
PARAMETERS
|
115
|
+
--rails_root=rails_root, -R (0 ~> rails_root=)
|
116
|
+
the rails_root will be guessed unless you set this
|
117
|
+
--rails_env=rails_env, -E (0 ~> rails_env=development)
|
118
|
+
set the rails_env
|
119
|
+
--log=log, -l (0 ~> log=STDERR)
|
120
|
+
set the logfile
|
121
|
+
--help, -h
|
122
|
+
|
123
|
+
AUTHOR
|
124
|
+
ara.t.howard@gmail.com
|
125
|
+
|
126
|
+
URIS
|
127
|
+
http://codeforpeople.com/lib/ruby/
|
128
|
+
http://rubyforge.org/projects/codeforpeople/
|
129
|
+
http://codeforpeople.rubyforge.org/svn/rails/plugins/
|
130
|
+
|
data/TODO
ADDED
data/bin/bj
ADDED
@@ -0,0 +1,478 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bj"
|
4
|
+
|
5
|
+
Main {
|
6
|
+
usage["description"] = <<-txt
|
7
|
+
________________________________
|
8
|
+
Overview
|
9
|
+
--------------------------------
|
10
|
+
|
11
|
+
Backgroundjob (Bj) is a simple to use background priority queue for rails.
|
12
|
+
Although not yet tested on windows, the design of bj is such that operation
|
13
|
+
should be possible on any operating system, including M$.
|
14
|
+
|
15
|
+
Jobs can be submitted to the queue directly using the api or from the
|
16
|
+
commandline using the 'bj' script. For example
|
17
|
+
|
18
|
+
code:
|
19
|
+
Bj.submit 'cat /etc/password'
|
20
|
+
|
21
|
+
cli:
|
22
|
+
bj submit cat /etc/password
|
23
|
+
|
24
|
+
When used from inside a rails application bj arranges that another process
|
25
|
+
will always be running in the background to process the jobs that you submit.
|
26
|
+
By using a separate process to run jobs bj does not impact the resource
|
27
|
+
utilization of your rails application at all and enables several very cool
|
28
|
+
features:
|
29
|
+
|
30
|
+
1) Bj allows you to sumbit jobs to any of your configured databases and,
|
31
|
+
in each case, spawns a separate background process to run jobs from that
|
32
|
+
queue
|
33
|
+
|
34
|
+
Bj.in :production do
|
35
|
+
Bj.submit 'production_job.exe'
|
36
|
+
end
|
37
|
+
|
38
|
+
Bj.in :development do
|
39
|
+
Bj.submit 'development_job.exe'
|
40
|
+
end
|
41
|
+
|
42
|
+
2) Although bj ensures that a process is always running to process
|
43
|
+
your jobs, you can start a proces manually. This means that any machine
|
44
|
+
capable of seeing your RAILS_ROOT can run jobs for your application, allowing
|
45
|
+
one to setup a cluster of machines doing the work of a single front end rails
|
46
|
+
applicaiton.
|
47
|
+
|
48
|
+
________________________________
|
49
|
+
Install
|
50
|
+
--------------------------------
|
51
|
+
|
52
|
+
Bj can be installed two ways: as a gem or as a plugin.
|
53
|
+
|
54
|
+
gem:
|
55
|
+
|
56
|
+
1) $sudo gem install bj
|
57
|
+
2) bj setup ./rails_root/
|
58
|
+
|
59
|
+
plugin:
|
60
|
+
|
61
|
+
1) ./script/plugin install http://codeforpeople.rubyforge.org/svn/rails/plugins/bj
|
62
|
+
2) ./script/bj setup
|
63
|
+
|
64
|
+
________________________________
|
65
|
+
Api
|
66
|
+
--------------------------------
|
67
|
+
|
68
|
+
submit jobs for background processing. 'jobs' can be a string or array of
|
69
|
+
strings. options are applied to each job in the 'jobs', and the list of
|
70
|
+
submitted jobs is always returned. options (string or symbol) can be
|
71
|
+
|
72
|
+
:rails_env => production|development|key_in_database_yml
|
73
|
+
when given this keyword causes bj to submit jobs to the
|
74
|
+
specified database. default is RAILS_ENV.
|
75
|
+
|
76
|
+
:priority => any number, including negative ones. default is zero.
|
77
|
+
|
78
|
+
:tag => a tag added to the job. simply makes searching easier.
|
79
|
+
|
80
|
+
:env => a hash specifying any additional environment vars the background
|
81
|
+
process should have.
|
82
|
+
|
83
|
+
:stdin => any stdin the background process should have.
|
84
|
+
|
85
|
+
eg:
|
86
|
+
|
87
|
+
jobs = Bj.submit 'echo foobar', :tag => 'simple job'
|
88
|
+
|
89
|
+
jobs = Bj.submit '/bin/cat', :stdin => 'in the hat'
|
90
|
+
|
91
|
+
jobs = Bj.submit './script/runner ./scripts/a.rb', :rails_env => 'production'
|
92
|
+
|
93
|
+
when jobs are run, they are run in RAILS_ROOT. various attributes are
|
94
|
+
available *only* once the job has finished. you can check whether or not a
|
95
|
+
job is finished by using the #finished method, which simple does a reload and
|
96
|
+
checks to see if the exit_status is non-nil.
|
97
|
+
|
98
|
+
eg:
|
99
|
+
|
100
|
+
jobs = Bj.submit list_of_jobs, :tag => 'important'
|
101
|
+
...
|
102
|
+
|
103
|
+
jobs.each do |job|
|
104
|
+
if job.finished?
|
105
|
+
p job.exit_status
|
106
|
+
p job.stdout
|
107
|
+
p job.stderr
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
See lib/bj/api.rb for more details.
|
112
|
+
|
113
|
+
________________________________
|
114
|
+
Sponsors
|
115
|
+
--------------------------------
|
116
|
+
http://www.engineyard.com/
|
117
|
+
http://quintess.com/
|
118
|
+
http://eparklabs.com/
|
119
|
+
txt
|
120
|
+
|
121
|
+
usage["uris"] = <<-txt
|
122
|
+
http://codeforpeople.com/lib/ruby/
|
123
|
+
http://rubyforge.org/projects/codeforpeople/
|
124
|
+
http://codeforpeople.rubyforge.org/svn/rails/plugins/
|
125
|
+
txt
|
126
|
+
|
127
|
+
author "ara.t.howard@gmail.com"
|
128
|
+
|
129
|
+
option("rails_root", "R"){
|
130
|
+
description "the rails_root will be guessed unless you set this"
|
131
|
+
argument_required
|
132
|
+
default RAILS_ROOT
|
133
|
+
}
|
134
|
+
|
135
|
+
option("rails_env", "E"){
|
136
|
+
description "set the rails_env"
|
137
|
+
argument_required
|
138
|
+
default RAILS_ENV
|
139
|
+
}
|
140
|
+
|
141
|
+
option("log", "l"){
|
142
|
+
description "set the logfile"
|
143
|
+
argument_required
|
144
|
+
default STDERR
|
145
|
+
}
|
146
|
+
|
147
|
+
|
148
|
+
mode "migration_code" do
|
149
|
+
description "dump migration code on stdout"
|
150
|
+
|
151
|
+
def run
|
152
|
+
puts Bj.table.migration_code
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
mode "generate_migration" do
|
157
|
+
description "generate a migration"
|
158
|
+
|
159
|
+
def run
|
160
|
+
Bj.generate_migration
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
mode "migrate" do
|
165
|
+
description "migrate the db"
|
166
|
+
|
167
|
+
def run
|
168
|
+
Bj.migrate
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
mode "setup" do
|
173
|
+
description "generate a migration and migrate"
|
174
|
+
|
175
|
+
def run
|
176
|
+
Bj.setup
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
mode "run" do
|
181
|
+
description "start a job runnner, possibly as a daemon"
|
182
|
+
|
183
|
+
option("--forever"){}
|
184
|
+
option("--daemon"){}
|
185
|
+
option("--ppid"){
|
186
|
+
argument :required
|
187
|
+
cast :integer
|
188
|
+
}
|
189
|
+
option("--redirect"){
|
190
|
+
argument :required
|
191
|
+
}
|
192
|
+
|
193
|
+
def run
|
194
|
+
options = {}
|
195
|
+
|
196
|
+
%w[ forever daemon ppid ].each do |key|
|
197
|
+
options[key.to_sym] = true if param[key].given?
|
198
|
+
end
|
199
|
+
|
200
|
+
if param["redirect"].given?
|
201
|
+
open(param["redirect"].value, "a+") do |fd|
|
202
|
+
STDERR.reopen fd
|
203
|
+
STDOUT.reopen fd
|
204
|
+
end
|
205
|
+
STDERR.sync = true
|
206
|
+
STDOUT.sync = true
|
207
|
+
end
|
208
|
+
|
209
|
+
trap("SIGTERM"){
|
210
|
+
info{ "SIGTERM" }
|
211
|
+
exit
|
212
|
+
}
|
213
|
+
|
214
|
+
if param["daemon"].given?
|
215
|
+
daemon{ Bj.run options }
|
216
|
+
else
|
217
|
+
Bj.run options
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
mode "submit" do
|
223
|
+
keyword("file"){
|
224
|
+
argument :required
|
225
|
+
attr
|
226
|
+
}
|
227
|
+
|
228
|
+
def run
|
229
|
+
joblist = Bj.joblist.for argv.join(' ')
|
230
|
+
|
231
|
+
case file
|
232
|
+
when "-"
|
233
|
+
joblist.push(Bj.joblist.jobs_from_io(STDIN))
|
234
|
+
when "--", "---"
|
235
|
+
joblist.push(Bj.joblist.jobs_from_yaml(STDIN))
|
236
|
+
else
|
237
|
+
open(file){|io| joblist.push(Bj.joblist.jobs_from_io(io)) }
|
238
|
+
end
|
239
|
+
|
240
|
+
jobs = Bj.submit joblist, :no_tickle => true
|
241
|
+
|
242
|
+
oh = lambda{|job| OrderedHash["id", job.id, "command", job.command]}
|
243
|
+
|
244
|
+
y jobs.map{|job| oh[job]}
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
mode "list" do
|
249
|
+
def run
|
250
|
+
Bj.transaction do
|
251
|
+
y Bj::Table::Job.find(:all).map(&:to_hash)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
mode "set" do
|
257
|
+
argument("key"){ attr }
|
258
|
+
|
259
|
+
argument("value"){ attr }
|
260
|
+
|
261
|
+
option("hostname", "H"){
|
262
|
+
argument :required
|
263
|
+
default Bj.hostname
|
264
|
+
attr
|
265
|
+
}
|
266
|
+
|
267
|
+
option("cast", "c"){
|
268
|
+
argument :required
|
269
|
+
default "to_s"
|
270
|
+
attr
|
271
|
+
}
|
272
|
+
|
273
|
+
def run
|
274
|
+
Bj.transaction do
|
275
|
+
Bj.config.set(key, value, :hostname => hostname, :cast => cast)
|
276
|
+
y Bj.table.config.for(:hostname => hostname)
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
mode "config" do
|
282
|
+
option("hostname", "H"){
|
283
|
+
argument :required
|
284
|
+
default Bj.hostname
|
285
|
+
}
|
286
|
+
|
287
|
+
def run
|
288
|
+
Bj.transaction do
|
289
|
+
y Bj.table.config.for(:hostname => param["hostname"].value)
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
mode "pid" do
|
295
|
+
option("hostname", "H"){
|
296
|
+
argument :required
|
297
|
+
default Bj.hostname
|
298
|
+
}
|
299
|
+
|
300
|
+
def run
|
301
|
+
Bj.transaction do
|
302
|
+
config = Bj.table.config.for(:hostname => param["hostname"].value)
|
303
|
+
puts config[ "#{ RAILS_ENV }.pid" ] if config
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
|
309
|
+
def run
|
310
|
+
help!
|
311
|
+
end
|
312
|
+
|
313
|
+
def before_run
|
314
|
+
self.logger = param["log"].value
|
315
|
+
Bj.logger = logger
|
316
|
+
|
317
|
+
if param["rails_root"].given?
|
318
|
+
rails_root = param["rails_root"].value
|
319
|
+
ENV["RAILS_ROOT"] = rails_root
|
320
|
+
::Object.instance_eval do
|
321
|
+
remove_const :RAILS_ROOT
|
322
|
+
const_set :RAILS_ROOT, rails_root
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
if param["rails_env"].given?
|
327
|
+
rails_env = param["rails_env"].value
|
328
|
+
ENV["RAILS_ENV"] = rails_env
|
329
|
+
::Object.instance_eval do
|
330
|
+
remove_const :RAILS_ENV
|
331
|
+
const_set :RAILS_ENV, rails_env
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
def daemon
|
337
|
+
ra, wa = IO.pipe
|
338
|
+
rb, wb = IO.pipe
|
339
|
+
if fork
|
340
|
+
at_exit{ exit! }
|
341
|
+
wa.close
|
342
|
+
r = ra
|
343
|
+
rb.close
|
344
|
+
w = wb
|
345
|
+
pid = r.gets
|
346
|
+
w.puts pid
|
347
|
+
Integer pid.strip
|
348
|
+
else
|
349
|
+
ra.close
|
350
|
+
w = wa
|
351
|
+
wb.close
|
352
|
+
r = rb
|
353
|
+
open("/dev/null", "r+") do |fd|
|
354
|
+
STDIN.reopen fd
|
355
|
+
STDOUT.reopen fd
|
356
|
+
STDERR.reopen fd
|
357
|
+
end
|
358
|
+
Process::setsid rescue nil
|
359
|
+
pid =
|
360
|
+
fork do
|
361
|
+
Dir::chdir RAILS_ROOT
|
362
|
+
File::umask 0
|
363
|
+
$DAEMON = true
|
364
|
+
yield
|
365
|
+
exit!
|
366
|
+
end
|
367
|
+
w.puts pid
|
368
|
+
r.gets
|
369
|
+
exit!
|
370
|
+
end
|
371
|
+
end
|
372
|
+
}
|
373
|
+
|
374
|
+
|
375
|
+
|
376
|
+
|
377
|
+
|
378
|
+
#
|
379
|
+
# we setup a few things so the script works regardless of whether it was
|
380
|
+
# called out of /usr/local/bin, ./script, or wherever. note that the script
|
381
|
+
# does *not* require the entire rails application to be loaded into memory!
|
382
|
+
# we could just load boot.rb and environment.rb, but this method let's
|
383
|
+
# submitting and running jobs be infinitely more lightweight.
|
384
|
+
#
|
385
|
+
|
386
|
+
BEGIN {
|
387
|
+
#
|
388
|
+
# see if we're running out of RAILS_ROOT/script/
|
389
|
+
#
|
390
|
+
unless defined? BJ_IS_SCRIPT #{{{
|
391
|
+
BJ_IS_SCRIPT =
|
392
|
+
if %w[ script config app ].map{|d| test ?d, "#{ File.dirname __FILE__ }/../#{ d }"}.all?
|
393
|
+
__FILE__
|
394
|
+
else
|
395
|
+
nil
|
396
|
+
end
|
397
|
+
end #}}}
|
398
|
+
|
399
|
+
#
|
400
|
+
# setup RAILS_ROOT
|
401
|
+
#
|
402
|
+
unless defined? RAILS_ROOT #{{{
|
403
|
+
### grab env var first
|
404
|
+
rails_root = ENV["RAILS_ROOT"]
|
405
|
+
|
406
|
+
### commandline usage clobbers
|
407
|
+
kv = nil
|
408
|
+
ARGV.delete_if{|arg| arg =~ %r/^RAILS_ROOT=/ and kv = arg}
|
409
|
+
rails_root = kv.split(%r/=/,2).last if kv
|
410
|
+
|
411
|
+
### we know the rails_root if we are in RAILS_ROOT/script/
|
412
|
+
unless rails_root
|
413
|
+
if BJ_IS_SCRIPT
|
414
|
+
rails_root = File.expand_path "#{ File.dirname __FILE__ }/.."
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
### perhaps the current directory is a rails_root?
|
419
|
+
unless rails_root
|
420
|
+
if %w[ script config app ].map{|d| test(?d, d)}.all?
|
421
|
+
rails_root = File.expand_path "."
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
### bootstrap
|
426
|
+
RAILS_ROOT = rails_root
|
427
|
+
end #}}}
|
428
|
+
|
429
|
+
#
|
430
|
+
# setup RAILS_ENV
|
431
|
+
#
|
432
|
+
unless defined? RAILS_ENV #{{{
|
433
|
+
### grab env var first
|
434
|
+
rails_env = ENV["RAILS_ENV"]
|
435
|
+
|
436
|
+
### commandline usage clobbers
|
437
|
+
kv = nil
|
438
|
+
ARGV.delete_if{|arg| arg =~ %r/^RAILS_ENV=/ and kv = arg}
|
439
|
+
rails_env = kv.split(%r/=/,2).last if kv
|
440
|
+
|
441
|
+
### fallback to development
|
442
|
+
unless rails_env
|
443
|
+
rails_env = "development"
|
444
|
+
end
|
445
|
+
|
446
|
+
### bootstrap
|
447
|
+
RAILS_ENV = rails_env
|
448
|
+
end #}}}
|
449
|
+
|
450
|
+
#
|
451
|
+
# setup $LOAD_PATH to detect plugin - iff it is installed and running out of
|
452
|
+
# RAILS_ROOT/script
|
453
|
+
#
|
454
|
+
if RAILS_ROOT #{{{
|
455
|
+
if BJ_IS_SCRIPT and test(?d, "#{ RAILS_ROOT }/vendor/plugins/bj/lib")
|
456
|
+
$LOAD_PATH.unshift "#{ RAILS_ROOT }/vendor/plugins/bj/lib"
|
457
|
+
end
|
458
|
+
end #}}}
|
459
|
+
|
460
|
+
#
|
461
|
+
# ensure that rubygems is loaded
|
462
|
+
#
|
463
|
+
begin
|
464
|
+
require "rubygems"
|
465
|
+
rescue
|
466
|
+
42
|
467
|
+
end
|
468
|
+
|
469
|
+
#
|
470
|
+
# hack to_s of STDERR/STDOUT for nice help messages
|
471
|
+
#
|
472
|
+
class << STDERR
|
473
|
+
def to_s() 'STDERR' end
|
474
|
+
end
|
475
|
+
class << STDOUT
|
476
|
+
def to_s() 'STDOUT' end
|
477
|
+
end
|
478
|
+
}
|