bjj 1.0.3

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.
@@ -0,0 +1,214 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rbconfig'
3
+ require 'find'
4
+ require 'ftools'
5
+ require 'tempfile'
6
+ include Config
7
+
8
+ LIBDIR = "lib"
9
+ LIBDIR_MODE = 0644
10
+
11
+ BINDIR = "bin"
12
+ BINDIR_MODE = 0755
13
+
14
+
15
+ $srcdir = CONFIG["srcdir"]
16
+ $version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
17
+ $libdir = File.join(CONFIG["libdir"], "ruby", $version)
18
+ $archdir = File.join($libdir, CONFIG["arch"])
19
+ $site_libdir = $:.find {|x| x =~ /site_ruby$/}
20
+ $bindir = CONFIG["bindir"] || CONFIG['BINDIR']
21
+ $ruby_install_name = CONFIG['ruby_install_name'] || CONFIG['RUBY_INSTALL_NAME'] || 'ruby'
22
+ $ruby_ext = CONFIG['EXEEXT'] || ''
23
+ $ruby = File.join($bindir, ($ruby_install_name + $ruby_ext))
24
+
25
+ if !$site_libdir
26
+ $site_libdir = File.join($libdir, "site_ruby")
27
+ elsif $site_libdir !~ %r/#{Regexp.quote($version)}/
28
+ $site_libdir = File.join($site_libdir, $version)
29
+ end
30
+
31
+ def install_rb(srcdir=nil, destdir=nil, mode=nil, bin=nil)
32
+ #{{{
33
+ path = []
34
+ dir = []
35
+ Find.find(srcdir) do |f|
36
+ next unless FileTest.file?(f)
37
+ next if (f = f[srcdir.length+1..-1]) == nil
38
+ next if (/CVS$/ =~ File.dirname(f))
39
+ next if (/\.svn/ =~ File.dirname(f))
40
+ next if f =~ %r/\.lnk/
41
+ next if f =~ %r/\.svn/
42
+ next if f =~ %r/\.swp/
43
+ next if f =~ %r/\.svn/
44
+ path.push f
45
+ dir |= [File.dirname(f)]
46
+ end
47
+ for f in dir
48
+ next if f == "."
49
+ next if f == "CVS"
50
+ File::makedirs(File.join(destdir, f))
51
+ end
52
+ for f in path
53
+ next if (/\~$/ =~ f)
54
+ next if (/^\./ =~ File.basename(f))
55
+ unless bin
56
+ File::install(File.join(srcdir, f), File.join(destdir, f), mode, true)
57
+ else
58
+ from = File.join(srcdir, f)
59
+ to = File.join(destdir, f)
60
+ shebangify(from) do |sf|
61
+ $deferr.print from, " -> ", File::catname(from, to), "\n"
62
+ $deferr.printf "chmod %04o %s\n", mode, to
63
+ File::install(sf, to, mode, false)
64
+ end
65
+ end
66
+ end
67
+ #}}}
68
+ end
69
+ def shebangify f
70
+ #{{{
71
+ open(f) do |fd|
72
+ buf = fd.read 42
73
+ if buf =~ %r/^\s*#\s*!.*ruby/o
74
+ ftmp = Tempfile::new("#{ $$ }_#{ File::basename(f) }")
75
+ begin
76
+ fd.rewind
77
+ ftmp.puts "#!#{ $ruby }"
78
+ while((buf = fd.read(8192)))
79
+ ftmp.write buf
80
+ end
81
+ ftmp.close
82
+ yield ftmp.path
83
+ ensure
84
+ ftmp.close!
85
+ end
86
+ else
87
+ yield f
88
+ end
89
+ end
90
+ #}}}
91
+ end
92
+ def ARGV.switch
93
+ #{{{
94
+ return nil if self.empty?
95
+ arg = self.shift
96
+ return nil if arg == '--'
97
+ if arg =~ /^-(.)(.*)/
98
+ return arg if $1 == '-'
99
+ raise 'unknown switch "-"' if $2.index('-')
100
+ self.unshift "-#{$2}" if $2.size > 0
101
+ "-#{$1}"
102
+ else
103
+ self.unshift arg
104
+ nil
105
+ end
106
+ #}}}
107
+ end
108
+ def ARGV.req_arg
109
+ #{{{
110
+ self.shift || raise('missing argument')
111
+ #}}}
112
+ end
113
+ def linkify d, linked = []
114
+ #--{{{
115
+ if test ?d, d
116
+ versioned = Dir[ File::join(d, "*-[0-9].[0-9].[0-9].rb") ]
117
+ versioned.each do |v|
118
+ src, dst = v, v.gsub(%r/\-[\d\.]+\.rb$/, '.rb')
119
+ lnk = nil
120
+ begin
121
+ if test ?l, dst
122
+ lnk = "#{ dst }.lnk"
123
+ puts "#{ dst } -> #{ lnk }"
124
+ File::rename dst, lnk
125
+ end
126
+ unless test ?e, dst
127
+ puts "#{ src } -> #{ dst }"
128
+ File::copy src, dst
129
+ linked << dst
130
+ end
131
+ ensure
132
+ if lnk
133
+ at_exit do
134
+ puts "#{ lnk } -> #{ dst }"
135
+ File::rename lnk, dst
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
141
+ linked
142
+ #--}}}
143
+ end
144
+
145
+
146
+ #
147
+ # main program
148
+ #
149
+
150
+ libdir = $site_libdir
151
+ bindir = $bindir
152
+ no_linkify = false
153
+ linked = nil
154
+ help = false
155
+
156
+ usage = <<-usage
157
+ #{ File::basename $0 }
158
+ -d, --destdir <destdir>
159
+ -l, --libdir <libdir>
160
+ -b, --bindir <bindir>
161
+ -r, --ruby <ruby>
162
+ -n, --no_linkify
163
+ -s, --sudo
164
+ -h, --help
165
+ usage
166
+
167
+ begin
168
+ while switch = ARGV.switch
169
+ case switch
170
+ when '-d', '--destdir'
171
+ libdir = ARGV.req_arg
172
+ when '-l', '--libdir'
173
+ libdir = ARGV.req_arg
174
+ when '-b', '--bindir'
175
+ bindir = ARGV.req_arg
176
+ when '-r', '--ruby'
177
+ $ruby = ARGV.req_arg
178
+ when '-n', '--no_linkify'
179
+ no_linkify = true
180
+ when '-s', '--sudo'
181
+ sudo = 'sudo'
182
+ when '-h', '--help'
183
+ help = true
184
+ else
185
+ raise "unknown switch #{switch.dump}"
186
+ end
187
+ end
188
+ rescue
189
+ STDERR.puts $!.to_s
190
+ STDERR.puts usage
191
+ exit 1
192
+ end
193
+
194
+ if help
195
+ STDOUT.puts usage
196
+ exit
197
+ end
198
+
199
+ system "#{ sudo } #{ $ruby } pre-install.rb" if test(?s, 'pre-install.rb')
200
+
201
+ unless no_linkify
202
+ linked = linkify('lib') + linkify('bin')
203
+ end
204
+
205
+ system "#{ $ruby } extconf.rb && make && #{ sudo } make install" if test(?s, 'extconf.rb')
206
+
207
+ install_rb(LIBDIR, libdir, LIBDIR_MODE)
208
+ install_rb(BINDIR, bindir, BINDIR_MODE, bin=true)
209
+
210
+ if linked
211
+ linked.each{|path| File::rm_f path}
212
+ end
213
+
214
+ system "#{ sudo } #{ $ruby } post-install.rb" if test(?s, 'post-install.rb')
@@ -0,0 +1,87 @@
1
+ unless defined? Bj
2
+ class Bj
3
+ #
4
+ # constants and associated attrs
5
+ #
6
+ Bj::VERSION = "1.0.2" #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
+ #
35
+ # bootstrap rubygems
36
+ #
37
+ begin
38
+ require "rubygems"
39
+ rescue LoadError
40
+ 42
41
+ end
42
+ #
43
+ # rubyforge/remote
44
+ #
45
+ require "active_record"
46
+ #
47
+ # rubyforge/remote or local/lib
48
+ #
49
+ #%w[ attributes systemu orderedhash ].each do |lib|
50
+ %w[ systemu orderedhash ].each do |lib|
51
+ begin
52
+ require lib
53
+ rescue
54
+ require libdir(lib)
55
+ end
56
+ end
57
+ #
58
+ # local
59
+ #
60
+ load libdir("attributes.rb")
61
+ load libdir("stdext.rb")
62
+ load libdir("util.rb")
63
+ load libdir("errors.rb")
64
+ load libdir("logger.rb")
65
+ load libdir("bj.rb")
66
+ load libdir("joblist.rb")
67
+ load libdir("table.rb")
68
+ load libdir("runner.rb")
69
+ load libdir("api.rb")
70
+ #
71
+ # an imperfect reloading hook - because neither rails' plugins nor gems provide one, sigh...
72
+ #
73
+ def self.reload!
74
+ background = nil
75
+ ::Object.module_eval do
76
+ background = Bj.runner.background
77
+ remove_const :Bj rescue nil
78
+ remove_const :BackgroundJob rescue nil
79
+ end
80
+ returned = load __FILE__ rescue nil
81
+ Bj.runner.background = background if background
82
+ returned
83
+ end
84
+ end
85
+
86
+ BackgroundJob = Bj
87
+ end
@@ -0,0 +1,164 @@
1
+ class Bj
2
+ #
3
+ # the api exposes nearly all the bj code you'll likely need, with the
4
+ # exception of accessing the job table for searching, which is done using
5
+ #
6
+ # eg.
7
+ #
8
+ # Bj.table.job.find :all
9
+ #
10
+ module API
11
+ #
12
+ # submit jobs for background processing. 'jobs' can be a string or array of
13
+ # strings. options are applied to each job in the 'jobs', and the list of
14
+ # submitted jobs is always returned. options (string or symbol) can be
15
+ #
16
+ # :rails_env => production|development|key_in_database_yml
17
+ # when given this keyword causes bj to submit jobs to the
18
+ # specified database. default is RAILS_ENV.
19
+ #
20
+ # :priority => any number, including negative ones. default is zero.
21
+ #
22
+ # :tag => a tag added to the job. simply makes searching easier.
23
+ #
24
+ # :env => a hash specifying any additional environment vars the background
25
+ # process should have.
26
+ #
27
+ # :stdin => any stdin the background process should have.
28
+ #
29
+ # eg:
30
+ #
31
+ # jobs = Bj.submit 'echo foobar', :tag => 'simple job'
32
+ #
33
+ # jobs = Bj.submit '/bin/cat', :stdin => 'in the hat', :priority => 42
34
+ #
35
+ # jobs = Bj.submit './script/runner ./scripts/a.rb', :rails_env => 'production'
36
+ #
37
+ # jobs = Bj.submit './script/runner /dev/stdin', :stdin => 'p RAILS_ENV', :tag => 'dynamic ruby code'
38
+ #
39
+ # jobs = Bj.submit array_of_commands, :priority => 451
40
+ #
41
+ # when jobs are run, they are run in RAILS_ROOT. various attributes are
42
+ # available *only* once the job has finished. you can check whether or not
43
+ # a job is finished by using the #finished method, which simple does a
44
+ # reload and checks to see if the exit_status is non-nil.
45
+ #
46
+ # eg:
47
+ #
48
+ # jobs = Bj.submit list_of_jobs, :tag => 'important'
49
+ # ...
50
+ #
51
+ # jobs.each do |job|
52
+ # if job.finished?
53
+ # p job.exit_status
54
+ # p job.stdout
55
+ # p job.stderr
56
+ # end
57
+ # end
58
+ #
59
+ #
60
+ def submit jobs, options = {}, &block
61
+ options.to_options!
62
+ Bj.transaction(options) do
63
+ table.job.submit jobs, options, &block
64
+ end
65
+ ensure
66
+ Bj.runner.tickle unless options[:no_tickle]
67
+ end
68
+ #
69
+ # this method changes the context under which bj is operating. a context is
70
+ # a RAILS_ENV. the method accepts a block and it used to alter the
71
+ # behaviour of the bj lib on a global scale such that all operations,
72
+ # spawning of background runnner processes, etc, occur in that context.
73
+ #
74
+ # eg:
75
+ #
76
+ # Bj.in :production do
77
+ # Bj.submit './script/runner ./scripts/facebook_notification.rb'
78
+ # end
79
+ #
80
+ # Bj.in :development do
81
+ # Bj.submit 'does_this_eat_memory.exe'
82
+ # end
83
+ #
84
+ def in rails_env = Bj.rails_env, &block
85
+ transaction(:rails_env => rails_env.to_s, &block)
86
+ end
87
+ #
88
+ # list simply returns a list of all jobs in the job table
89
+ #
90
+ def list options = {}, &block
91
+ options.to_options!
92
+ Bj.transaction(options) do
93
+ options.delete :rails_env
94
+ table.job.find(:all, options)
95
+ end
96
+ end
97
+ #
98
+ #
99
+ #
100
+ def run options = {}
101
+ runner.run options
102
+ end
103
+ #
104
+ # generate a migration and migrate a database (production/development/etc)
105
+ #
106
+ def setup options = {}
107
+ options.to_options!
108
+ chroot do
109
+ generate_migration options
110
+ migrate options
111
+ end
112
+ end
113
+ #
114
+ # generate_migration, suprisingly, generates the single migration needed for
115
+ # bj. you'll notice the the migration is very short as the migration
116
+ # classes themselves are inner classes of the respective bj table class.
117
+ # see lib/bj/table.rb for details.
118
+ #
119
+ def generate_migration options = {}
120
+ options.to_options!
121
+ options[:verbose] = true
122
+ chroot do
123
+ before = Dir.glob "./db/migrate/*"
124
+ n = Dir.glob("./db/migrate/*_bj_*").size
125
+ classname = "BjMigration#{ n }"
126
+ util.spawn "#{ Bj.ruby } ./script/generate migration #{ classname }", options rescue nil
127
+ after = Dir.glob "./db/migrate/*"
128
+ candidates = after - before
129
+ case candidates.size
130
+ when 0
131
+ false
132
+ when 1
133
+ generated = candidates.first
134
+ open(generated, "w"){|fd| fd.puts Bj.table.migration_code(classname)}
135
+ Bj.logger.info{ "generated <#{ generated }>" }
136
+ generated
137
+ else
138
+ raise "ambiguous migration <#{ candidates.inspect }>"
139
+ end
140
+ end
141
+ end
142
+ #
143
+ # migrate a database (production|development|etc)
144
+ #
145
+ def migrate options = {}
146
+ options.to_options!
147
+ options[:verbose] = true
148
+ chroot do
149
+ util.spawn "#{ Bj.rake } RAILS_ENV=#{ Bj.rails_env } db:migrate", options
150
+ end
151
+ end
152
+ #
153
+ # install plugin into this rails app
154
+ #
155
+ def plugin options = {}
156
+ options.to_options!
157
+ options[:verbose] = true
158
+ chroot do
159
+ util.spawn "#{ Bj.ruby } ./script/plugin install http://codeforpeople.rubyforge.org/svn/rails/plugins/bj --force", options
160
+ end
161
+ end
162
+ end
163
+ send :extend, API
164
+ end