bj 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. data/HISTORY +19 -14
  2. data/README +235 -57
  3. data/bin/bj +2 -1
  4. data/gemspec.rb +3 -2
  5. data/lib/bj.rb +4 -2
  6. data/lib/bj/attributes.rb +120 -0
  7. metadata +67 -68
data/HISTORY CHANGED
@@ -1,19 +1,24 @@
1
- 0.0.5:
2
- - use full path to ruby for plugin mode
3
- - plugin correctly installs bin -->> script
4
- - plugin install uses --force
5
- - properly quote paths in windows (spaces)
6
- - swith win signal to ABRT (was INT)
7
- - background job regrestration now uses ppid to pin the subprocess to a
8
- parent
9
- - use ppid to detect parent death and exit in event loop
10
- - don't use gem dependanices in plugin as they are broken when loading from
11
- muliple gem repos
12
- - added a small amount of drb magic that allows signals to work across
13
- processes even on windows (see http://drawohara.com/post/22540307)
1
+ 1.0.1:
2
+ - fixed name collision with 'record.attributes = hash' ar mass
3
+ assignment method (thx jon guymon)
4
+ - added new sponsor: http://igicom.com/
5
+
6
+ 0.0.5:
7
+ - use full path to ruby for plugin mode
8
+ - plugin correctly installs bin -->> script
9
+ - plugin install uses --force
10
+ - properly quote paths in windows (spaces)
11
+ - switch win signal to ABRT (was INT)
12
+ - background job regrestration now uses ppid to pin the subprocess to a
13
+ parent
14
+ - use ppid to detect parent death and exit in event loop
15
+ - don't use gem dependanices in plugin as they are broken when loading from
16
+ muliple gem repos
17
+ - added a small amount of drb magic that allows signals to work across
18
+ processes even on windows (see http://drawohara.com/post/22540307)
14
19
 
15
20
  0.0.4:
16
- - basic functionality in widows
21
+ - basic functionality in windows
17
22
  - several small bug fixes
18
23
 
19
24
  0.0.3:
data/README CHANGED
@@ -2,94 +2,257 @@ NAME
2
2
  bj
3
3
 
4
4
  SYNOPSIS
5
- bj (migration_code|generate_migration|migrate|setup|run|submit|list|set|config|pid) [options]+
5
+ bj (migration_code|generate_migration|migrate|setup|plugin|run|submit|list|set|config|pid) [options]+
6
6
 
7
7
  DESCRIPTION
8
8
  ________________________________
9
9
  Overview
10
10
  --------------------------------
11
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$.
12
+ Backgroundjob (Bj) is a brain dead simple zero admin background priority queue
13
+ for Rails. Bj is robust, platform independent (including windows), and
14
+ supports internal or external manangement of the background runner process.
15
15
 
16
- Jobs can be submitted to the queue directly using the api or from the
17
- commandline using the 'bj' script. For example
16
+ Jobs can be submitted to the queue directly using the api or from the command
17
+ line using the ./script/bj:
18
18
 
19
- code:
20
- Bj.submit 'cat /etc/password'
19
+ api:
20
+ Bj.submit 'cat /etc/password'
21
21
 
22
- cli:
23
- bj submit cat /etc/password
22
+ command line:
23
+ bj submit cat /etc/password
24
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:
25
+ Bj's priority queue lives in the database and is therefore durable - your jobs
26
+ will live across an app crash or machine reboot. The job management is
27
+ comprehensive capturing stdout, stderr, exit_status, and temporal statistics
28
+ about each job:
30
29
 
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
30
+ jobs = Bj.submit array_of_commands, :priority => 42
34
31
 
35
- Bj.in :production do
36
- Bj.submit 'production_job.exe'
37
- end
32
+ ...
38
33
 
39
- Bj.in :development do
40
- Bj.submit 'development_job.exe'
41
- end
34
+ jobs.each do |job|
35
+ if job.finished?
36
+ p job.stdout
37
+ p job.stderr
38
+ p job.exit_status
39
+ p job.started_at
40
+ p job.finished_at
41
+ end
42
+ end
43
+
44
+ In addition the background runner process logs all commands run and their
45
+ exit_status to a log named using the following convention:
46
+
47
+ rails_root/log/bj.#{ HOSTNAME }.#{ RAILS_ENV }.log
48
+
49
+ Bj allows you to submit jobs to multiple databases; for instance, if your
50
+ application is running in development mode you may do:
51
+
52
+ Bj.in :production do
53
+ Bj.submit 'my_job.exe'
54
+ end
55
+
56
+ Bj manages the ever growing list of jobs ran by automatically archiving them
57
+ into another table (by default jobs > 24 hrs old are archived) to prevent the
58
+ jobs table from becoming bloated and huge.
59
+
60
+ All Bj's tables are namespaced and accessible via the Bj module:
61
+
62
+ Bj.table.job.find(:all) # jobs table
63
+ Bj.table.job_archive.find(:all) # archived jobs
64
+ Bj.table.config.find(:all) # configuration and runner state
65
+
66
+ Bj always arranges for submitted jobs to run with a current working directory
67
+ of RAILS_ROOT and with the correct RAILS_ENV setting. For example, if you
68
+ submit a job in production it will have ENV['RAILS_ENV'] == 'production'.
69
+
70
+ When Bj manages the background runner it will never outlive the rails
71
+ application - it is started and stopped on demand as the rails app is started
72
+ and stopped. This is also true for ./script/console - Bj will automatically
73
+ fire off the background runner to process jobs submitted using the console.
74
+
75
+ Bj ensures that only one background process is running for your application -
76
+ firing up three mongrels or fcgi processes will result in only one background
77
+ runner being started. Note that the number of background runners does not
78
+ determine throughput - that is determined primarily by the nature of the jobs
79
+ themselves and how much work they perform per process.
42
80
 
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
81
 
49
82
  ________________________________
50
- Install
83
+ Architecture
51
84
  --------------------------------
85
+
86
+ If one ignores platform specific details the design of Bj is quite simple: the
87
+ main Rails application submits jobs to table, stored in the database. The act
88
+ of submitting triggers exactly one of two things to occur:
89
+
90
+ 1) a new long running background runner to be started
91
+
92
+ 2) an existing background runner to be signaled
93
+
94
+ The background runner refuses to run two copies of itself for a given
95
+ hostname/rails_env combination. For example you may only have one background
96
+ runner processing jobs on localhost in development mode.
97
+
98
+ The background runner, under normal circumstances, is managed by Bj itself -
99
+ you need do nothing to start, monitor, or stop it - it just works. However,
100
+ some people will prefer manage their own background process, see 'External
101
+ Runner' section below for more on this.
102
+
103
+ The runner simply processes each job in a highest priority oldest-in fashion,
104
+ capturing stdout, stderr, exit_status, etc. and storing the information back
105
+ into the database while logging it's actions. When there are no jobs to run
106
+ the runner goes to sleep for 42 seconds; however this sleep is interuptable,
107
+ such as when the runner is signaled that a new job has been submitted so,
108
+ under normal circumstances there will be zero lag between job submission and
109
+ job running for an empty queue.
110
+
111
+
112
+ ________________________________
113
+ External Runner / Clustering
114
+ --------------------------------
115
+
116
+ For the paranoid control freaks out there (myself included) it is quite
117
+ possible to manage and monitor the runner process manually. This can be
118
+ desirable in production setups where monitoring software may kill leaking
119
+ rails apps periodically.
120
+
121
+ Recalling that Bj will only allow one copy of itself to process jobs per
122
+ hostname/rails_env pair we can simply do something like this in cron
123
+
124
+ cmd = bj run --forever \
125
+ --rails_env=development \
126
+ --rails_root=/Users/ahoward/rails_root
127
+
128
+ */15 * * * * $cmd
129
+
130
+ this will simply attempt the start the background runner every 15 minutes if,
131
+ and only if, it's not *already* running.
132
+
133
+ In addtion to this you'll want to tell Bj not to manage the runner itself
134
+ using
135
+
136
+ Bj.config["production.no_tickle"] = true
137
+
138
+ Note that, for clusting setups, it's as simple as adding a crontab and config
139
+ entry like this for each host. Because Bj throttles background runners per
140
+ hostname this will allow one runner per hostname - making it quite simple to
141
+ cluster three nodes behind a besieged rails application.
142
+
143
+
144
+ ________________________________
145
+ Designing Jobs
146
+ --------------------------------
147
+
148
+ Bj runs it's jobs as command line applications. It ensures that all jobs run
149
+ in RAILS_ROOT so it's quite natural to apply a pattern such as
150
+
151
+ mkdir ./jobs
152
+ edit ./jobs/background_job_to_run
153
+
154
+ ...
155
+
156
+ Bj.submit "./jobs/background_job_to_run"
157
+
158
+ If you need to run you jobs under an entire rails environment you'll need to
159
+ do this:
160
+
161
+ Bj.submit "./script/runner ./jobs/background_job_to_run"
162
+
163
+ Obviously "./script/runner" loads the rails environment for you. It's worth
164
+ noting that this happens for each job and that this is by design: the reason
165
+ is that most rails applications leak memory like a sieve so, if one were to
166
+ spawn a long running process that used the application code base you'd have a
167
+ lovely doubling of memory usage on you app servers. Although loading the
168
+ rails environment for each background job requires a little time, a little
169
+ cpu, and a lot less memory. A future version of Bj will provide a way to load
170
+ the rails environment once and to process background jobs in this environment,
171
+ but anyone wanting to use this in production will be required to duct tape
172
+ their entire chest and have a team of oxen rip off the tape without screaming
173
+ to prove steelyness of spirit and profound understanding of the other side.
174
+
175
+ Don't forget that you can submit jobs with command line arguments:
176
+
177
+ Bj.submit "./jobs/a.rb 1 foobar --force"
178
+
179
+ and that you can do powerful things by passing stdin to a job that powers
180
+ through a list of work. For instance, assume a "./jobs/bulkmail" job
181
+ resembling
182
+
183
+ STDIN.each do |line|
184
+ address = line.strip
185
+ mail_message_to address
186
+ end
52
187
 
