swiftiply 0.5.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.
Files changed (76) hide show
  1. data/README +126 -0
  2. data/bin/mongrel_rails +254 -0
  3. data/bin/swiftiply +136 -0
  4. data/bin/swiftiply_mongrel_rails +54 -0
  5. data/external/package.rb +672 -0
  6. data/external/test_support.rb +58 -0
  7. data/setup.rb +40 -0
  8. data/src/ramaze/adapter/evented_mongrel.rb +2 -0
  9. data/src/ramaze/adapter/swiftiplied_mongrel.rb +2 -0
  10. data/src/swiftcore/Swiftiply.rb +444 -0
  11. data/src/swiftcore/Swiftiply.rb.orig +390 -0
  12. data/src/swiftcore/evented_mongrel.rb +182 -0
  13. data/src/swiftcore/swiftiplied_mongrel.rb +212 -0
  14. data/swiftiply.gemspec +41 -0
  15. data/test/rails/README +182 -0
  16. data/test/rails/Rakefile +10 -0
  17. data/test/rails/app/controllers/application.rb +6 -0
  18. data/test/rails/app/controllers/tests_controller.rb +15 -0
  19. data/test/rails/app/helpers/application_helper.rb +3 -0
  20. data/test/rails/config/boot.rb +45 -0
  21. data/test/rails/config/database.yml +36 -0
  22. data/test/rails/config/environment.rb +60 -0
  23. data/test/rails/config/environments/development.rb +21 -0
  24. data/test/rails/config/environments/production.rb +18 -0
  25. data/test/rails/config/environments/production_no_caching.rb +18 -0
  26. data/test/rails/config/environments/test.rb +19 -0
  27. data/test/rails/config/routes.rb +23 -0
  28. data/test/rails/doc/README_FOR_APP +2 -0
  29. data/test/rails/observe_ram.rb +10 -0
  30. data/test/rails/public/404.html +30 -0
  31. data/test/rails/public/500.html +30 -0
  32. data/test/rails/public/dispatch.cgi +10 -0
  33. data/test/rails/public/dispatch.fcgi +24 -0
  34. data/test/rails/public/dispatch.rb +10 -0
  35. data/test/rails/public/favicon.ico +0 -0
  36. data/test/rails/public/images/rails.png +0 -0
  37. data/test/rails/public/index.html +277 -0
  38. data/test/rails/public/javascripts/application.js +2 -0
  39. data/test/rails/public/javascripts/controls.js +833 -0
  40. data/test/rails/public/javascripts/dragdrop.js +942 -0
  41. data/test/rails/public/javascripts/effects.js +1088 -0
  42. data/test/rails/public/javascripts/prototype.js +2515 -0
  43. data/test/rails/public/robots.txt +1 -0
  44. data/test/rails/script/about +3 -0
  45. data/test/rails/script/breakpointer +3 -0
  46. data/test/rails/script/console +3 -0
  47. data/test/rails/script/destroy +3 -0
  48. data/test/rails/script/generate +3 -0
  49. data/test/rails/script/performance/benchmarker +3 -0
  50. data/test/rails/script/performance/profiler +3 -0
  51. data/test/rails/script/plugin +3 -0
  52. data/test/rails/script/process/inspector +3 -0
  53. data/test/rails/script/process/reaper +3 -0
  54. data/test/rails/script/process/spawner +3 -0
  55. data/test/rails/script/runner +3 -0
  56. data/test/rails/script/server +3 -0
  57. data/test/rails/test/test_helper.rb +28 -0
  58. data/test/ramaze/conf/benchmark.yaml +35 -0
  59. data/test/ramaze/conf/debug.yaml +34 -0
  60. data/test/ramaze/conf/live.yaml +33 -0
  61. data/test/ramaze/conf/silent.yaml +31 -0
  62. data/test/ramaze/conf/stage.yaml +33 -0
  63. data/test/ramaze/main.rb +18 -0
  64. data/test/ramaze/public/404.jpg +0 -0
  65. data/test/ramaze/public/css/coderay.css +105 -0
  66. data/test/ramaze/public/css/ramaze_error.css +42 -0
  67. data/test/ramaze/public/error.zmr +77 -0
  68. data/test/ramaze/public/favicon.ico +0 -0
  69. data/test/ramaze/public/js/jquery.js +1923 -0
  70. data/test/ramaze/public/ramaze.png +0 -0
  71. data/test/ramaze/src/controller/main.rb +8 -0
  72. data/test/ramaze/src/element/page.rb +17 -0
  73. data/test/ramaze/src/model.rb +6 -0
  74. data/test/ramaze/template/index.xhtml +6 -0
  75. data/test/ramaze/yaml.db +0 -0
  76. metadata +189 -0
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ENV['SWIFT'] = 'true'
4
+ require 'optparse'
5
+
6
+ class MongrelSwiftStart
7
+
8
+ def self.parse_options(config = {})
9
+ defaults={:env => 'production',
10
+ :pid => (File.expand_path(Dir.pwd)+'/log'),
11
+ :host => '127.0.0.1',
12
+ :port => 4000,
13
+ :num => 1
14
+ }
15
+ OptionParser.new do |opts|
16
+ opts.banner = 'Usage: mongrel_swift [options]'
17
+ opts.separator ''
18
+ opts.on('-C','--config CONFFILE',"The mongrel configuration file to read.") do |conf|
19
+ config[:conf] = conf
20
+ end
21
+ opts.on('-h','--host [HOST]','The hostname/IP address that the swiftiply proxy will listen on for backend connections.') do |host|
22
+ config[:host] = host
23
+ end
24
+ opts.on('-p','--port [PORT]','The port that swiftiply proxy is listening on for backend connections. Use the same port for all mongrels!') do |port|
25
+ config[:port] = port
26
+ end
27
+ opts.on('-d','--daemonize','Whether mongrel_rails should put itself into the background.') do |yn|
28
+ config[:daemonize] = true
29
+ end
30
+ opts.on('-n','--num-mongrels [NUM]','The number of mongrels to start.') do |numm|
31
+ config[:num] = numm.to_i
32
+ end
33
+ opts.on('-P','--pidfiles [NUM]','Path to store PID files.') do |numm|
34
+ config[:num] = numm.to_i
35
+ end
36
+ end.parse!
37
+ @config = defaults.update(config)
38
+ end
39
+
40
+ def self.run
41
+ parse_options
42
+ @config[:num].times do |i|
43
+ cmd = "mongrel_rails start -p #{@config[:port]} " <<
44
+ "-e #{@config[:env]} #{@config[:daemonize] ? '-d' : ''}" <<
45
+ "-P #{File.join(@config[:pid],'dog' + i.to_s + '.pid')}" <<
46
+ "#{@config[:conf] ? ' -C '+@config[:conf] : ''}"
47
+ output = `#{cmd}`
48
+ puts output
49
+ end
50
+ end
51
+
52
+ end
53
+
54
+ MongrelSwiftStart.run
@@ -0,0 +1,672 @@
1
+ require 'rbconfig'
2
+ require 'fileutils'
3
+ require 'optparse'
4
+ require 'yaml'
5
+
6
+ class String
7
+ # This patch for win32 paths contributed by James Britt.
8
+ def w32
9
+ if self =~ /^\w:\/\w:/i
10
+ self.gsub(/^\w:\//i, '')
11
+ else
12
+ self
13
+ end
14
+ end
15
+ end
16
+
17
+ module Package
18
+
19
+ class SpecificationError < StandardError; end
20
+ class PackageSpecification_1_0; end
21
+
22
+ SEMANTICS = { "1.0" => PackageSpecification_1_0 }
23
+
24
+ KINDS = [
25
+ :bin, :lib, :ext, :data, :conf, :doc
26
+ ]
27
+
28
+ mapping = { '.' => '\.', '$' => '\$', '#' => '\#', '*' => '.*' }
29
+ ignore_files = %w[core RCSLOG tags TAGS .make.state .nse_depinfo .hg
30
+ #* .#* cvslog.* ,* .del-* *.olb *~ *.old *.bak *.BAK *.orig *.rej _$* *$
31
+ *.org *.in .* ]
32
+
33
+ IGNORE_FILES = ignore_files.map do |x|
34
+ Regexp.new('\A' + x.gsub(/[\.\$\#\*]/){|c| mapping[c]} + '\z')
35
+ end
36
+
37
+ def self.config(name)
38
+ # XXX use pathname
39
+ prefix = Regexp.quote(Config::CONFIG["prefix"])
40
+ exec_prefix = Regexp.quote(Config::CONFIG["exec_prefix"])
41
+ Config::CONFIG[name].gsub(/\A\/?(#{prefix}|#{exec_prefix})\/?/, '')
42
+ end
43
+
44
+ SITE_DIRS = {
45
+ :bin => config("bindir"),
46
+ :lib => config("sitelibdir"),
47
+ :ext => config("sitearchdir"),
48
+ :data => config("datadir"),
49
+ :conf => config("sysconfdir"),
50
+ :doc => File.join(config("datadir"), "doc"),
51
+ }
52
+
53
+ VENDOR_DIRS = {
54
+ :bin => config("bindir"),
55
+ :lib => config("rubylibdir"),
56
+ :ext => config("archdir"),
57
+ :data => config("datadir"),
58
+ :conf => config("sysconfdir"),
59
+ :doc => File.join(config("datadir"), "doc"),
60
+ }
61
+
62
+ MODES = {
63
+ :bin => 0755,
64
+ :lib => 0644,
65
+ :ext => 0755, # was: 0555,
66
+ :data => 0644,
67
+ :conf => 0644,
68
+ :doc => 0644,
69
+ }
70
+
71
+
72
+ SETUP_OPTIONS = {:parse_cmdline => true, :load_conf => true, :run_tasks => true}
73
+ RUBY_BIN = File.join(::Config::CONFIG['bindir'],::Config::CONFIG['ruby_install_name']) << ::Config::CONFIG['EXEEXT']
74
+
75
+ def self.setup(version, options = {}, &instructions)
76
+ prefixes = dirs = nil
77
+ options = SETUP_OPTIONS.dup.update(options)
78
+
79
+ if options[:load_conf] && File.exist?("config.save")
80
+ config = YAML.load_file "config.save"
81
+ prefixes = config[:prefixes]
82
+ dirs = config[:dirs]
83
+ end
84
+
85
+ pkg = package_specification_with_semantics(version).new(prefixes, dirs)
86
+ pkg.parse_command_line if options[:parse_cmdline]
87
+ pkg.instance_eval(&instructions)
88
+
89
+ pkg.run_tasks if options[:run_tasks]
90
+
91
+ # pkg.install
92
+ pkg
93
+ end
94
+
95
+ def self.package_specification_with_semantics(version)
96
+ #XXX: implement the full x.y(.z)? semantics
97
+ r = SEMANTICS[version]
98
+ raise SpecificationError, "Unknown version #{version}." unless r
99
+ r
100
+ end
101
+
102
+
103
+ module Actions
104
+
105
+ class InstallFile
106
+
107
+ attr_reader :source, :destination, :mode
108
+
109
+ def initialize(source, destination, mode, options)
110
+ @source = source
111
+ @destination = destination
112
+ @mode = mode
113
+ @options = options
114
+ end
115
+
116
+ def install
117
+ dirs = [@options.destdir.to_s, @destination].select {|x| x}
118
+ d = File.expand_path(File.join(dirs)).w32
119
+ FileUtils.install @source, d,
120
+ {:verbose => @options.verbose,
121
+ :noop => @options.noop, :mode => @mode }
122
+ end
123
+
124
+ def hash
125
+ [@source.hash, @destination.hash].hash
126
+ end
127
+
128
+ def eql?(other)
129
+ self.class == other.class &&
130
+ @source == other.source &&
131
+ @destination == other.destination &&
132
+ @mode == other.mode
133
+ end
134
+
135
+ def <=>(other)
136
+ FULL_ORDER[self, other] || self.destination <=> other.destination
137
+ end
138
+ end
139
+
140
+ class MkDir
141
+
142
+ attr_reader :directory
143
+
144
+ def initialize(directory, options)
145
+ @directory = directory
146
+ @options = options
147
+ end
148
+
149
+ def install
150
+ dirs = [@options.destdir.to_s, @directory].select {|x| x}
151
+ d = File.expand_path(File.join(dirs)).w32
152
+ FileUtils.mkdir_p d,
153
+ {:verbose => @options.verbose,
154
+ :noop => @options.noop }
155
+ end
156
+
157
+ def <=>(other)
158
+ FULL_ORDER[self, other] || self.directory <=> other.directory
159
+ end
160
+ end
161
+
162
+ class FixShebang
163
+
164
+ attr_reader :destination
165
+
166
+ def initialize(destination, options)
167
+ @options = options
168
+ @destination = destination
169
+ end
170
+
171
+ def install
172
+ dirs = [@options.destdir.to_s, @destination].select {|x| x}
173
+ d = File.expand_path(File.join(dirs)).w32
174
+ path = d
175
+ fix_shebang(path)
176
+ end
177
+
178
+ # taken from rpa-base, originally based on setup.rb's
179
+ # modify: #!/usr/bin/ruby
180
+ # modify: #! /usr/bin/ruby
181
+ # modify: #!ruby
182
+ # not modify: #!/usr/bin/env ruby
183
+ SHEBANG_RE = /\A\#!\s*\S*ruby\S*/
184
+
185
+ #TODO allow the ruby-prog to be placed in the shebang line to be passed as
186
+ # an option
187
+ def fix_shebang(path)
188
+ tmpfile = path + '.tmp'
189
+ begin
190
+ #XXX: needed at all?
191
+ # it seems that FileUtils doesn't expose its default output
192
+ # @fileutils_output = $stderr
193
+ # we might want to allow this to be redirected.
194
+ $stderr.puts "shebang:open #{tmpfile}" if @options.verbose
195
+ unless @options.noop
196
+ File.open(path) do |r|
197
+ File.open(tmpfile, 'w', 0755) do |w|
198
+ first = r.gets
199
+ return unless SHEBANG_RE =~ first
200
+ ruby = File.join(::Config::CONFIG['bindir'],::Config::CONFIG['ruby_install_name'])
201
+ ruby << ::Config::CONFIG['EXEEXT']
202
+ #w.print first.sub(SHEBANG_RE, '#!' + Config::CONFIG['ruby-prog'])
203
+ w.print first.sub(SHEBANG_RE, '#!' + ruby)
204
+ w.write r.read
205
+ end
206
+ end
207
+ end
208
+ FileUtils.mv(tmpfile, path, :verbose => @options.verbose,
209
+ :noop => @options.noop)
210
+ ensure
211
+ FileUtils.rm_f(tmpfile, :verbose => @options.verbose,
212
+ :noop => @options.noop)
213
+ end
214
+ end
215
+
216
+ def <=>(other)
217
+ FULL_ORDER[self, other] || self.destination <=> other.destination
218
+ end
219
+
220
+ def hash
221
+ @destination.hash
222
+ end
223
+
224
+ def eql?(other)
225
+ self.class == other.class && self.destination == other.destination
226
+ end
227
+ end
228
+
229
+ order = [MkDir, InstallFile, FixShebang]
230
+ FULL_ORDER = lambda do |me, other|
231
+ a, b = order.index(me.class), order.index(other.class)
232
+ if a && b
233
+ (r = a - b) == 0 ? nil : r
234
+ else
235
+ -1
236
+ end
237
+ end
238
+
239
+ class ActionList < Array
240
+
241
+ def directories!(options)
242
+ dirnames = []
243
+ map! do |d|
244
+ if d.kind_of?(InstallFile) && !dirnames.include?(File.dirname(d.destination))
245
+ dirnames << File.dirname(d.destination)
246
+ [MkDir.new(File.dirname(d.destination), options), d]
247
+ else
248
+ d
249
+ end
250
+ end
251
+ flatten!
252
+ end
253
+
254
+ def run(task)
255
+ each { |action| action.__send__ task }
256
+ end
257
+ end
258
+
259
+ end # module Actions
260
+
261
+ Options = Struct.new(:noop, :verbose, :destdir, :nodoc)
262
+
263
+ class PackageSpecification_1_0
264
+
265
+ TASKS = %w[config setup install test show]
266
+ # default options for translate(foo => bar)
267
+ TRANSLATE_DEFAULT_OPTIONS = { :inherit => true }
268
+
269
+ def self.declare_file_type(args, &handle_arg)
270
+ str_arr_p = lambda{|x| Array === x && x.all?{|y| String === y}}
271
+
272
+ # strict type checking --- we don't want this to be extended arbitrarily
273
+ unless args.size == 1 && Hash === args.first &&
274
+ args.first.all?{|f,r| [Proc, String, NilClass].include?(r.class) &&
275
+ (String === f || str_arr_p[f])} or
276
+ args.all?{|x| String === x || str_arr_p[x]}
277
+ raise SpecificationError,
278
+ "Unspecified semantics for the given arguments: #{args.inspect}"
279
+ end
280
+
281
+ if args.size == 1 && Hash === args.first
282
+ args.first.to_a.each do |file, rename_info|
283
+ if Array === file
284
+ # ignoring boring files
285
+ handle_arg.call(file, true, rename_info)
286
+ else
287
+ # we do want "boring" files given explicitly
288
+ handle_arg.call([file], false, rename_info)
289
+ end
290
+ end
291
+ else
292
+ args.each do |a|
293
+ if Array === a
294
+ a.each{|file| handle_arg.call(file, true, nil)}
295
+ else
296
+ handle_arg.call(a, false, nil)
297
+ end
298
+ end
299
+ end
300
+ end
301
+
302
+ #{{{ define the file tagging methods
303
+ KINDS.each do |kind|
304
+ define_method(kind) do |*args| # if this were 1.9 we could also take a block
305
+ bin_callback = lambda do |kind_, type, dest, options|
306
+ next if kind_ != :bin || type == :dir
307
+ @actions << Actions::FixShebang.new(dest, options)
308
+ end
309
+ #TODO: refactor
310
+ self.class.declare_file_type(args) do |files, ignore_p, opt_rename_info|
311
+ files.each do |file|
312
+ next if ignore_p && IGNORE_FILES.any?{|re| re.match(file)}
313
+ add_file(kind, file, opt_rename_info, &bin_callback)
314
+ end
315
+ end
316
+ end
317
+ end
318
+
319
+ def unit_test(*files)
320
+ if ARGV.length > 0
321
+ files.each do |x|
322
+ @unit_tests.concat([x]) if ARGV.include?(File.basename(x).sub(/\.\w+$/,''))
323
+ end
324
+ else
325
+ @unit_tests.concat files.flatten
326
+ end
327
+ end
328
+
329
+ def ri(*files)
330
+ @ri_files.concat files.flatten
331
+ end
332
+
333
+ def build_ext(path,opts = {:mkmf => true}, &blk)
334
+ @ext_targets << [path,opts,blk]
335
+ end
336
+
337
+ attr_accessor :actions, :options
338
+
339
+ def self.metadata(name)
340
+ define_method(name) do |*args|
341
+ if args.size == 1
342
+ @metadata[name] = args.first
343
+ end
344
+ @metadata[name]
345
+ end
346
+ end
347
+
348
+ metadata :name
349
+ metadata :version
350
+ metadata :author
351
+
352
+ def translate_dir(kind, dir)
353
+ replaced_dir_parts = dir.split(%r{/})
354
+ kept_dir_parts = []
355
+ loop do
356
+ replaced_path = replaced_dir_parts.join("/")
357
+ target, options = @translate[kind][replaced_path]
358
+ options ||= TRANSLATE_DEFAULT_OPTIONS
359
+ if target && (replaced_path == dir || options[:inherit])
360
+ dir = (target != '' ? File.join(target, *kept_dir_parts) :
361
+ File.join(*kept_dir_parts))
362
+ break
363
+ end
364
+ break if replaced_dir_parts.empty?
365
+ kept_dir_parts.unshift replaced_dir_parts.pop
366
+ end
367
+ dir
368
+ end
369
+
370
+ def add_file(kind, filename, new_filename_info, &callback)
371
+ #TODO: refactor!!!
372
+ if File.directory? filename #XXX setup.rb and rpa-base defined File.dir?
373
+ dir = filename.sub(/\A\.\//, "").sub(/\/\z/, "")
374
+ dest = File.join(@prefixes[kind], @dirs[kind], translate_dir(kind, dir))
375
+ @actions << Actions::MkDir.new(dest, @options)
376
+ callback.call(kind, :dir, dest, @options) if block_given?
377
+ else
378
+ if new_filename_info
379
+ case new_filename_info
380
+ when Proc
381
+ dest_name = new_filename_info.call(filename.dup)
382
+ else
383
+ dest_name = new_filename_info.dup
384
+ end
385
+ else
386
+ dest_name = filename.dup
387
+ end
388
+
389
+ dirname = File.dirname(dest_name)
390
+ dirname = "" if dirname == "."
391
+ dest_name = File.join(translate_dir(kind, dirname), File.basename(dest_name))
392
+
393
+ dest = File.join(@prefixes[kind], @dirs[kind], dest_name)
394
+ @actions << Actions::InstallFile.new(filename, dest, MODES[kind], @options)
395
+ callback.call(kind, :file, dest, @options) if block_given?
396
+ end
397
+ end
398
+
399
+ def initialize(prefixes = nil, dirs = nil)
400
+ @prefix = Config::CONFIG["prefix"].gsub(/\A\//, '')
401
+ @translate = {}
402
+ @prefixes = (prefixes || {}).dup
403
+ KINDS.each do |kind|
404
+ @prefixes[kind] = @prefix unless prefixes
405
+ @translate[kind] = {}
406
+ end
407
+
408
+ @dirs = (dirs || {}).dup
409
+ @dirs.update SITE_DIRS unless dirs
410
+
411
+ @actions = Actions::ActionList.new
412
+
413
+ @metadata = {}
414
+ @unit_tests = []
415
+ @ri_files = []
416
+ @ext_targets = []
417
+
418
+ @options = Options.new
419
+ @options.verbose = true
420
+ @options.noop = false # XXX for testing
421
+ @options.destdir = ''
422
+
423
+ @tasks = []
424
+ end
425
+
426
+ def aoki
427
+ (KINDS - [:ext]).each do |kind|
428
+ translate(kind, kind.to_s => "", :inherit => true)
429
+ __send__ kind, Dir["#{kind}/**/*"]
430
+ end
431
+ translate(:ext, "ext/*" => "", :inherit => true)
432
+ ext Dir["ext/**/*.#{Config::CONFIG['DLEXT']}"]
433
+ end
434
+
435
+ # Builds any needed extensions.
436
+
437
+ def setup
438
+ @ext_targets.each do |et|
439
+ path, options, block = et
440
+ path = expand_ext_path(path)
441
+ case
442
+ when options[:mkmf]
443
+ setup_mkmf(path, options, block)
444
+ end
445
+ end
446
+ end
447
+
448
+ def expand_ext_path(path)
449
+ if path =~ /#{File::SEPARATOR}/
450
+ extpath = File.expand_path(path)
451
+ else
452
+ extpath = File.expand_path(File.join('ext',path,'extconf.rb'))
453
+ end
454
+ unless extpath =~ /\.rb$/
455
+ extpath = File.join(extpath,'extconf.rb')
456
+ end
457
+ extpath
458
+ end
459
+
460
+ def setup_mkmf(execpath, options, block)
461
+ $stderr.puts "Building extension in #{File.dirname(execpath)} with #{options.inspect}."
462
+ cwd = Dir.pwd
463
+ begin
464
+ if block
465
+ block.call(options)
466
+ else
467
+ Dir.chdir(File.dirname(execpath))
468
+ system('make','clean') if FileTest.exist? "Makefile"
469
+ system(RUBY_BIN,execpath)
470
+ system('make')
471
+ end
472
+ ensure
473
+ Dir.chdir(cwd)
474
+ end
475
+ end
476
+
477
+ def install
478
+ $stderr.puts "Installing #{name || "unknown package"} #{version}..." if options.verbose
479
+
480
+ actions.uniq!
481
+ actions.sort!
482
+ actions.directories!(options)
483
+
484
+ actions.run :install
485
+
486
+ unless @ri_files.empty? or @options.nodoc
487
+ $stderr.puts "Generating ri documentation from #{@ri_files.join(',')}"
488
+ require 'rdoc/rdoc'
489
+ unless options.noop
490
+ begin
491
+ RDoc::RDoc.new.document(["--ri-site"].concat(@ri_files.flatten))
492
+ rescue Exception => e
493
+ $stderr.write("Installation of ri documentation failed: #{e.to_s} #{e.backtrace.join("\n")}")
494
+ end
495
+ end
496
+ end
497
+ end
498
+
499
+ def test
500
+ unless @unit_tests.empty?
501
+ puts "Testing #{name || "unknown package"} #{version}..." if options.verbose
502
+ require 'test/unit'
503
+ unless options.noop
504
+ t = Test::Unit::AutoRunner.new(true)
505
+ t.process_args(@unit_tests)
506
+ t.run
507
+ end
508
+ end
509
+ end
510
+
511
+ def config
512
+ File.open("config.save", "w") do |f|
513
+ YAML.dump({:prefixes => @prefixes, :dirs => @dirs}, f)
514
+ end
515
+ end
516
+
517
+ def show
518
+ KINDS.each do |kind|
519
+ puts "#{kind}\t#{File.join(options.destdir, @prefixes[kind], @dirs[kind])}"
520
+ end
521
+ end
522
+
523
+ def translate(kind, additional_translations)
524
+ default_opts = TRANSLATE_DEFAULT_OPTIONS.dup
525
+ key_val_pairs = additional_translations.to_a
526
+ option_pairs = key_val_pairs.select{|(k,v)| Symbol === k}
527
+ default_opts.update(Hash[*option_pairs.flatten])
528
+
529
+ (key_val_pairs - option_pairs).each do |key, val|
530
+ add_translation(kind, key, val, default_opts)
531
+ end
532
+ end
533
+
534
+ def add_translation(kind, src, dest, options)
535
+ if is_glob?(src)
536
+ dirs = expand_dir_glob(src)
537
+ else
538
+ dirs = [src]
539
+ end
540
+ dirs.each do |dirname|
541
+ dirname = dirname.sub(%r{\A\./}, "").sub(%r{/\z}, "")
542
+ @translate[kind].update({dirname => [dest, options]})
543
+ end
544
+ end
545
+
546
+ def is_glob?(x)
547
+ /(^|[^\\])[*?{\[]/.match(x)
548
+ end
549
+
550
+ def expand_dir_glob(src)
551
+ Dir[src].select{|x| File.directory?(x)}
552
+ end
553
+
554
+ def clean_path(path)
555
+ path.gsub(/\A\//, '').gsub(/\/+\Z/, '').squeeze("/")
556
+ end
557
+
558
+ def parse_command_line
559
+ opts = OptionParser.new(nil, 24, ' ') do |opts|
560
+ opts.banner = "Usage: setup.rb [options] [task]"
561
+
562
+ opts.separator ""
563
+ opts.separator "Tasks:"
564
+ opts.separator " config configures paths"
565
+ opts.separator " show shows paths"
566
+ opts.separator " setup compiles ruby extentions and others XXX"
567
+ opts.separator " install installs files"
568
+ opts.separator " test runs unit tests"
569
+
570
+
571
+ opts.separator ""
572
+ opts.separator "Specific options:"
573
+
574
+ opts.on "--prefix=PREFIX",
575
+ "path prefix of target environment [#@prefix]" do |prefix|
576
+ @prefix.replace clean_path(prefix) # Shared!
577
+ end
578
+
579
+ opts.separator ""
580
+
581
+ KINDS.each do |kind|
582
+ opts.on "--#{kind}prefix=PREFIX",
583
+ "path prefix for #{kind} files [#{@prefixes[kind]}]" do |prefix|
584
+ @prefixes[kind] = clean_path(prefix)
585
+ end
586
+ end
587
+
588
+ opts.separator ""
589
+
590
+ KINDS.each do |kind|
591
+ opts.on "--#{kind}dir=PREFIX",
592
+ "directory for #{kind} files [#{@dirs[kind]}]" do |prefix|
593
+ @dirs[kind] = clean_path(prefix)
594
+ end
595
+ end
596
+
597
+ opts.separator ""
598
+
599
+ KINDS.each do |kind|
600
+ opts.on "--#{kind}=PREFIX",
601
+ "absolute directory for #{kind} files [#{File.join(@prefixes[kind], @dirs[kind])}]" do |prefix|
602
+ @prefixes[kind] = clean_path(prefix)
603
+ end
604
+ end
605
+
606
+ opts.separator ""
607
+ opts.separator "Predefined path configurations:"
608
+ opts.on "--site", "install into site-local directories (default)" do
609
+ @dirs.update SITE_DIRS
610
+ end
611
+
612
+ opts.on "--vendor", "install into distribution directories (for packagers)" do
613
+ @dirs.update VENDOR_DIRS
614
+ end
615
+
616
+ opts.separator ""
617
+ opts.separator "General options:"
618
+
619
+ opts.on "--destdir=DESTDIR",
620
+ "install all files relative to DESTDIR (/)" do |destdir|
621
+ @options.destdir = destdir
622
+ end
623
+
624
+ opts.on "--dry-run", "only display what to do if given [#{@options.noop}]" do
625
+ @options.noop = true
626
+ end
627
+
628
+ opts.on "--no-harm", "only display what to do if given" do
629
+ @options.noop = true
630
+ end
631
+
632
+ opts.on "--no-doc","don't generate documentation" do
633
+ @options.nodoc = true
634
+ end
635
+
636
+ opts.on "--[no-]verbose", "output messages verbosely [#{@options.verbose}]" do |verbose|
637
+ @options.verbose = verbose
638
+ end
639
+
640
+ opts.on_tail("-h", "--help", "Show this message") do
641
+ puts opts
642
+ exit
643
+ end
644
+ end
645
+
646
+ opts.parse! ARGV
647
+
648
+ #if (ARGV - TASKS).empty? # Only existing tasks?
649
+ @tasks = ARGV.dup.select do |t|
650
+ if TASKS.include?(t)
651
+ ARGV.delete(t)
652
+ true
653
+ end
654
+ end
655
+
656
+ @tasks = ["setup","install"] if @tasks.empty?
657
+ #else
658
+ # abort "Unknown task(s) #{(ARGV-TASKS).join ", "}."
659
+ #end
660
+ end
661
+
662
+ def run_tasks
663
+ @tasks.each { |task| __send__ task }
664
+ end
665
+ end
666
+
667
+ end # module Package
668
+
669
+ require 'rbconfig'
670
+ def config(x)
671
+ Config::CONFIG[x]
672
+ end