bj_fixed_for_rails3 1.0.2
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 +64 -0
- data/README +308 -0
- data/TODO +40 -0
- data/bin/bj +680 -0
- data/bj-1.0.2.gem +0 -0
- data/gemspec.rb +30 -0
- data/install.rb +210 -0
- data/lib/bj/api.rb +161 -0
- data/lib/bj/attributes.rb +120 -0
- data/lib/bj/bj.rb +72 -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 +357 -0
- data/lib/bj/stdext.rb +86 -0
- data/lib/bj/table.rb +384 -0
- data/lib/bj/util.rb +111 -0
- data/lib/bj.rb +88 -0
- metadata +131 -0
data/lib/bj/table.rb
ADDED
@@ -0,0 +1,384 @@
|
|
1
|
+
class Bj
|
2
|
+
#
|
3
|
+
# table base class
|
4
|
+
#
|
5
|
+
class Table < ActiveRecord::Base
|
6
|
+
module ClassMethods
|
7
|
+
attribute("list"){ Array.new }
|
8
|
+
attribute("migration"){}
|
9
|
+
|
10
|
+
def migration_code classname = "BjMigration"
|
11
|
+
<<-code
|
12
|
+
class #{ classname } < ActiveRecord::Migration
|
13
|
+
def self.up
|
14
|
+
Bj::Table.each{|table| table.up}
|
15
|
+
end
|
16
|
+
def self.down
|
17
|
+
Bj::Table.reverse_each{|table| table.down}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
code
|
21
|
+
end
|
22
|
+
|
23
|
+
def up
|
24
|
+
migration_class.up
|
25
|
+
end
|
26
|
+
|
27
|
+
def down
|
28
|
+
migration_class.down
|
29
|
+
end
|
30
|
+
|
31
|
+
def migration_class
|
32
|
+
table = self
|
33
|
+
@migration_class ||=
|
34
|
+
Class.new(ActiveRecord::Migration) do
|
35
|
+
sc =
|
36
|
+
class << self
|
37
|
+
self
|
38
|
+
end
|
39
|
+
sc.module_eval{ attribute :table => table }
|
40
|
+
sc.module_eval &table.migration
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def content_column_names
|
45
|
+
@content_column_names = content_columns.map{|column| column.name}
|
46
|
+
end
|
47
|
+
|
48
|
+
def create_hash_for options
|
49
|
+
options.to_options!
|
50
|
+
hash = {}
|
51
|
+
content_column_names.each do |key|
|
52
|
+
key = key.to_s.to_sym
|
53
|
+
hash[key] = options[key]
|
54
|
+
end
|
55
|
+
hash
|
56
|
+
end
|
57
|
+
|
58
|
+
def each *a, &b
|
59
|
+
list.each *a, &b
|
60
|
+
end
|
61
|
+
|
62
|
+
def reverse_each *a, &b
|
63
|
+
list.reverse.each *a, &b
|
64
|
+
end
|
65
|
+
end
|
66
|
+
send :extend, ClassMethods
|
67
|
+
|
68
|
+
module InstanceMethods
|
69
|
+
def to_hash
|
70
|
+
oh = OrderedHash.new
|
71
|
+
self.class.content_column_names.each{|c| oh[c] = self[c]}
|
72
|
+
oh
|
73
|
+
end
|
74
|
+
end
|
75
|
+
send :include, InstanceMethods
|
76
|
+
|
77
|
+
module RecursivelyInherited
|
78
|
+
def inherited other
|
79
|
+
super
|
80
|
+
ensure
|
81
|
+
(Table.list << other).uniq!
|
82
|
+
basename = other.name.split(%r/::/).last.underscore
|
83
|
+
Table.singleton_class{ attribute basename => other }
|
84
|
+
other.send :extend, RecursivelyInherited
|
85
|
+
end
|
86
|
+
end
|
87
|
+
send :extend, RecursivelyInherited
|
88
|
+
|
89
|
+
#
|
90
|
+
# table classes
|
91
|
+
#
|
92
|
+
class Job < Table
|
93
|
+
set_table_name "bj_job"
|
94
|
+
set_primary_key "#{ table_name }_id"
|
95
|
+
|
96
|
+
migration {
|
97
|
+
define_method :up do
|
98
|
+
create_table table.table_name, :primary_key => table.primary_key, :force => true do |t|
|
99
|
+
t.column "command" , :text
|
100
|
+
|
101
|
+
t.column "state" , :text
|
102
|
+
t.column "priority" , :integer
|
103
|
+
t.column "tag" , :text
|
104
|
+
t.column "is_restartable" , :integer
|
105
|
+
|
106
|
+
t.column "submitter" , :text
|
107
|
+
t.column "runner" , :text
|
108
|
+
t.column "pid" , :integer
|
109
|
+
|
110
|
+
t.column "submitted_at" , :datetime
|
111
|
+
t.column "started_at" , :datetime
|
112
|
+
t.column "finished_at" , :datetime
|
113
|
+
|
114
|
+
t.column "env" , :text
|
115
|
+
t.column "stdin" , :text
|
116
|
+
t.column "stdout" , :text
|
117
|
+
t.column "stderr" , :text
|
118
|
+
t.column "exit_status" , :integer
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
define_method :down do
|
123
|
+
drop_table table.table_name
|
124
|
+
end
|
125
|
+
}
|
126
|
+
|
127
|
+
module ClassMethods
|
128
|
+
def submit jobs, options = {}, &block
|
129
|
+
jobs = Joblist.for jobs, options
|
130
|
+
returned = []
|
131
|
+
transaction do
|
132
|
+
jobs.each do |job|
|
133
|
+
job = create_hash_for(job.reverse_merge(submit_defaults))
|
134
|
+
job = create! job
|
135
|
+
returned << (block ? block.call(job) : job)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
returned
|
139
|
+
end
|
140
|
+
|
141
|
+
def submit_defaults
|
142
|
+
{
|
143
|
+
:state => "pending",
|
144
|
+
:priority => 0,
|
145
|
+
:tag => "",
|
146
|
+
:is_restartable => true,
|
147
|
+
:submitter => Bj.hostname,
|
148
|
+
:submitted_at => Time.now,
|
149
|
+
}
|
150
|
+
end
|
151
|
+
end
|
152
|
+
send :extend, ClassMethods
|
153
|
+
|
154
|
+
module InstanceMethods
|
155
|
+
def title
|
156
|
+
"job[#{ id }](#{ command })"
|
157
|
+
end
|
158
|
+
def finished
|
159
|
+
reload
|
160
|
+
exit_status
|
161
|
+
end
|
162
|
+
alias_method "finished?", "finished"
|
163
|
+
end
|
164
|
+
send :include, InstanceMethods
|
165
|
+
end
|
166
|
+
|
167
|
+
class JobArchive < Job
|
168
|
+
set_table_name "bj_job_archive"
|
169
|
+
set_primary_key "#{ table_name }_id"
|
170
|
+
|
171
|
+
migration {
|
172
|
+
define_method(:up) do
|
173
|
+
create_table table.table_name, :primary_key => table.primary_key, :force => true do |t|
|
174
|
+
t.column "command" , :text
|
175
|
+
|
176
|
+
t.column "state" , :text
|
177
|
+
t.column "priority" , :integer
|
178
|
+
t.column "tag" , :text
|
179
|
+
t.column "is_restartable" , :integer
|
180
|
+
|
181
|
+
t.column "submitter" , :text
|
182
|
+
t.column "runner" , :text
|
183
|
+
t.column "pid" , :integer
|
184
|
+
|
185
|
+
t.column "submitted_at" , :datetime
|
186
|
+
t.column "started_at" , :datetime
|
187
|
+
t.column "finished_at" , :datetime
|
188
|
+
t.column "archived_at" , :datetime
|
189
|
+
|
190
|
+
t.column "env" , :text
|
191
|
+
t.column "stdin" , :text
|
192
|
+
t.column "stdout" , :text
|
193
|
+
t.column "stderr" , :text
|
194
|
+
t.column "exit_status" , :integer
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
define_method(:down) do
|
199
|
+
drop_table table.table_name
|
200
|
+
end
|
201
|
+
}
|
202
|
+
end
|
203
|
+
|
204
|
+
# TODO - initialize with a set of global defaults and fallback to those on perhaps '* * key'
|
205
|
+
class Config < Table
|
206
|
+
set_table_name "bj_config"
|
207
|
+
set_primary_key "#{ table_name }_id"
|
208
|
+
|
209
|
+
migration {
|
210
|
+
define_method(:up) do
|
211
|
+
create_table table.table_name, :primary_key => table.primary_key, :force => true do |t|
|
212
|
+
t.column "hostname" , :text
|
213
|
+
t.column "key" , :text
|
214
|
+
t.column "value" , :text
|
215
|
+
t.column "cast" , :text
|
216
|
+
end
|
217
|
+
|
218
|
+
begin
|
219
|
+
add_index table.table_name, %w[ hostname key ], :unique => true
|
220
|
+
rescue Exception
|
221
|
+
STDERR.puts "WARNING: your database does not support unique indexes on text fields!?"
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
define_method(:down) do
|
226
|
+
begin
|
227
|
+
remove_index table.table_name, :column => %w[ hostname key ]
|
228
|
+
rescue Exception
|
229
|
+
end
|
230
|
+
drop_table table.table_name
|
231
|
+
end
|
232
|
+
}
|
233
|
+
|
234
|
+
module ClassMethods
|
235
|
+
def [] key
|
236
|
+
get key
|
237
|
+
end
|
238
|
+
|
239
|
+
def get key, options = {}
|
240
|
+
transaction do
|
241
|
+
options.to_options!
|
242
|
+
hostname = options[:hostname] || Bj.hostname
|
243
|
+
record = find :first, :conditions => conditions(:key => key, :hostname => hostname)
|
244
|
+
record ? record.value : default_for(key)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
def conditions options = {}
|
249
|
+
options.to_options!
|
250
|
+
options.reverse_merge!(
|
251
|
+
:hostname => Bj.hostname
|
252
|
+
)
|
253
|
+
options
|
254
|
+
end
|
255
|
+
|
256
|
+
def default_for key
|
257
|
+
record = find :first, :conditions => conditions(:key => key, :hostname => '*')
|
258
|
+
record ? record.value : nil
|
259
|
+
end
|
260
|
+
|
261
|
+
def []= key, value
|
262
|
+
set key, value
|
263
|
+
end
|
264
|
+
|
265
|
+
def set key, value, options = {}
|
266
|
+
transaction do
|
267
|
+
options.to_options!
|
268
|
+
hostname = options[:hostname] || Bj.hostname
|
269
|
+
record = find :first, :conditions => conditions(:key => key, :hostname => hostname), :lock => true
|
270
|
+
cast = options[:cast] || cast_for(value)
|
271
|
+
key = key.to_s
|
272
|
+
value = value.to_s
|
273
|
+
if record
|
274
|
+
record["value"] = value
|
275
|
+
record["cast"] = cast
|
276
|
+
record.save!
|
277
|
+
else
|
278
|
+
create! :hostname => hostname, :key => key, :value => value, :cast => cast
|
279
|
+
end
|
280
|
+
value
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
def delete key
|
285
|
+
transaction do
|
286
|
+
record = find :first, :conditions => conditions(:key => key), :lock => true
|
287
|
+
if record
|
288
|
+
record.destroy
|
289
|
+
record
|
290
|
+
else
|
291
|
+
nil
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
def has_key? key
|
297
|
+
record = find :first, :conditions => conditions(:key => key)
|
298
|
+
record ? record : false
|
299
|
+
end
|
300
|
+
alias_method "has_key", "has_key?"
|
301
|
+
|
302
|
+
def keys
|
303
|
+
find(:all, :conditions => conditions).map(&:key)
|
304
|
+
end
|
305
|
+
|
306
|
+
def values
|
307
|
+
find(:all, :conditions => conditions).map(&:value)
|
308
|
+
end
|
309
|
+
|
310
|
+
def for options = {}
|
311
|
+
oh = OrderedHash.new
|
312
|
+
find(:all, :conditions => conditions(options)).each do |record|
|
313
|
+
oh[record.key] = record.value
|
314
|
+
end
|
315
|
+
oh
|
316
|
+
end
|
317
|
+
|
318
|
+
def cast_for value
|
319
|
+
case value
|
320
|
+
when TrueClass, FalseClass
|
321
|
+
'to_bool'
|
322
|
+
when NilClass
|
323
|
+
'to_nil'
|
324
|
+
when Fixnum, Bignum
|
325
|
+
'to_i'
|
326
|
+
when Float
|
327
|
+
'to_f'
|
328
|
+
when Time
|
329
|
+
'to_time'
|
330
|
+
when Symbol
|
331
|
+
'to_sym'
|
332
|
+
else
|
333
|
+
case value.to_s
|
334
|
+
when %r/^\d+$/
|
335
|
+
'to_i'
|
336
|
+
when %r/^\d+\.\d+$/
|
337
|
+
'to_f'
|
338
|
+
when %r/^nil$|^$/
|
339
|
+
'to_nil'
|
340
|
+
when %r/^true|false$/
|
341
|
+
'to_bool'
|
342
|
+
else
|
343
|
+
'to_s'
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
def casts
|
349
|
+
@casts ||= {
|
350
|
+
'to_bool' => lambda do |value|
|
351
|
+
value.to_s =~ %r/^true$/i ? true : false
|
352
|
+
end,
|
353
|
+
'to_i' => lambda do |value|
|
354
|
+
Integer value.to_s.gsub(%r/^(-)?0*/,'\1')
|
355
|
+
end,
|
356
|
+
'to_f' => lambda do |value|
|
357
|
+
Float value.to_s.gsub(%r/^0*/,'')
|
358
|
+
end,
|
359
|
+
'to_time' => lambda do |value|
|
360
|
+
Time.parse(value.to_s)
|
361
|
+
end,
|
362
|
+
'to_sym' => lambda do |value|
|
363
|
+
value.to_s.to_sym
|
364
|
+
end,
|
365
|
+
'to_nil' => lambda do |value|
|
366
|
+
value.to_s =~ %r/^nil$|^$/i ? nil : value.to_s
|
367
|
+
end,
|
368
|
+
'to_s' => lambda do |value|
|
369
|
+
value.to_s
|
370
|
+
end,
|
371
|
+
}
|
372
|
+
end
|
373
|
+
end
|
374
|
+
send :extend, ClassMethods
|
375
|
+
|
376
|
+
module InstanceMethods
|
377
|
+
def value
|
378
|
+
self.class.casts[cast][self["value"]]
|
379
|
+
end
|
380
|
+
end
|
381
|
+
send :include, InstanceMethods
|
382
|
+
end
|
383
|
+
end
|
384
|
+
end
|
data/lib/bj/util.rb
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
class Bj
|
2
|
+
module Util
|
3
|
+
module ModuleMethods
|
4
|
+
def constant_get const, &block
|
5
|
+
begin
|
6
|
+
ancestors = const.split(%r/::/)
|
7
|
+
parent = Object
|
8
|
+
while((child = ancestors.shift))
|
9
|
+
klass = parent.const_get child
|
10
|
+
parent = klass
|
11
|
+
end
|
12
|
+
klass
|
13
|
+
rescue
|
14
|
+
block ? block.call : raise
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def const_or_env const, &block
|
19
|
+
constant_get(const){ ENV[const] || block.call }
|
20
|
+
end
|
21
|
+
|
22
|
+
def spawn cmd, options = {}
|
23
|
+
options.to_options!
|
24
|
+
logger = options.has_key?(:logger) ? options[:logger] : Bj.logger
|
25
|
+
logger.info{ "cmd <#{ cmd }>" } if logger
|
26
|
+
status = systemu cmd, 1=>(stdout=""), 2=>(stderr="")
|
27
|
+
logger.info{ "status <#{ status.exitstatus }>" } if logger
|
28
|
+
status.exitstatus.zero? or raise "#{ cmd.inspect } failed with #{ $?.inspect }"
|
29
|
+
[ stdout, stderr ]
|
30
|
+
end
|
31
|
+
|
32
|
+
def start *a
|
33
|
+
q = Queue.new
|
34
|
+
thread = Thread.new do
|
35
|
+
Thread.current.abort_on_exception = true
|
36
|
+
systemu(*a){|pid| q << pid}
|
37
|
+
end
|
38
|
+
pid = q.pop
|
39
|
+
thread.singleton_class{ define_method(:pid){ pid } }
|
40
|
+
thread
|
41
|
+
end
|
42
|
+
|
43
|
+
def alive pid
|
44
|
+
return false unless pid
|
45
|
+
pid = Integer pid.to_s
|
46
|
+
Process::kill 0, pid
|
47
|
+
true
|
48
|
+
rescue Errno::ESRCH, Errno::EPERM
|
49
|
+
false
|
50
|
+
end
|
51
|
+
alias_method "alive?", "alive"
|
52
|
+
|
53
|
+
def which_ruby
|
54
|
+
c = ::Config::CONFIG
|
55
|
+
ruby = File::join(c['bindir'], c['ruby_install_name']) << c['EXEEXT']
|
56
|
+
raise "ruby @ #{ ruby } not executable!?" unless test(?e, ruby)
|
57
|
+
ruby
|
58
|
+
end
|
59
|
+
|
60
|
+
def which_rake
|
61
|
+
tmp = Tempfile.new Process.pid
|
62
|
+
tmp.write "task(:foobar){ puts 42 }"
|
63
|
+
tmp.close
|
64
|
+
bat = spawn("rake.bat -f #{ tmp.path.inspect } foobar", :logger => false) rescue false
|
65
|
+
bat ? "rake.bat" : "rake"
|
66
|
+
ensure
|
67
|
+
tmp.close! rescue nil
|
68
|
+
end
|
69
|
+
|
70
|
+
def ipc_signals_supported
|
71
|
+
@ipc_signals_supported ||=
|
72
|
+
IO.popen 'ruby', 'r+' do |ruby|
|
73
|
+
pid = ruby.pid
|
74
|
+
begin
|
75
|
+
Process.kill 'TERM', pid
|
76
|
+
true
|
77
|
+
rescue Exception
|
78
|
+
false
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
alias_method "ipc_signals_supported?", "ipc_signals_supported"
|
83
|
+
|
84
|
+
def find_script basename
|
85
|
+
path = ENV["PATH"] || ENV["path"] || Bj.default_path
|
86
|
+
raise "no env PATH" unless path
|
87
|
+
path = path.split File::PATH_SEPARATOR
|
88
|
+
path.unshift File.join(Bj.rails_root, "script")
|
89
|
+
path.each do |directory|
|
90
|
+
script = File.join directory, basename
|
91
|
+
return File.expand_path(script) if(test(?s, script) and test(?r, script))
|
92
|
+
end
|
93
|
+
raise "no #{ basename } found in #{ path.inspect }"
|
94
|
+
end
|
95
|
+
|
96
|
+
def valid_rails_root root = ".", expected = %w[ config script app ]
|
97
|
+
directories = expected.flatten.compact.map{|dir| dir.to_s}
|
98
|
+
directories.all?{|dir| test(?d, File.join(root, dir))}
|
99
|
+
end
|
100
|
+
alias_method "valid_rails_root?", "valid_rails_root"
|
101
|
+
|
102
|
+
def emsg e
|
103
|
+
m = e.message rescue ""
|
104
|
+
c = e.class rescue Exception
|
105
|
+
b = e.backtrace.join("\n") rescue ""
|
106
|
+
"#{ m }(#{ c })\n#{ b }"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
send :extend, ModuleMethods
|
110
|
+
end
|
111
|
+
end
|
data/lib/bj.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
unless defined? Bj
|
2
|
+
class Bj
|
3
|
+
#
|
4
|
+
# constants and associated attrs
|
5
|
+
#
|
6
|
+
Bj::VERSION = "1.0.1" #unless defined? Bj::VERSION
|
7
|
+
def self.version() Bj::VERSION end
|
8
|
+
|
9
|
+
Bj::LIBDIR = File.expand_path(File::join(File.dirname(__FILE__), "bj")) + File::SEPARATOR unless
|
10
|
+
defined? Bj::LIBDIR
|
11
|
+
def self.libdir(*value)
|
12
|
+
unless value.empty?
|
13
|
+
File.join libdir, *value
|
14
|
+
else
|
15
|
+
Bj::LIBDIR
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module EXIT
|
20
|
+
SUCCESS = 0
|
21
|
+
FAILURE = 1
|
22
|
+
WARNING = 42
|
23
|
+
end
|
24
|
+
#
|
25
|
+
# built-in
|
26
|
+
#
|
27
|
+
require "socket"
|
28
|
+
require "yaml"
|
29
|
+
require "thread"
|
30
|
+
require "rbconfig"
|
31
|
+
require "set"
|
32
|
+
require "erb"
|
33
|
+
require "tempfile"
|
34
|
+
require "logger"
|
35
|
+
#
|
36
|
+
# bootstrap rubygems
|
37
|
+
#
|
38
|
+
begin
|
39
|
+
require "rubygems"
|
40
|
+
rescue LoadError
|
41
|
+
42
|
42
|
+
end
|
43
|
+
#
|
44
|
+
# rubyforge/remote
|
45
|
+
#
|
46
|
+
require "active_record"
|
47
|
+
#
|
48
|
+
# rubyforge/remote or local/lib
|
49
|
+
#
|
50
|
+
#%w[ attributes systemu orderedhash ].each do |lib|
|
51
|
+
%w[ systemu orderedhash ].each do |lib|
|
52
|
+
begin
|
53
|
+
require lib
|
54
|
+
rescue
|
55
|
+
require libdir(lib)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
#
|
59
|
+
# local
|
60
|
+
#
|
61
|
+
load libdir("attributes.rb")
|
62
|
+
load libdir("stdext.rb")
|
63
|
+
load libdir("util.rb")
|
64
|
+
load libdir("errors.rb")
|
65
|
+
load libdir("logger.rb")
|
66
|
+
load libdir("bj.rb")
|
67
|
+
load libdir("joblist.rb")
|
68
|
+
load libdir("table.rb")
|
69
|
+
load libdir("runner.rb")
|
70
|
+
load libdir("api.rb")
|
71
|
+
#
|
72
|
+
# an imperfect reloading hook - because neither rails' plugins nor gems provide one, sigh...
|
73
|
+
#
|
74
|
+
def self.reload!
|
75
|
+
background = nil
|
76
|
+
::Object.module_eval do
|
77
|
+
background = Bj.runner.background
|
78
|
+
remove_const :Bj rescue nil
|
79
|
+
remove_const :BackgroundJob rescue nil
|
80
|
+
end
|
81
|
+
returned = load __FILE__ rescue nil
|
82
|
+
Bj.runner.background = background if background
|
83
|
+
returned
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
BackgroundJob = Bj
|
88
|
+
end
|
metadata
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bj_fixed_for_rails3
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 19
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 2
|
10
|
+
version: 1.0.2
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Ara T. Howard
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-12-15 00:00:00 -08:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: main
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 23
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 6
|
33
|
+
- 0
|
34
|
+
version: 2.6.0
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: systemu
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 31
|
46
|
+
segments:
|
47
|
+
- 1
|
48
|
+
- 2
|
49
|
+
- 0
|
50
|
+
version: 1.2.0
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: orderedhash
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
hash: 25
|
62
|
+
segments:
|
63
|
+
- 0
|
64
|
+
- 0
|
65
|
+
- 3
|
66
|
+
version: 0.0.3
|
67
|
+
type: :runtime
|
68
|
+
version_requirements: *id003
|
69
|
+
description:
|
70
|
+
email: ara.t.howard@gmail.com
|
71
|
+
executables:
|
72
|
+
- bj
|
73
|
+
extensions: []
|
74
|
+
|
75
|
+
extra_rdoc_files: []
|
76
|
+
|
77
|
+
files:
|
78
|
+
- bin/bj
|
79
|
+
- bj-1.0.2.gem
|
80
|
+
- gemspec.rb
|
81
|
+
- HISTORY
|
82
|
+
- install.rb
|
83
|
+
- lib/bj/api.rb
|
84
|
+
- lib/bj/attributes.rb
|
85
|
+
- lib/bj/bj.rb
|
86
|
+
- lib/bj/errors.rb
|
87
|
+
- lib/bj/joblist.rb
|
88
|
+
- lib/bj/logger.rb
|
89
|
+
- lib/bj/runner.rb
|
90
|
+
- lib/bj/stdext.rb
|
91
|
+
- lib/bj/table.rb
|
92
|
+
- lib/bj/util.rb
|
93
|
+
- lib/bj.rb
|
94
|
+
- README
|
95
|
+
- TODO
|
96
|
+
has_rdoc: true
|
97
|
+
homepage: http://codeforpeople.com/lib/ruby/bj_fixed_for_rails3/
|
98
|
+
licenses: []
|
99
|
+
|
100
|
+
post_install_message:
|
101
|
+
rdoc_options: []
|
102
|
+
|
103
|
+
require_paths:
|
104
|
+
- lib
|
105
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
hash: 3
|
111
|
+
segments:
|
112
|
+
- 0
|
113
|
+
version: "0"
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
+
none: false
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
hash: 3
|
120
|
+
segments:
|
121
|
+
- 0
|
122
|
+
version: "0"
|
123
|
+
requirements: []
|
124
|
+
|
125
|
+
rubyforge_project: codeforpeople
|
126
|
+
rubygems_version: 1.3.7
|
127
|
+
signing_key:
|
128
|
+
specification_version: 3
|
129
|
+
summary: bj_fixed_for_rails3
|
130
|
+
test_files: []
|
131
|
+
|