53
- Bj can be installed two ways: as a gem or as a plugin.
188
+ then you could
54
189
 
55
- gem:
190
+ stdin = [
191
+ "foo@bar.com",
192
+ "bar@foo.com",
193
+ "ara.t.howard@codeforpeople.com",
194
+ ]
56
195
 
57
- 1) $sudo gem install bj
58
- 2) bj setup ./rails_root/
196
+ Bj.submit "./script/runner ./jobs/bulkmail", :stdin => stdin
197
+
198
+ and all those emails would be sent in the background.
199
+
200
+ Bj's power is putting jobs in the background in a simple and robust fashion.
201
+ It's your task to build intelligent jobs that leverage batch processing, and
202
+ other, possibilities. The upshot of building tasks this way is that they are
203
+ quite easy to test before submitting them from inside your application.
59
204
 
60
- plugin:
61
205
 
206
+ ________________________________
207
+ Install
208
+ --------------------------------
209
+
210
+ Bj can be installed two ways: as a plugin or via rubygems
211
+
212
+ plugin:
62
213
  1) ./script/plugin install http://codeforpeople.rubyforge.org/svn/rails/plugins/bj
63
214
  2) ./script/bj setup
64
215
 
216
+ gem:
217
+ 1) $sudo gem install bj
218
+ 2) add "require 'bj'" to config/environment.rb
219
+ 3) bj setup
220
+
65
221
  ________________________________
