ruby-oci8 2.1.5.1-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +17 -0
  3. data/COPYING +30 -0
  4. data/COPYING_old +64 -0
  5. data/ChangeLog +2779 -0
  6. data/Makefile +92 -0
  7. data/NEWS +660 -0
  8. data/README.md +43 -0
  9. data/VERSION +1 -0
  10. data/dist-files +91 -0
  11. data/docs/install-binary-package.md +40 -0
  12. data/docs/install-full-client.md +116 -0
  13. data/docs/install-instant-client.md +167 -0
  14. data/docs/platform-specific-issues.md +197 -0
  15. data/docs/report-installation-issue.md +50 -0
  16. data/lib/.document +1 -0
  17. data/lib/dbd/OCI8.rb +591 -0
  18. data/lib/oci8.rb +147 -0
  19. data/lib/oci8.rb.in +147 -0
  20. data/lib/oci8/.document +8 -0
  21. data/lib/oci8/bindtype.rb +350 -0
  22. data/lib/oci8/compat.rb +113 -0
  23. data/lib/oci8/connection_pool.rb +108 -0
  24. data/lib/oci8/cursor.rb +564 -0
  25. data/lib/oci8/datetime.rb +605 -0
  26. data/lib/oci8/encoding-init.rb +79 -0
  27. data/lib/oci8/encoding.yml +537 -0
  28. data/lib/oci8/metadata.rb +2092 -0
  29. data/lib/oci8/object.rb +605 -0
  30. data/lib/oci8/oci8.rb +560 -0
  31. data/lib/oci8/ocihandle.rb +607 -0
  32. data/lib/oci8/oracle_version.rb +143 -0
  33. data/lib/oci8/properties.rb +134 -0
  34. data/lib/oci8lib_200.so +0 -0
  35. data/metaconfig +142 -0
  36. data/pre-distclean.rb +7 -0
  37. data/ruby-oci8.gemspec +80 -0
  38. data/setup.rb +1333 -0
  39. data/test/README +42 -0
  40. data/test/config.rb +184 -0
  41. data/test/setup_test_object.sql +171 -0
  42. data/test/test_all.rb +54 -0
  43. data/test/test_appinfo.rb +63 -0
  44. data/test/test_array_dml.rb +333 -0
  45. data/test/test_bind_raw.rb +46 -0
  46. data/test/test_bind_string.rb +106 -0
  47. data/test/test_bind_time.rb +178 -0
  48. data/test/test_break.rb +124 -0
  49. data/test/test_clob.rb +98 -0
  50. data/test/test_connection_pool.rb +125 -0
  51. data/test/test_connstr.rb +81 -0
  52. data/test/test_datetime.rb +581 -0
  53. data/test/test_dbi.rb +366 -0
  54. data/test/test_dbi_clob.rb +53 -0
  55. data/test/test_encoding.rb +104 -0
  56. data/test/test_error.rb +88 -0
  57. data/test/test_metadata.rb +1485 -0
  58. data/test/test_object.rb +462 -0
  59. data/test/test_oci8.rb +489 -0
  60. data/test/test_oracle_version.rb +70 -0
  61. data/test/test_oradate.rb +256 -0
  62. data/test/test_oranumber.rb +787 -0
  63. data/test/test_rowid.rb +33 -0
  64. metadata +109 -0
