ruby-oci8 2.1.5.1-x64-mingw32

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 (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