66
222
  Api
67
223
  --------------------------------
68
224
 
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.
225
+ submit jobs for background processing. 'jobs' can be a string or array of
226
+ strings. options are applied to each job in the 'jobs', and the list of
227
+ submitted jobs is always returned. options (string or symbol) can be
80
228
 
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'
229
+ :rails_env => production|development|key_in_database_yml
230
+ when given this keyword causes bj to submit jobs to the
231
+ specified database. default is RAILS_ENV.
232
+
233
+ :priority => any number, including negative ones. default is zero.
234
+
235
+ :tag => a tag added to the job. simply makes searching easier.
236
+
237
+ :env => a hash specifying any additional environment vars the background
238
+ process should have.
239
+
240
+ :stdin => any stdin the background process should have. must respond_to
241
+ to_s
91
242
 
92
- jobs = Bj.submit './script/runner ./scripts/a.rb', :rails_env => 'production'
243
+ eg:
244
+
245
+ jobs = Bj.submit 'echo foobar', :tag => 'simple job'
246
+
247
+ jobs = Bj.submit '/bin/cat', :stdin => 'in the hat', :priority => 42
248
+
249
+ jobs = Bj.submit './script/runner ./scripts/a.rb', :rails_env => 'production'
250
+
251
+ jobs = Bj.submit './script/runner /dev/stdin',
252
+ :stdin => 'p RAILS_ENV',
253
+ :tag => 'dynamic ruby code'
254
+
255
+ jobs Bj.submit array_of_commands, :priority => 451
93
256
 