data/setup.rb ADDED
@@ -0,0 +1,1333 @@
1
+ #
2
+ # setup.rb
3
+ #
4
+ # Copyright (c) 2000-2004 Minero Aoki
5
+ #
6
+ # This program is free software.
7
+ # You can distribute/modify this program under the terms of
8
+ # the GNU Lesser General Public License version 2.1.
9
+ #
10
+
11
+ #
12
+ # For backward compatibility
13
+ #
14
+
15
+ unless Enumerable.method_defined?(:map)
16
+ module Enumerable
17
+ alias map collect
18
+ end
19
+ end
20
+
21
+ unless Enumerable.method_defined?(:detect)
22
+ module Enumerable
23
+ alias detect find
24
+ end
25
+ end
26
+
27
+ unless Enumerable.method_defined?(:select)
28
+ module Enumerable
29
+ alias select find_all
30
+ end
31
+ end
32
+
33
+ unless Enumerable.method_defined?(:reject)
34
+ module Enumerable
35
+ def reject
36
+ result = []
37
+ each do |i|
38
+ result.push i unless yield(i)
39
+ end
40
+ result
41
+ end
42
+ end
43
+ end
44
+
45
+ unless Enumerable.method_defined?(:inject)
46
+ module Enumerable
47
+ def inject(result)
48
+ each do |i|
49
+ result = yield(result, i)
50
+ end
51
+ result
52
+ end
53
+ end
54
+ end
55
+
56
+ unless Enumerable.method_defined?(:any?)
57
+ module Enumerable
58
+ def any?
59
+ each do |i|
60
+ return true if yield(i)
61
+ end
62
+ false
63
+ end
64
+ end
65
+ end
66
+
67
+ unless File.respond_to?(:read)
68
+ def File.read(fname)
69
+ open(fname) {|f|
70
+ return f.read
71
+ }
72
+ end
73
+ end
74
+
75
+ #
76
+ # Application independent utilities
77
+ #
78
+
79
+ def File.binread(fname)
80
+ open(fname, 'rb') {|f|
81
+ return f.read
82
+ }
83
+ end
84
+
85
+ # for corrupted windows stat(2)
86
+ def File.dir?(path)
87
+ File.directory?((path[-1,1] == '/') ? path : path + '/')
88
+ end
89
+
90
+ #
91
+ # Config
92
+ #
93
+
94
+ if arg = ARGV.detect{|a| /\A--rbconfig=/ =~ a }
95
+ ARGV.delete(arg)
96
+ require arg.split(/=/, 2)[1]
97
+ $".push 'rbconfig.rb'
98
+ else
99
+ require 'rbconfig'
100
+ end
101
+
102
+ RbConfig = Config unless defined? RbConfig
103
+
104
+ def multipackage_install?
105
+ FileTest.directory?(File.dirname($0) + '/packages')
106
+ end
107
+
108
+
109
+ class ConfigTable
110
+
111
+ c = ::RbConfig::CONFIG
112
+
113
+ rubypath = c['bindir'] + '/' + c['ruby_install_name']
114
+
115
+ major = c['MAJOR'].to_i
116
+ minor = c['MINOR'].to_i
117
+ teeny = c['TEENY'].to_i
118
+ version = "#{major}.#{minor}"
119
+
120
+ # ruby ver. >= 1.4.4?
121
+ newpath_p = ((major >= 2) or
122
+ ((major == 1) and
123
+ ((minor >= 5) or
124
+ ((minor == 4) and (teeny >= 4)))))
125
+
126
+ subprefix = lambda {|path|
127
+ path.sub(/\A#{Regexp.quote(c['prefix'])}/o, '$prefix')
128
+ }
129
+
130
+ if c['rubylibdir']
131
+ # V < 1.6.3
132
+ stdruby = subprefix.call(c['rubylibdir'])
133
+ siteruby = subprefix.call(c['sitedir'])
134
+ versite = subprefix.call(c['sitelibdir'])
135
+ sodir = subprefix.call(c['sitearchdir'])
136
+ elsif newpath_p
137
+ # 1.4.4 <= V <= 1.6.3
138
+ stdruby = "$prefix/lib/ruby/#{version}"
139
+ siteruby = subprefix.call(c['sitedir'])
140
+ versite = siteruby + '/' + version
141
+ sodir = "$site-ruby/#{c['arch']}"
142
+ else
143
+ # V < 1.4.4
144
+ stdruby = "$prefix/lib/ruby/#{version}"
145
+ siteruby = "$prefix/lib/ruby/#{version}/site_ruby"
146
+ versite = siteruby
147
+ sodir = "$site-ruby/#{c['arch']}"
148
+ end
149
+
150
+ if arg = c['configure_args'].split.detect {|a| /--with-make-prog=/ =~ a }
151
+ makeprog = arg.sub(/'/, '').split(/=/, 2)[1]
152
+ else
153
+ makeprog = 'make'
154
+ end
155
+
156
+ common_descripters = [
157
+ [ 'prefix', [ c['prefix'],
158
+ 'path',
159
+ 'path prefix of target environment' ] ],
160
+ [ 'std-ruby', [ stdruby,
161
+ 'path',
162
+ 'the directory for standard ruby libraries' ] ],
163
+ [ 'site-ruby-common', [ siteruby,
164
+ 'path',
165
+ 'the directory for version-independent non-standard ruby libraries' ] ],
166
+ [ 'site-ruby', [ versite,
167
+ 'path',
168
+ 'the directory for non-standard ruby libraries' ] ],
169
+ [ 'bin-dir', [ '$prefix/bin',
170
+ 'path',
171
+ 'the directory for commands' ] ],
172
+ [ 'rb-dir', [ '$site-ruby',
173
+ 'path',
174
+ 'the directory for ruby scripts' ] ],
175
+ [ 'so-dir', [ sodir,
176
+ 'path',
177
+ 'the directory for ruby extentions' ] ],
178
+ [ 'data-dir', [ '$prefix/share',
179
+ 'path',
180
+ 'the directory for shared data' ] ],
181
+ [ 'ruby-path', [ rubypath,
182
+ 'path',
183
+ 'path to set to #! line' ] ],
184
+ [ 'ruby-prog', [ rubypath,
185
+ 'name',
186
+ 'the ruby program using for installation' ] ],
187
+ [ 'make-prog', [ makeprog,
188
+ 'name',
189
+ 'the make program to compile ruby extentions' ] ],
190
+ [ 'without-ext', [ 'no',
191
+ 'yes/no',
192
+ 'does not compile/install ruby extentions' ] ]
193
+ ]
194
+ multipackage_descripters = [
195
+ [ 'with', [ '',
196
+ 'name,name...',
197
+ 'package names that you want to install',
198
+ 'ALL' ] ],
199
+ [ 'without', [ '',
200
+ 'name,name...',
201
+ 'package names that you do not want to install',
202
+ 'NONE' ] ]
203
+ ]
204
+ if multipackage_install?
205
+ DESCRIPTER = common_descripters + multipackage_descripters
206
+ else
207
+ DESCRIPTER = common_descripters
208
+ end
209
+
210
+ SAVE_FILE = 'config.save'
211
+
212
+ def ConfigTable.each_name(&block)
213
+ keys().each(&block)
214
+ end
215
+
216
+ def ConfigTable.keys
217
+ DESCRIPTER.map {|name, *dummy| name }
218
+ end
219
+
220
+ def ConfigTable.each_definition(&block)
221
+ DESCRIPTER.each(&block)
222
+ end
223
+
224
+ def ConfigTable.get_entry(name)
225
+ name, ent = DESCRIPTER.assoc(name)
226
+ ent
227
+ end
228
+
229
+ def ConfigTable.get_entry!(name)
230
+ get_entry(name) or raise ArgumentError, "no such config: #{name}"
231
+ end
232
+
233
+ def ConfigTable.add_entry(name, vals)
234
+ ConfigTable::DESCRIPTER.push [name,vals]
235
+ end
236
+
237
+ def ConfigTable.remove_entry(name)
238
+ get_entry(name) or raise ArgumentError, "no such config: #{name}"
239
+ DESCRIPTER.delete_if {|n, arr| n == name }
240
+ end
241
+
242
+ def ConfigTable.config_key?(name)
243
+ get_entry(name) ? true : false
244
+ end
245
+
246
+ def ConfigTable.bool_config?(name)
247
+ ent = get_entry(name) or return false
248
+ ent[1] == 'yes/no'
249
+ end
250
+
251
+ def ConfigTable.value_config?(name)
252
+ ent = get_entry(name) or return false
253
+ ent[1] != 'yes/no'
254
+ end
255
+
256
+ def ConfigTable.path_config?(name)
257
+ ent = get_entry(name) or return false
258
+ ent[1] == 'path'
259
+ end
260
+
261
+
262
+ class << self
263
+ alias newobj new
264
+ end
265
+
266
+ def ConfigTable.new
267
+ c = newobj()
268
+ c.initialize_from_table
269
+ c
270
+ end
271
+
272
+ def ConfigTable.load
273
+ c = newobj()
274
+ c.initialize_from_file
275
+ c
276
+ end
277
+
278
+ def initialize_from_table
279
+ @table = {}
280
+ DESCRIPTER.each do |k, (default, vname, desc, default2)|
281
+ @table[k] = default
282
+ end
283
+ end
284
+
285
+ def initialize_from_file
286
+ raise InstallError, "#{File.basename $0} config first"\
287
+ unless File.file?(SAVE_FILE)
288
+ @table = {}
289
+ File.foreach(SAVE_FILE) do |line|
290
+ k, v = line.split(/=/, 2)
291
+ @table[k] = v.strip
292
+ end
293
+ end
294
+
295
+ def save
296
+ File.open(SAVE_FILE, 'w') {|f|
297
+ @table.each do |k, v|
298
+ f.printf "%s=%s\n", k, v if v
299
+ end
300
+ }
301
+ end
302
+
303
+ def []=(k, v)
304
+ raise InstallError, "unknown config option #{k}"\
305
+ unless ConfigTable.config_key?(k)
306
+ @table[k] = v
307
+ end
308
+
309
+ def [](key)
310
+ return nil unless @table[key]
311
+ @table[key].gsub(%r<\$([^/]+)>) { self[$1] }
312
+ end
313
+
314
+ def set_raw(key, val)
315
+ @table[key] = val
316
+ end
317
+
318
+ def get_raw(key)
319
+ @table[key]
320
+ end
321
+
322
+ end
323
+
324
+
325
+ module MetaConfigAPI
326
+
327
+ def eval_file_ifexist(fname)
328
+ instance_eval File.read(fname), fname, 1 if File.file?(fname)
329
+ end
330
+
331
+ def config_names
332
+ ConfigTable.keys
333
+ end
334
+
335
+ def config?(name)
336
+ ConfigTable.config_key?(name)
337
+ end
338
+
339
+ def bool_config?(name)
340
+ ConfigTable.bool_config?(name)
341
+ end
342
+
343
+ def value_config?(name)
344
+ ConfigTable.value_config?(name)
345
+ end
346
+
347
+ def path_config?(name)
348
+ ConfigTable.path_config?(name)
349
+ end
350
+
351
+ def add_config(name, argname, default, desc)
352
+ ConfigTable.add_entry name,[default,argname,desc]
353
+ end
354
+
355
+ def add_path_config(name, default, desc)
356
+ add_config name, 'path', default, desc
357
+ end
358
+
359
+ def add_bool_config(name, default, desc)
360
+ add_config name, 'yes/no', default ? 'yes' : 'no', desc
361
+ end
362
+
363
+ def set_config_default(name, default)
364
+ if bool_config?(name)
365
+ ConfigTable.get_entry!(name)[0] = (default ? 'yes' : 'no')
366
+ else
367
+ ConfigTable.get_entry!(name)[0] = default
368
+ end
369
+ end
370
+
371
+ def remove_config(name)
372
+ ent = ConfigTable.get_entry(name)
373
+ ConfigTable.remove_entry name
374
+ ent
375
+ end
376
+
377
+ end
378
+
379
+ #
380
+ # File Operations
381
+ #
382
+
383
+ module FileOperations
384
+
385
+ def mkdir_p(dirname, prefix = nil)
386
+ dirname = prefix + dirname if prefix
387
+ $stderr.puts "mkdir -p #{dirname}" if verbose?
388
+ return if no_harm?
389
+
390
+ # does not check '/'... it's too abnormal case
391
+ dirs = dirname.split(%r<(?=/)>)
392
+ if /\A[a-z]:\z/i =~ dirs[0]
393
+ disk = dirs.shift
394
+ dirs[0] = disk + dirs[0]
395
+ end
396
+ dirs.each_index do |idx|
397
+ path = dirs[0..idx].join('')
398
+ Dir.mkdir path unless File.dir?(path)
399
+ end
400
+ end
401
+
402
+ def rm_f(fname)
403
+ $stderr.puts "rm -f #{fname}" if verbose?
404
+ return if no_harm?
405
+
406
+ if File.exist?(fname) or File.symlink?(fname)
407
+ File.chmod 0777, fname
408
+ File.unlink fname
409
+ end
410
+ end
411
+
412
+ def rm_rf(dn)
413
+ $stderr.puts "rm -rf #{dn}" if verbose?
414
+ return if no_harm?
415
+
416
+ Dir.chdir dn
417
+ Dir.foreach('.') do |fn|
418
+ next if fn == '.'
419
+ next if fn == '..'
420
+ if File.dir?(fn)
421
+ verbose_off {
422
+ rm_rf fn
423
+ }
424
+ else
425
+ verbose_off {
426
+ rm_f fn
427
+ }
428
+ end
429
+ end
430
+ Dir.chdir '..'
431
+ Dir.rmdir dn
432
+ end
433
+
434
+ def move_file(src, dest)
435
+ File.unlink dest if File.exist?(dest)
436
+ begin
437
+ File.rename src, dest
438
+ rescue
439
+ File.open(dest, 'wb') {|f| f.write File.binread(src) }
440
+ File.chmod File.stat(src).mode, dest
441
+ File.unlink src
442
+ end
443
+ end
444
+
445
+ def install(from, dest, mode, prefix = nil)
446
+ $stderr.puts "install #{from} #{dest}" if verbose?
447
+ return if no_harm?
448
+
449
+ realdest = prefix + dest if prefix
450
+ realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest)
451
+ str = File.binread(from)
452
+ if diff?(str, realdest)
453
+ verbose_off {
454
+ rm_f realdest if File.exist?(realdest)
455
+ }
456
+ File.open(realdest, 'wb') {|f|
457
+ f.write str
458
+ }
459
+ File.chmod mode, realdest
460
+
461
+ File.open("#{objdir_root()}/InstalledFiles", 'a') {|f|
462
+ if prefix
463
+ f.puts realdest.sub(prefix, '')
464
+ else
465
+ f.puts realdest
466
+ end
467
+ }
468
+ end
469
+ end
470
+
471
+ def diff?(new_content, path)
472
+ return true unless File.exist?(path)
473
+ new_content != File.binread(path)
474
+ end
475
+
476
+ def command(str)
477
+ $stderr.puts str if verbose?
478
+ system str or raise RuntimeError, "'system #{str}' failed"
479
+ end
480
+
481
+ def ruby(str)
482
+ command config('ruby-prog') + ' ' + str
483
+ end
484
+
485
+ def make(task = '')
486
+ command config('make-prog') + ' ' + task
487
+ end
488
+
489
+ def extdir?(dir)
490
+ File.exist?(dir + '/MANIFEST')
491
+ end
492
+
493
+ def all_files_in(dirname)
494
+ Dir.open(dirname) {|d|
495
+ return d.select {|ent| File.file?("#{dirname}/#{ent}") }
496
+ }
497
+ end
498
+
499
+ REJECT_DIRS = %w(
500
+ CVS SCCS RCS CVS.adm .svn .git
501
+ )
502
+
503
+ def all_dirs_in(dirname)
504
+ Dir.open(dirname) {|d|
505
+ return d.select {|n| File.dir?("#{dirname}/#{n}") } - %w(. ..) - REJECT_DIRS
506
+ }
507
+ end
508
+
509
+ end
510
+
511
+ #
512
+ # Main Installer
513
+ #
514
+
515
+ class InstallError < StandardError; end
516
+
517
+
518
+ module HookUtils
519
+
520
+ def run_hook(name)
521
+ try_run_hook "#{curr_srcdir()}/#{name}" or
522
+ try_run_hook "#{curr_srcdir()}/#{name}.rb"
523
+ end
524
+
525
+ def try_run_hook(fname)
526
+ return false unless File.file?(fname)
527
+ begin
528
+ instance_eval File.read(fname), fname, 1
529
+ rescue
530
+ raise InstallError, "hook #{fname} failed:\n" + $!.message
531
+ end
532
+ true
533
+ end
534
+
535
+ end
536
+
537
+
538
+ module HookScriptAPI
539
+
540
+ def get_config(key)
541
+ @config[key]
542
+ end
543
+
544
+ alias config get_config
545
+
546
+ def set_config(key, val)
547
+ @config[key] = val
548
+ end
549
+
550
+ #
551
+ # srcdir/objdir (works only in the package directory)
552
+ #
553
+
554
+ #abstract srcdir_root
555
+ #abstract objdir_root
556
+ #abstract relpath
557
+
558
+ def curr_srcdir
559
+ "#{srcdir_root()}/#{relpath()}"
560
+ end
561
+
562
+ def curr_objdir
563
+ "#{objdir_root()}/#{relpath()}"
564
+ end
565
+
566
+ def srcfile(path)
567
+ "#{curr_srcdir()}/#{path}"
568
+ end
569
+
570
+ def srcexist?(path)
571
+ File.exist?(srcfile(path))
572
+ end
573
+
574
+ def srcdirectory?(path)
575
+ File.dir?(srcfile(path))
576
+ end
577
+
578
+ def srcfile?(path)
579
+ File.file? srcfile(path)
580
+ end
581
+
582
+ def srcentries(path = '.')
583
+ Dir.open("#{curr_srcdir()}/#{path}") {|d|
584
+ return d.to_a - %w(. ..)
585
+ }
586
+ end
587
+
588
+ def srcfiles(path = '.')
589
+ srcentries(path).select {|fname|
590
+ File.file?(File.join(curr_srcdir(), path, fname))
591
+ }
592
+ end
593
+
594
+ def srcdirectories(path = '.')
595
+ srcentries(path).select {|fname|
596
+ File.dir?(File.join(curr_srcdir(), path, fname))
597
+ }
598
+ end
599
+
600
+ end
601
+
602
+
603
+ class ToplevelInstaller
604
+
605
+ Version = '3.2.4'
606
+ Copyright = 'Copyright (c) 2000-2004 Minero Aoki'
607
+
608
+ TASKS = [
609
+ [ 'config', 'saves your configurations' ],
610
+ [ 'show', 'shows current configuration' ],
611
+ [ 'setup', 'compiles ruby extentions and others' ],
612
+ [ 'install', 'installs files' ],
613
+ [ 'clean', "does `make clean' for each extention" ],
614
+ [ 'distclean',"does `make distclean' for each extention" ]
615
+ ]
616
+
617
+ def ToplevelInstaller.invoke
618
+ instance().invoke
619
+ end
620
+
621
+ @singleton = nil
622
+
623
+ def ToplevelInstaller.instance
624
+ @singleton ||= new(File.dirname($0))
625
+ @singleton
626
+ end
627
+
628
+ include MetaConfigAPI
629
+
630
+ def initialize(ardir_root)
631
+ @config = nil
632
+ @options = { 'verbose' => true }
633
+ @ardir = File.expand_path(ardir_root)
634
+ end
635
+
636
+ def inspect
637
+ "#<#{self.class} #{__id__()}>"
638
+ end
639
+
640
+ def invoke
641
+ run_metaconfigs
642
+ task = parsearg_global()
643
+ @config = load_config(task)
644
+ __send__ "parsearg_#{task}"
645
+ init_installers
646
+ __send__ "exec_#{task}"
647
+ end
648
+
649
+ def run_metaconfigs
650
+ eval_file_ifexist "#{@ardir}/metaconfig"
651
+ end
652
+
653
+ def load_config(task)
654
+ case task
655
+ when 'config'
656
+ ConfigTable.new
657
+ when 'clean', 'distclean'
658
+ if File.exist?('config.save')
659
+ then ConfigTable.load
660
+ else ConfigTable.new
661
+ end
662
+ else
663
+ ConfigTable.load
664
+ end
665
+ end
666
+
667
+ def init_installers
668
+ @installer = Installer.new(@config, @options, @ardir, File.expand_path('.'))
669
+ end
670
+
671
+ #
672
+ # Hook Script API bases
673
+ #
674
+
675
+ def srcdir_root
676
+ @ardir
677
+ end
678
+
679
+ def objdir_root
680
+ '.'
681
+ end
682
+
683
+ def relpath
684
+ '.'
685
+ end
686
+
687
+ #
688
+ # Option Parsing
689
+ #
690
+
691
+ def parsearg_global
692
+ valid_task = /\A(?:#{TASKS.map {|task,desc| task }.join '|'})\z/
693
+
694
+ while arg = ARGV.shift
695
+ case arg
696
+ when /\A\w+\z/
697
+ raise InstallError, "invalid task: #{arg}" unless valid_task =~ arg
698
+ return arg
699
+
700
+ when '-q', '--quiet'
701
+ @options['verbose'] = false
702
+
703
+ when '--verbose'
704
+ @options['verbose'] = true
705
+
706
+ when '-h', '--help'
707
+ print_usage $stdout
708
+ exit 0
709
+
710
+ when '-v', '--version'
711
+ puts "#{File.basename($0)} version #{Version}"
712
+ exit 0
713
+
714
+ when '--copyright'
715
+ puts Copyright
716
+ exit 0
717
+
718
+ else
719
+ raise InstallError, "unknown global option '#{arg}'"
720
+ end
721
+ end
722
+
723
+ raise InstallError, <<EOS
724
+ No task or global option given.
725
+ Typical installation procedure is:
726
+ $ ruby #{File.basename($0)} config
727
+ $ ruby #{File.basename($0)} setup
728
+ # ruby #{File.basename($0)} install (may require root privilege)
729
+ EOS
730
+ end
731
+
732
+
733
+ def parsearg_no_options
734
+ raise InstallError, "#{task}: unknown options: #{ARGV.join ' '}"\
735
+ unless ARGV.empty?
736
+ end
737
+
738
+ alias parsearg_show parsearg_no_options
739
+ alias parsearg_setup parsearg_no_options
740
+ alias parsearg_clean parsearg_no_options
741
+ alias parsearg_distclean parsearg_no_options
742
+
743
+ def parsearg_config
744
+ re = /\A--(#{ConfigTable.keys.join '|'})(?:=(.*))?\z/
745
+ @options['config-opt'] = []
746
+
747
+ while i = ARGV.shift
748
+ if /\A--?\z/ =~ i
749
+ @options['config-opt'] = ARGV.dup
750
+ break
751
+ end
752
+ m = re.match(i) or raise InstallError, "config: unknown option #{i}"
753
+ name, value = m.to_a[1,2]
754
+ if value
755
+ if ConfigTable.bool_config?(name)
756
+ raise InstallError, "config: --#{name} allows only yes/no for argument"\
757
+ unless /\A(y(es)?|n(o)?|t(rue)?|f(alse))\z/i =~ value
758
+ value = (/\Ay(es)?|\At(rue)/i =~ value) ? 'yes' : 'no'
759
+ end
760
+ else
761
+ raise InstallError, "config: --#{name} requires argument"\
762
+ unless ConfigTable.bool_config?(name)
763
+ value = 'yes'
764
+ end
765
+ @config[name] = value
766
+ end
767
+ end
768
+
769
+ def parsearg_install
770
+ @options['no-harm'] = false
771
+ @options['install-prefix'] = ''
772
+ while a = ARGV.shift
773
+ case a
774
+ when /\A--no-harm\z/
775
+ @options['no-harm'] = true
776
+ when /\A--prefix=(.*)\z/
777
+ path = $1
778
+ path = File.expand_path(path) unless path[0,1] == '/'
779
+ @options['install-prefix'] = path
780
+ else
781
+ raise InstallError, "install: unknown option #{a}"
782
+ end
783
+ end
784
+ end
785
+
786
+ def print_usage(out)
787
+ out.puts 'Typical Installation Procedure:'
788
+ out.puts " $ ruby #{File.basename $0} config"
789
+ out.puts " $ ruby #{File.basename $0} setup"
790
+ out.puts " # ruby #{File.basename $0} install (may require root privilege)"
791
+ out.puts
792
+ out.puts 'Detailed Usage:'
793
+ out.puts " ruby #{File.basename $0} <global option>"
794
+ out.puts " ruby #{File.basename $0} [<global options>] <task> [<task options>]"
795
+
796
+ fmt = " %-20s %s\n"
797
+ out.puts
798
+ out.puts 'Global options:'
799
+ out.printf fmt, '-q,--quiet', 'suppress message outputs'
800
+ out.printf fmt, ' --verbose', 'output messages verbosely'
801
+ out.printf fmt, '-h,--help', 'print this message'
802
+ out.printf fmt, '-v,--version', 'print version and quit'
803
+ out.printf fmt, ' --copyright', 'print copyright and quit'
804
+
805
+ out.puts
806
+ out.puts 'Tasks:'
807
+ TASKS.each do |name, desc|
808
+ out.printf " %-10s %s\n", name, desc
809
+ end
810
+
811
+ out.puts
812
+ out.puts 'Options for config:'
813
+ ConfigTable.each_definition do |name, (default, arg, desc, default2)|
814
+ out.printf " %-20s %s [%s]\n",
815
+ '--'+ name + (ConfigTable.bool_config?(name) ? '' : '='+arg),
816
+ desc,
817
+ default2 || default
818
+ end
819
+ out.printf " %-20s %s [%s]\n",
820
+ '--rbconfig=path', 'your rbconfig.rb to load', "running ruby's"
821
+
822
+ out.puts
823
+ out.puts 'Options for install:'
824
+ out.printf " %-20s %s [%s]\n",
825
+ '--no-harm', 'only display what to do if given', 'off'
826
+ out.printf " %-20s %s [%s]\n",
827
+ '--prefix', 'install path prefix', '$prefix'
828
+
829
+ out.puts
830
+ end
831
+
832
+ #
833
+ # Task Handlers
834
+ #
835
+
836
+ def exec_config
837
+ @installer.exec_config
838
+ @config.save # must be final
839
+ end
840
+
841
+ def exec_setup
842
+ @installer.exec_setup
843
+ end
844
+
845
+ def exec_install
846
+ @installer.exec_install
847
+ end
848
+
849
+ def exec_show
850
+ ConfigTable.each_name do |k|
851
+ v = @config.get_raw(k)
852
+ if not v or v.empty?
853
+ v = '(not specified)'
854
+ end
855
+ printf "%-10s %s\n", k, v
856
+ end
857
+ end
858
+
859
+ def exec_clean
860
+ @installer.exec_clean
861
+ end
862
+
863
+ def exec_distclean
864
+ @installer.exec_distclean
865
+ end
866
+
867
+ end
868
+
869
+
870
+ class ToplevelInstallerMulti < ToplevelInstaller
871
+
872
+ include HookUtils
873
+ include HookScriptAPI
874
+ include FileOperations
875
+
876
+ def initialize(ardir)
877
+ super
878
+ @packages = all_dirs_in("#{@ardir}/packages")
879
+ raise 'no package exists' if @packages.empty?
880
+ end
881
+
882
+ def run_metaconfigs
883
+ eval_file_ifexist "#{@ardir}/metaconfig"
884
+ @packages.each do |name|
885
+ eval_file_ifexist "#{@ardir}/packages/#{name}/metaconfig"
886
+ end
887
+ end
888
+
889
+ def init_installers
890
+ @installers = {}
891
+ @packages.each do |pack|
892
+ @installers[pack] = Installer.new(@config, @options,
893
+ "#{@ardir}/packages/#{pack}",
894
+ "packages/#{pack}")
895
+ end
896
+
897
+ with = extract_selection(config('with'))
898
+ without = extract_selection(config('without'))
899
+ @selected = @installers.keys.select {|name|
900
+ (with.empty? or with.include?(name)) \
901
+ and not without.include?(name)
902
+ }
903
+ end
904
+
905
+ def extract_selection(list)
906
+ a = list.split(/,/)
907
+ a.each do |name|
908
+ raise InstallError, "no such package: #{name}" \
909
+ unless @installers.key?(name)
910
+ end
911
+ a
912
+ end
913
+
914
+ def print_usage(f)
915
+ super
916
+ f.puts 'Inluded packages:'
917
+ f.puts ' ' + @packages.sort.join(' ')
918
+ f.puts
919
+ end
920
+
921
+ #
922
+ # multi-package metaconfig API
923
+ #
924
+
925
+ attr_reader :packages
926
+
927
+ def declare_packages(list)
928
+ raise 'package list is empty' if list.empty?
929
+ list.each do |name|
930
+ raise "directory packages/#{name} does not exist"\
931
+ unless File.dir?("#{@ardir}/packages/#{name}")
932
+ end
933
+ @packages = list
934
+ end
935
+
936
+ #
937
+ # Task Handlers
938
+ #
939
+
940
+ def exec_config
941
+ run_hook 'pre-config'
942
+ each_selected_installers {|inst| inst.exec_config }
943
+ run_hook 'post-config'
944
+ @config.save # must be final
945
+ end
946
+
947
+ def exec_setup
948
+ run_hook 'pre-setup'
949
+ each_selected_installers {|inst| inst.exec_setup }
950
+ run_hook 'post-setup'
951
+ end
952
+
953
+ def exec_install
954
+ run_hook 'pre-install'
955
+ each_selected_installers {|inst| inst.exec_install }
956
+ run_hook 'post-install'
957
+ end
958
+
959
+ def exec_clean
960
+ rm_f 'config.save'
961
+ run_hook 'pre-clean'
962
+ each_selected_installers {|inst| inst.exec_clean }
963
+ run_hook 'post-clean'
964
+ end
965
+
966
+ def exec_distclean
967
+ rm_f 'config.save'
968
+ run_hook 'pre-distclean'
969
+ each_selected_installers {|inst| inst.exec_distclean }
970
+ run_hook 'post-distclean'
971
+ end
972
+
973
+ #
974
+ # lib
975
+ #
976
+
977
+ def each_selected_installers
978
+ Dir.mkdir 'packages' unless File.dir?('packages')
979
+ @selected.each do |pack|
980
+ $stderr.puts "Processing the package `#{pack}' ..." if @options['verbose']
981
+ Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}")
982
+ Dir.chdir "packages/#{pack}"
983
+ yield @installers[pack]
984
+ Dir.chdir '../..'
985
+ end
986
+ end
987
+
988
+ def verbose?
989
+ @options['verbose']
990
+ end
991
+
992
+ def no_harm?
993
+ @options['no-harm']
994
+ end
995
+
996
+ end
997
+
998
+
999
+ class Installer
1000
+
1001
+ FILETYPES = %w( bin lib ext data )
1002
+
1003
+ include HookScriptAPI
1004
+ include HookUtils
1005
+ include FileOperations
1006
+
1007
+ def initialize(config, opt, srcroot, objroot)
1008
+ @config = config
1009
+ @options = opt
1010
+ @srcdir = File.expand_path(srcroot)
1011
+ @objdir = File.expand_path(objroot)
1012
+ @currdir = '.'
1013
+ end
1014
+
1015
+ def inspect
1016
+ "#<#{self.class} #{File.basename(@srcdir)}>"
1017
+ end
1018
+
1019
+ #
1020
+ # Hook Script API bases
1021
+ #
1022
+
1023
+ def srcdir_root
1024
+ @srcdir
1025
+ end
1026
+
1027
+ def objdir_root
1028
+ @objdir
1029
+ end
1030
+
1031
+ def relpath
1032
+ @currdir
1033
+ end
1034
+
1035
+ #
1036
+ # configs/options
1037
+ #
1038
+
1039
+ def no_harm?
1040
+ @options['no-harm']
1041
+ end
1042
+
1043
+ def verbose?
1044
+ @options['verbose']
1045
+ end
1046
+
1047
+ def verbose_off
1048
+ begin
1049
+ save, @options['verbose'] = @options['verbose'], false
1050
+ yield
1051
+ ensure
1052
+ @options['verbose'] = save
1053
+ end
1054
+ end
1055
+
1056
+ #
1057
+ # TASK config
1058
+ #
1059
+
1060
+ def exec_config
1061
+ exec_task_traverse 'config'
1062
+ end
1063
+
1064
+ def config_dir_bin(rel)
1065
+ end
1066
+
1067
+ def config_dir_lib(rel)
1068
+ end
1069
+
1070
+ def config_dir_ext(rel)
1071
+ extconf if extdir?(curr_srcdir())
1072
+ end
1073
+
1074
+ def extconf
1075
+ opt = @options['config-opt'].join(' ')
1076
+ command "#{config('ruby-prog')} #{curr_srcdir()}/extconf.rb #{opt}"
1077
+ end
1078
+
1079
+ def config_dir_data(rel)
1080
+ end
1081
+
1082
+ #
1083
+ # TASK setup
1084
+ #
1085
+
1086
+ def exec_setup
1087
+ exec_task_traverse 'setup'
1088
+ end
1089
+
1090
+ def setup_dir_bin(rel)
1091
+ all_files_in(curr_srcdir()).each do |fname|
1092
+ adjust_shebang "#{curr_srcdir()}/#{fname}"
1093
+ end
1094
+ end
1095
+
1096
+ # modify: #!/usr/bin/ruby
1097
+ # modify: #! /usr/bin/ruby
1098
+ # modify: #!ruby
1099
+ # not modify: #!/usr/bin/env ruby
1100
+ SHEBANG_RE = /\A\#!\s*\S*ruby\S*/
1101
+
1102
+ def adjust_shebang(path)
1103
+ return if no_harm?
1104
+
1105
+ tmpfile = File.basename(path) + '.tmp'
1106
+ begin
1107
+ File.open(path, 'rb') {|r|
1108
+ File.open(tmpfile, 'wb') {|w|
1109
+ first = r.gets
1110
+ return unless SHEBANG_RE =~ first
1111
+
1112
+ $stderr.puts "adjusting shebang: #{File.basename path}" if verbose?
1113
+ w.print first.sub(SHEBANG_RE, '#!' + config('ruby-path'))
1114
+ w.write r.read
1115
+ }
1116
+ }
1117
+ move_file tmpfile, File.basename(path)
1118
+ ensure
1119
+ File.unlink tmpfile if File.exist?(tmpfile)
1120
+ end
1121
+ end
1122
+
1123
+ def setup_dir_lib(rel)
1124
+ end
1125
+
1126
+ def setup_dir_ext(rel)
1127
+ make if extdir?(curr_srcdir())
1128
+ end
1129
+
1130
+ def setup_dir_data(rel)
1131
+ end
1132
+
1133
+ #
1134
+ # TASK install
1135
+ #
1136
+
1137
+ def exec_install
1138
+ exec_task_traverse 'install'
1139
+ end
1140
+
1141
+ def install_dir_bin(rel)
1142
+ install_files collect_filenames_auto(), "#{config('bin-dir')}/#{rel}", 0755
1143
+ end
1144
+
1145
+ def install_dir_lib(rel)
1146
+ install_files ruby_scripts(), "#{config('rb-dir')}/#{rel}", 0644
1147
+ end
1148
+
1149
+ def install_dir_ext(rel)
1150
+ return unless extdir?(curr_srcdir())
1151
+ install_files ruby_extentions('.'),
1152
+ "#{config('so-dir')}/#{File.dirname(rel)}",
1153
+ 0555
1154
+ end
1155
+
1156
+ def install_dir_data(rel)
1157
+ install_files collect_filenames_auto(), "#{config('data-dir')}/#{rel}", 0644
1158
+ end
1159
+
1160
+ def install_files(list, dest, mode)
1161
+ mkdir_p dest, @options['install-prefix']
1162
+ list.each do |fname|
1163
+ install fname, dest, mode, @options['install-prefix']
1164
+ end
1165
+ end
1166
+
1167
+ def ruby_scripts
1168
+ collect_filenames_auto().select {|n| /\.(rb|yml)\z/ =~ n }
1169
+ end
1170
+
1171
+ # picked up many entries from cvs-1.11.1/src/ignore.c
1172
+ reject_patterns = %w(
1173
+ core RCSLOG tags TAGS .make.state
1174
+ .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb
1175
+ *~ *.old *.bak *.BAK *.orig *.rej _$* *$
1176
+
1177
+ *.org *.in .*
1178
+ )
1179
+ mapping = {
1180
+ '.' => '\.',
1181
+ '$' => '\$',
1182
+ '#' => '\#',
1183
+ '*' => '.*'
1184
+ }
1185
+ REJECT_PATTERNS = Regexp.new('\A(?:' +
1186
+ reject_patterns.map {|pat|
1187
+ pat.gsub(/[\.\$\#\*]/) {|ch| mapping[ch] }
1188
+ }.join('|') +
1189
+ ')\z')
1190
+
1191
+ def collect_filenames_auto
1192
+ mapdir((existfiles() - hookfiles()).reject {|fname|
1193
+ REJECT_PATTERNS =~ fname
1194
+ })
1195
+ end
1196
+
1197
+ def existfiles
1198
+ all_files_in(curr_srcdir()) | all_files_in('.')
1199
+ end
1200
+
1201
+ def hookfiles
1202
+ %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt|
1203
+ %w( config setup install clean ).map {|t| sprintf(fmt, t) }
1204
+ }.flatten
1205
+ end
1206
+
1207
+ def mapdir(filelist)
1208
+ filelist.map {|fname|
1209
+ if File.exist?(fname) # objdir
1210
+ fname
1211
+ else # srcdir
1212
+ File.join(curr_srcdir(), fname)
1213
+ end
1214
+ }
1215
+ end
1216
+
1217
+ def ruby_extentions(dir)
1218
+ _ruby_extentions(dir) or
1219
+ raise InstallError, "no ruby extention exists: 'ruby #{$0} setup' first"
1220
+ end
1221
+
1222
+ DLEXT = /\.#{ ::RbConfig::CONFIG['DLEXT'] }\z/
1223
+
1224
+ def _ruby_extentions(dir)
1225
+ Dir.open(dir) {|d|
1226
+ return d.select {|fname| DLEXT =~ fname }
1227
+ }
1228
+ end
1229
+
1230
+ #
1231
+ # TASK clean
1232
+ #
1233
+
1234
+ def exec_clean
1235
+ exec_task_traverse 'clean'
1236
+ rm_f 'config.save'
1237
+ rm_f 'InstalledFiles'
1238
+ end
1239
+
1240
+ def clean_dir_bin(rel)
1241
+ end
1242
+
1243
+ def clean_dir_lib(rel)
1244
+ end
1245
+
1246
+ def clean_dir_ext(rel)
1247
+ return unless extdir?(curr_srcdir())
1248
+ make 'clean' if File.file?('Makefile')
1249
+ end
1250
+
1251
+ def clean_dir_data(rel)
1252
+ end
1253
+
1254
+ #
1255
+ # TASK distclean
1256
+ #
1257
+
1258
+ def exec_distclean
1259
+ exec_task_traverse 'distclean'
1260
+ rm_f 'config.save'
1261
+ rm_f 'InstalledFiles'
1262
+ end
1263
+
1264
+ def distclean_dir_bin(rel)
1265
+ end
1266
+
1267
+ def distclean_dir_lib(rel)
1268
+ end
1269
+
1270
+ def distclean_dir_ext(rel)
1271
+ return unless extdir?(curr_srcdir())
1272
+ make 'distclean' if File.file?('Makefile')
1273
+ end
1274
+
1275
+ #
1276
+ # lib
1277
+ #
1278
+
1279
+ def exec_task_traverse(task)
1280
+ run_hook "pre-#{task}"
1281
+ FILETYPES.each do |type|
1282
+ if config('without-ext') == 'yes' and type == 'ext'
1283
+ $stderr.puts 'skipping ext/* by user option' if verbose?
1284
+ next
1285
+ end
1286
+ traverse task, type, "#{task}_dir_#{type}"
1287
+ end
1288
+ run_hook "post-#{task}"
1289
+ end
1290
+
1291
+ def traverse(task, rel, mid)
1292
+ dive_into(rel) {
1293
+ run_hook "pre-#{task}"
1294
+ __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '')
1295
+ all_dirs_in(curr_srcdir()).each do |d|
1296
+ traverse task, "#{rel}/#{d}", mid
1297
+ end
1298
+ run_hook "post-#{task}"
1299
+ }
1300
+ end
1301
+
1302
+ def dive_into(rel)
1303
+ return unless File.dir?("#{@srcdir}/#{rel}")
1304
+
1305
+ dir = File.basename(rel)
1306
+ Dir.mkdir dir unless File.dir?(dir)
1307
+ prevdir = Dir.pwd
1308
+ Dir.chdir dir
1309
+ $stderr.puts '---> ' + rel if verbose?
1310
+ @currdir = rel
1311
+ yield
1312
+ Dir.chdir prevdir
1313
+ $stderr.puts '<--- ' + rel if verbose?
1314
+ @currdir = File.dirname(rel)
1315
+ end
1316
+
1317
+ end
1318
+
1319
+
1320
+ if $0 == __FILE__
1321
+ begin
1322
+ if multipackage_install?
1323
+ ToplevelInstallerMulti.invoke
1324
+ else
1325
+ ToplevelInstaller.invoke
1326
+ end
1327
+ rescue
1328
+ raise if $DEBUG
1329
+ $stderr.puts $!.message
1330
+ $stderr.puts "Try 'ruby #{$0} --help' for detailed usage."
1331
+ exit 1
1332
+ end
1333
+ end