94
257
  when jobs are run, they are run in RAILS_ROOT. various attributes are
95
258
  available *only* once the job has finished. you can check whether or not a
@@ -110,6 +273,21 @@ DESCRIPTION
110
273
  end
111
274
 
112
275
  See lib/bj/api.rb for more details.
276
+
277
+ ________________________________
278
+ Sponsors
279
+ --------------------------------
280
+ http://quintess.com/
281
+ http://www.engineyard.com/
282
+ http://igicom.com/
283
+ http://eparklabs.com/
284
+
285
+ http://your_company.com/ <<-- (targeted marketing aimed at *you*)
286
+
287
+ ________________________________
288
+ Version
289
+ --------------------------------
290
+ 1.0.1
113
291
 
114
292
  PARAMETERS
115
293
  --rails_root=rails_root, -R (0 ~> rails_root=)
data/bin/bj CHANGED
@@ -277,8 +277,9 @@ Main {
277
277
  ________________________________
278
278
  Sponsors
279
279
  --------------------------------
280
- http://www.engineyard.com/
281
280
  http://quintess.com/
281
+ http://www.engineyard.com/
282
+ http://igicom.com/
282
283
  http://eparklabs.com/
283
284
 
284
285
  http://your_company.com/ <<-- (targeted marketing aimed at *you*)
data/gemspec.rb CHANGED
@@ -12,11 +12,11 @@ Gem::Specification::new do |spec|
12
12
  spec.executables = Dir::glob("bin/*").map{|exe| File::basename exe}
13
13
 
14
14
  spec.require_path = "lib"
15
- spec.autorequire = lib
15
+ #spec.autorequire = lib
16
16
 
17
17
  spec.has_rdoc = File::exist? "doc"
18
18
  spec.test_suite_file = "test/#{ lib }.rb" if File::directory? "test"
19
- spec.add_dependency 'attributes', '>= 5.0.0'
19
+ #spec.add_dependency 'attributes', '>= 5.0.0'
20
20
  spec.add_dependency 'main', '>= 2.6.0'
21
21
  spec.add_dependency 'systemu', '>= 1.2.0'
22
22
  spec.add_dependency 'orderedhash', '>= 0.0.3'
@@ -26,4 +26,5 @@ Gem::Specification::new do |spec|
26
26
  spec.author = "Ara T. Howard"
27
27
  spec.email = "ara.t.howard@gmail.com"
28
28
  spec.homepage = "http://codeforpeople.com/lib/ruby/#{ lib }/"
29
+ spec.rubyforge_project = "codeforpeople"
29
30
  end
data/lib/bj.rb CHANGED
@@ -3,7 +3,7 @@ unless defined? Bj
3
3
  #
4
4
  # constants and associated attrs
5
5
  #
6
- Bj::VERSION = "1.0.0" #unless defined? Bj::VERSION
6
+ Bj::VERSION = "1.0.1" #unless defined? Bj::VERSION
7
7
  def self.version() Bj::VERSION end
8
8
 
9
9
  Bj::LIBDIR = File.expand_path(File::join(File.dirname(__FILE__), "bj")) + File::SEPARATOR unless
@@ -46,7 +46,8 @@ unless defined? Bj
46
46
  #
47
47
  # rubyforge/remote or local/lib
48
48
  #
49
- %w[ attributes systemu orderedhash ].each do |lib|
49
+ #%w[ attributes systemu orderedhash ].each do |lib|
50
+ %w[ systemu orderedhash ].each do |lib|
50
51
  begin
51
52
  require lib
52
53
  rescue
@@ -56,6 +57,7 @@ unless defined? Bj
56
57
  #
57
58
  # local
58
59
  #
60
+ load libdir("attributes.rb")
59
61
  load libdir("stdext.rb")
60
62
  load libdir("util.rb")
61
63
  load libdir("errors.rb")
@@ -0,0 +1,120 @@
1
+ module Attributes
2
+ Attributes::VERSION = '5.0.0' unless defined? Attributes::VERSION
3
+ def self.version() Attributes::VERSION end
4
+
5
+ class List < ::Array
6
+ def << element
7
+ super
8
+ self
9
+ ensure
10
+ uniq!
11
+ index!
12
+ end
13
+ def index!
14
+ @index ||= Hash.new
15
+ each{|element| @index[element] = true}
16
+ end
17
+ def include? element
18
+ @index ||= Hash.new
19
+ @index[element] ? true : false
20
+ end
21
+ def initializers
22
+ @initializers ||= Hash.new
23
+ end
24
+ end
25
+
26
+ def attributes *a, &b
27
+ unless a.empty?
28
+ returned = Hash.new
29
+
30
+ hashes, names = a.partition{|x| Hash === x}
31
+ names_and_defaults = {}
32
+ hashes.each{|h| names_and_defaults.update h}
33
+ names.flatten.compact.each{|name| names_and_defaults.update name => nil}
34
+
35
+ initializers = __attributes__.initializers
36
+
37
+ names_and_defaults.each do |name, default|
38
+ raise NameError, "bad instance variable name '@#{ name }'" if "@#{ name }" =~ %r/[!?=]$/o
39
+ name = name.to_s
40
+
41
+ initialize = b || lambda { default }
42
+ initializer = lambda do |this|
43
+ Object.instance_method('instance_eval').bind(this).call &initialize
44
+ end
45
+ initializer_id = initializer.object_id
46
+ __attributes__.initializers[name] = initializer
47
+
48
+ module_eval <<-code
49
+ def #{ name }=(*value, &block)
50
+ value.unshift block if block
51
+ @#{ name } = value.first
52
+ end
53
+ code
54
+
55
+ module_eval <<-code
56
+ def #{ name }(*value, &block)
57
+ value.unshift block if block
58
+ return self.send('#{ name }=', value.first) unless value.empty?
59
+ #{ name }! unless defined? @#{ name }
60
+ @#{ name }
61
+ end
62
+ code
63
+
64
+ module_eval <<-code
65
+ def #{ name }!
66
+ initializer = ObjectSpace._id2ref #{ initializer_id }
67
+ self.#{ name } = initializer.call(self)
68
+ @#{ name }
69
+ end
70
+ code
71
+
72
+ module_eval <<-code
73
+ def #{ name }?
74
+ #{ name }
75
+ end
76
+ code
77
+
78
+ attributes << name
79
+ returned[name] = initializer
80
+ end
81
+
82
+ returned
83
+ else
84
+ begin
85
+ __attribute_list__
86
+ rescue NameError
87
+ singleton_class =
88
+ class << self
89
+ self
90
+ end
91
+ klass = self
92
+ singleton_class.module_eval do
93
+ attribute_list = List.new
94
+ define_method('attribute_list'){ klass == self ? attribute_list : raise(NameError) }
95
+ alias_method '__attribute_list__', 'attribute_list'
96
+ end
97
+ __attribute_list__
98
+ end
99
+ end
100
+ end
101
+
102
+ %w( __attributes__ __attribute__ attribute ).each{|dst| alias_method dst, 'attributes'}
103
+ end
104
+
105
+ =begin
106
+ class Object
107
+ def attributes *a, &b
108
+ sc =
109
+ class << self
110
+ self
111
+ end
112
+ sc.attributes *a, &b
113
+ end
114
+ %w( __attributes__ __attribute__ attribute ).each{|dst| alias_method dst, 'attributes'}
115
+ end
116
+ =end
117
+
118
+ class Module
119
+ include Attributes
120
+ end
metadata CHANGED
@@ -1,80 +1,21 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.4
3
- specification_version: 1
4
2
  name: bj
5
3
  version: !ruby/object:Gem::Version
6
- version: 1.0.0
7
- date: 2007-12-28 00:00:00 -07:00
8
- summary: bj
9
- require_paths:
10
- - lib
11
- email: ara.t.howard@gmail.com
12
- homepage: http://codeforpeople.com/lib/ruby/bj/
13
- rubyforge_project:
14
- description:
15
- autorequire: bj
16
- default_executable:
17
- bindir: bin
18
- has_rdoc: false
19
- required_ruby_version: !ruby/object:Gem::Version::Requirement
20
- requirements:
21
- - - ">"
22
- - !ruby/object:Gem::Version
23
- version: 0.0.0
24
- version:
4
+ version: 1.0.1
25
5
  platform: ruby
26
- signing_key:
27
- cert_chain:
28
- post_install_message:
29
6
  authors:
30
7
  - Ara T. Howard
31
- files:
32
- - bin
33
- - bin/bj
34
- - gemspec.rb
35
- - HISTORY
36
- - install.rb
37
- - lib
38
- - lib/bj
39
- - lib/bj/api.rb
40
- - lib/bj/bj.rb
41
- - lib/bj/errors.rb
42
- - lib/bj/joblist.rb
43
- - lib/bj/logger.rb
44
- - lib/bj/runner.rb
45
- - lib/bj/stdext.rb
46
- - lib/bj/table.rb
47
- - lib/bj/util.rb
48
- - lib/bj.rb
49
- - rakefile
50
- - README
51
- - TODO
52
- test_files: []
53
-
54
- rdoc_options: []
55
-
56
- extra_rdoc_files: []
57
-
58
- executables:
59
- - bj
60
- extensions: []
61
-
62
- requirements: []
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
63
11
 
12
+ date: 2008-01-08 00:00:00 -07:00
13
+ default_executable:
64
14
  dependencies:
65
- - !ruby/object:Gem::Dependency
66
- name: attributes
67
- version_requirement:
68
- version_requirements: !ruby/object:Gem::Version::Requirement
69
- requirements:
70
- - - ">="
71
- - !ruby/object:Gem::Version
72
- version: 5.0.0
73
- version:
74
15
  - !ruby/object:Gem::Dependency
75
16
  name: main
76
17
  version_requirement:
77
- version_requirements: !ruby/object:Gem::Version::Requirement
18
+ version_requirements: !ruby/object:Gem::Requirement
78
19
  requirements:
79
20
  - - ">="
80
21
  - !ruby/object:Gem::Version
@@ -83,7 +24,7 @@ dependencies:
83
24
  - !ruby/object:Gem::Dependency
84
25
  name: systemu
85
26
  version_requirement:
86
- version_requirements: !ruby/object:Gem::Version::Requirement
27
+ version_requirements: !ruby/object:Gem::Requirement
87
28
  requirements:
88
29
  - - ">="
89
30
  - !ruby/object:Gem::Version
@@ -92,9 +33,67 @@ dependencies:
92
33
  - !ruby/object:Gem::Dependency
93
34
  name: orderedhash
94
35
  version_requirement:
95
- version_requirements: !ruby/object:Gem::Version::Requirement
36
+ version_requirements: !ruby/object:Gem::Requirement
96
37
  requirements:
97
38
  - - ">="
98
39
  - !ruby/object:Gem::Version
99
40
  version: 0.0.3
100
41
  version:
42
+ description:
43
+ email: ara.t.howard@gmail.com
44
+ executables:
45
+ - bj
46
+ extensions: []
47
+
48
+ extra_rdoc_files: []
49
+
50
+ files:
51
+ - bin
52
+ - bin/bj
53
+ - gemspec.rb
54
+ - HISTORY
55
+ - install.rb
56
+ - lib
57
+ - lib/bj
58
+ - lib/bj/api.rb
59
+ - lib/bj/attributes.rb
60
+ - lib/bj/bj.rb
61
+ - lib/bj/errors.rb
62
+ - lib/bj/joblist.rb
63
+ - lib/bj/logger.rb
64
+ - lib/bj/runner.rb
65
+ - lib/bj/stdext.rb
66
+ - lib/bj/table.rb
67
+ - lib/bj/util.rb
68
+ - lib/bj.rb
69
+ - rakefile
70
+ - README
71
+ - TODO
72
+ has_rdoc: false
73
+ homepage: http://codeforpeople.com/lib/ruby/bj/
74
+ post_install_message:
75
+ rdoc_options: []
76
+
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: "0"
84
+ version:
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: "0"
90
+ version:
91
+ requirements: []
92
+
93
+ rubyforge_project: codeforpeople
94
+ rubygems_version: 1.0.1
95
+ signing_key:
96
+ specification_version: 2
97
+ summary: bj
98
+ test_files: []
99
+