rqr19 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/rqr.rb +7 -1587
  2. data/lib/rqr/version.rb +1 -1
  3. metadata +3 -3
data/lib/rqr.rb CHANGED
@@ -1,1589 +1,9 @@
1
- module RQR
2
-
3
- #
4
- # setup.rb
5
- #
6
- # Copyright (c) 2000-2005 Minero Aoki
7
- #
8
- # This program is free software.
9
- # You can distribute/modify this program under the terms of
10
- # the GNU LGPL, Lesser General Public License version 2.1.
11
- #
12
-
13
- unless Enumerable.method_defined?(:map) # Ruby 1.4.6
14
- module Enumerable
15
- alias map collect
16
- end
17
- end
18
-
19
- unless File.respond_to?(:read) # Ruby 1.6
20
- def File.read(fname)
21
- open(fname) {|f|
22
- return f.read
23
- }
24
- end
25
- end
26
-
27
- unless Errno.const_defined?(:ENOTEMPTY) # Windows?
28
- module Errno
29
- class ENOTEMPTY
30
- # We do not raise this exception, implementation is not needed.
31
- end
32
- end
33
- end
34
-
35
- def File.binread(fname)
36
- open(fname, 'rb') {|f|
37
- return f.read
38
- }
39
- end
40
-
41
- # for corrupted Windows' stat(2)
42
- def File.dir?(path)
43
- File.directory?((path[-1,1] == '/') ? path : path + '/')
44
- end
45
-
46
-
47
- class ConfigTable
48
-
49
- include Enumerable
50
-
51
- def initialize(rbconfig)
52
- @rbconfig = rbconfig
53
- @items = []
54
- @table = {}
55
- # options
56
- @install_prefix = nil
57
- @config_opt = nil
58
- @verbose = true
59
- @no_harm = false
60
- end
61
-
62
- attr_accessor :install_prefix
63
- attr_accessor :config_opt
64
-
65
- attr_writer :verbose
66
-
67
- def verbose?
68
- @verbose
69
- end
70
-
71
- attr_writer :no_harm
72
-
73
- def no_harm?
74
- @no_harm
75
- end
76
-
77
- def [](key)
78
- lookup(key).resolve(self)
79
- end
80
-
81
- def []=(key, val)
82
- lookup(key).set val
83
- end
84
-
85
- def names
86
- @items.map {|i| i.name }
87
- end
88
-
89
- def each(&block)
90
- @items.each(&block)
91
- end
92
-
93
- def key?(name)
94
- @table.key?(name)
95
- end
96
-
97
- def lookup(name)
98
- @table[name] or setup_rb_error "no such config item: #{name}"
99
- end
100
-
101
- def add(item)
102
- @items.push item
103
- @table[item.name] = item
104
- end
105
-
106
- def remove(name)
107
- item = lookup(name)
108
- @items.delete_if {|i| i.name == name }
109
- @table.delete_if {|name, i| i.name == name }
110
- item
111
- end
112
-
113
- def load_script(path, inst = nil)
114
- if File.file?(path)
115
- MetaConfigEnvironment.new(self, inst).instance_eval File.read(path), path
116
- end
117
- end
118
-
119
- def savefile
120
- '.config'
121
- end
122
-
123
- def load_savefile
124
- begin
125
- File.foreach(savefile()) do |line|
126
- k, v = *line.split(/=/, 2)
127
- self[k] = v.strip
128
- end
129
- rescue Errno::ENOENT
130
- setup_rb_error $!.message + "\n#{File.basename($0)} config first"
131
- end
132
- end
133
-
134
- def save
135
- @items.each {|i| i.value }
136
- File.open(savefile(), 'w') {|f|
137
- @items.each do |i|
138
- f.printf "%s=%s\n", i.name, i.value if i.value? and i.value
139
- end
140
- }
141
- end
142
-
143
- def load_standard_entries
144
- standard_entries(@rbconfig).each do |ent|
145
- add ent
146
- end
147
- end
148
-
149
- def standard_entries(rbconfig)
150
- c = rbconfig
151
-
152
- rubypath = File.join(c['bindir'], c['ruby_install_name'] + c['EXEEXT'])
153
-
154
- major = c['MAJOR'].to_i
155
- minor = c['MINOR'].to_i
156
- teeny = c['TEENY'].to_i
157
- version = "#{major}.#{minor}"
158
-
159
- # ruby ver. >= 1.4.4?
160
- newpath_p = ((major >= 2) or
161
- ((major == 1) and
162
- ((minor >= 5) or
163
- ((minor == 4) and (teeny >= 4)))))
164
-
165
- if c['rubylibdir']
166
- # V > 1.6.3
167
- libruby = "#{c['prefix']}/lib/ruby"
168
- librubyver = c['rubylibdir']
169
- librubyverarch = c['archdir']
170
- siteruby = c['sitedir']
171
- siterubyver = c['sitelibdir']
172
- siterubyverarch = c['sitearchdir']
173
- elsif newpath_p
174
- # 1.4.4 <= V <= 1.6.3
175
- libruby = "#{c['prefix']}/lib/ruby"
176
- librubyver = "#{c['prefix']}/lib/ruby/#{version}"
177
- librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}"
178
- siteruby = c['sitedir']
179
- siterubyver = "$siteruby/#{version}"
180
- siterubyverarch = "$siterubyver/#{c['arch']}"
181
- else
182
- # V < 1.4.4
183
- libruby = "#{c['prefix']}/lib/ruby"
184
- librubyver = "#{c['prefix']}/lib/ruby/#{version}"
185
- librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}"
186
- siteruby = "#{c['prefix']}/lib/ruby/#{version}/site_ruby"
187
- siterubyver = siteruby
188
- siterubyverarch = "$siterubyver/#{c['arch']}"
189
- end
190
- parameterize = lambda {|path|
191
- path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix')
192
- }
193
-
194
- if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg }
195
- makeprog = arg.sub(/'/, '').split(/=/, 2)[1]
196
- else
197
- makeprog = 'make'
198
- end
199
-
200
- [
201
- ExecItem.new('installdirs', 'std/site/home',
202
- 'std: install under libruby; site: install under site_ruby; home: install under $HOME')\
203
- {|val, table|
204
- case val
205
- when 'std'
206
- table['rbdir'] = '$librubyver'
207
- table['sodir'] = '$librubyverarch'
208
- when 'site'
209
- table['rbdir'] = '$siterubyver'
210
- table['sodir'] = '$siterubyverarch'
211
- when 'home'
212
- setup_rb_error '$HOME was not set' unless ENV['HOME']
213
- table['prefix'] = ENV['HOME']
214
- table['rbdir'] = '$libdir/ruby'
215
- table['sodir'] = '$libdir/ruby'
216
- end
217
- },
218
- PathItem.new('prefix', 'path', c['prefix'],
219
- 'path prefix of target environment'),
220
- PathItem.new('bindir', 'path', parameterize.call(c['bindir']),
221
- 'the directory for commands'),
222
- PathItem.new('libdir', 'path', parameterize.call(c['libdir']),
223
- 'the directory for libraries'),
224
- PathItem.new('datadir', 'path', parameterize.call(c['datadir']),
225
- 'the directory for shared data'),
226
- PathItem.new('mandir', 'path', parameterize.call(c['mandir']),
227
- 'the directory for man pages'),
228
- PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']),
229
- 'the directory for system configuration files'),
230
- PathItem.new('localstatedir', 'path', parameterize.call(c['localstatedir']),
231
- 'the directory for local state data'),
232
- PathItem.new('libruby', 'path', libruby,
233
- 'the directory for ruby libraries'),
234
- PathItem.new('librubyver', 'path', librubyver,
235
- 'the directory for standard ruby libraries'),
236
- PathItem.new('librubyverarch', 'path', librubyverarch,
237
- 'the directory for standard ruby extensions'),
238
- PathItem.new('siteruby', 'path', siteruby,
239
- 'the directory for version-independent aux ruby libraries'),
240
- PathItem.new('siterubyver', 'path', siterubyver,
241
- 'the directory for aux ruby libraries'),
242
- PathItem.new('siterubyverarch', 'path', siterubyverarch,
243
- 'the directory for aux ruby binaries'),
244
- PathItem.new('rbdir', 'path', '$siterubyver',
245
- 'the directory for ruby scripts'),
246
- PathItem.new('sodir', 'path', '$siterubyverarch',
247
- 'the directory for ruby extentions'),
248
- PathItem.new('rubypath', 'path', rubypath,
249
- 'the path to set to #! line'),
250
- ProgramItem.new('rubyprog', 'name', rubypath,
251
- 'the ruby program using for installation'),
252
- ProgramItem.new('makeprog', 'name', makeprog,
253
- 'the make program to compile ruby extentions'),
254
- SelectItem.new('shebang', 'all/ruby/never', 'ruby',
255
- 'shebang line (#!) editing mode'),
256
- BoolItem.new('without-ext', 'yes/no', 'no',
257
- 'does not compile/install ruby extentions')
258
- ]
259
- end
260
- private :standard_entries
261
-
262
- def load_multipackage_entries
263
- multipackage_entries().each do |ent|
264
- add ent
265
- end
266
- end
267
-
268
- def multipackage_entries
269
- [
270
- PackageSelectionItem.new('with', 'name,name...', '', 'ALL',
271
- 'package names that you want to install'),
272
- PackageSelectionItem.new('without', 'name,name...', '', 'NONE',
273
- 'package names that you do not want to install')
274
- ]
275
- end
276
- private :multipackage_entries
277
-
278
- ALIASES = {
279
- 'std-ruby' => 'librubyver',
280
- 'stdruby' => 'librubyver',
281
- 'rubylibdir' => 'librubyver',
282
- 'archdir' => 'librubyverarch',
283
- 'site-ruby-common' => 'siteruby', # For backward compatibility
284
- 'site-ruby' => 'siterubyver', # For backward compatibility
285
- 'bin-dir' => 'bindir',
286
- 'bin-dir' => 'bindir',
287
- 'rb-dir' => 'rbdir',
288
- 'so-dir' => 'sodir',
289
- 'data-dir' => 'datadir',
290
- 'ruby-path' => 'rubypath',
291
- 'ruby-prog' => 'rubyprog',
292
- 'ruby' => 'rubyprog',
293
- 'make-prog' => 'makeprog',
294
- 'make' => 'makeprog'
295
- }
296
-
297
- def fixup
298
- ALIASES.each do |ali, name|
299
- @table[ali] = @table[name]
300
- end
301
- @items.freeze
302
- @table.freeze
303
- @options_re = /\A--(#{@table.keys.join('|')})(?:=(.*))?\z/
304
- end
305
-
306
- def parse_opt(opt)
307
- m = @options_re.match(opt) or setup_rb_error "config: unknown option #{opt}"
308
- m.to_a[1,2]
309
- end
310
-
311
- def dllext
312
- @rbconfig['DLEXT']
313
- end
314
-
315
- def value_config?(name)
316
- lookup(name).value?
317
- end
318
-
319
- class Item
320
- def initialize(name, template, default, desc)
321
- @name = name.freeze
322
- @template = template
323
- @value = default
324
- @default = default
325
- @description = desc
326
- end
327
-
328
- attr_reader :name
329
- attr_reader :description
330
-
331
- attr_accessor :default
332
- alias help_default default
333
-
334
- def help_opt
335
- "--#{@name}=#{@template}"
336
- end
337
-
338
- def value?
339
- true
340
- end
341
-
342
- def value
343
- @value
344
- end
345
-
346
- def resolve(table)
347
- @value.gsub(%r<\$([^/]+)>) { table[$1] }
348
- end
349
-
350
- def set(val)
351
- @value = check(val)
352
- end
353
-
354
- private
355
-
356
- def check(val)
357
- setup_rb_error "config: --#{name} requires argument" unless val
358
- val
359
- end
360
- end
361
-
362
- class BoolItem < Item
363
- def config_type
364
- 'bool'
365
- end
366
-
367
- def help_opt
368
- "--#{@name}"
369
- end
370
-
371
- private
372
-
373
- def check(val)
374
- return 'yes' unless val
375
- case val
376
- when /\Ay(es)?\z/i, /\At(rue)?\z/i then 'yes'
377
- when /\An(o)?\z/i, /\Af(alse)\z/i then 'no'
378
- else
379
- setup_rb_error "config: --#{@name} accepts only yes/no for argument"
380
- end
381
- end
382
- end
383
-
384
- class PathItem < Item
385
- def config_type
386
- 'path'
387
- end
388
-
389
- private
390
-
391
- def check(path)
392
- setup_rb_error "config: --#{@name} requires argument" unless path
393
- path[0,1] == '$' ? path : File.expand_path(path)
394
- end
395
- end
396
-
397
- class ProgramItem < Item
398
- def config_type
399
- 'program'
400
- end
401
- end
402
-
403
- class SelectItem < Item
404
- def initialize(name, selection, default, desc)
405
- super
406
- @ok = selection.split('/')
407
- end
408
-
409
- def config_type
410
- 'select'
411
- end
412
-
413
- private
414
-
415
- def check(val)
416
- unless @ok.include?(val.strip)
417
- setup_rb_error "config: use --#{@name}=#{@template} (#{val})"
418
- end
419
- val.strip
420
- end
421
- end
422
-
423
- class ExecItem < Item
424
- def initialize(name, selection, desc, &block)
425
- super name, selection, nil, desc
426
- @ok = selection.split('/')
427
- @action = block
428
- end
429
-
430
- def config_type
431
- 'exec'
432
- end
433
-
434
- def value?
435
- false
436
- end
437
-
438
- def resolve(table)
439
- setup_rb_error "$#{name()} wrongly used as option value"
440
- end
441
-
442
- undef set
443
-
444
- def evaluate(val, table)
445
- v = val.strip.downcase
446
- unless @ok.include?(v)
447
- setup_rb_error "invalid option --#{@name}=#{val} (use #{@template})"
448
- end
449
- @action.call v, table
450
- end
451
- end
452
-
453
- class PackageSelectionItem < Item
454
- def initialize(name, template, default, help_default, desc)
455
- super name, template, default, desc
456
- @help_default = help_default
457
- end
458
-
459
- attr_reader :help_default
460
-
461
- def config_type
462
- 'package'
463
- end
464
-
465
- private
466
-
467
- def check(val)
468
- unless File.dir?("packages/#{val}")
469
- setup_rb_error "config: no such package: #{val}"
470
- end
471
- val
472
- end
473
- end
474
-
475
- class MetaConfigEnvironment
476
- def initialize(config, installer)
477
- @config = config
478
- @installer = installer
479
- end
480
-
481
- def config_names
482
- @config.names
483
- end
484
-
485
- def config?(name)
486
- @config.key?(name)
487
- end
488
-
489
- def bool_config?(name)
490
- @config.lookup(name).config_type == 'bool'
491
- end
492
-
493
- def path_config?(name)
494
- @config.lookup(name).config_type == 'path'
495
- end
496
-
497
- def value_config?(name)
498
- @config.lookup(name).config_type != 'exec'
499
- end
500
-
501
- def add_config(item)
502
- @config.add item
503
- end
504
-
505
- def add_bool_config(name, default, desc)
506
- @config.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc)
507
- end
508
-
509
- def add_path_config(name, default, desc)
510
- @config.add PathItem.new(name, 'path', default, desc)
511
- end
512
-
513
- def set_config_default(name, default)
514
- @config.lookup(name).default = default
515
- end
516
-
517
- def remove_config(name)
518
- @config.remove(name)
519
- end
520
-
521
- # For only multipackage
522
- def packages
523
- raise '[setup.rb fatal] multi-package metaconfig API packages() called for single-package; contact application package vendor' unless @installer
524
- @installer.packages
525
- end
526
-
527
- # For only multipackage
528
- def declare_packages(list)
529
- raise '[setup.rb fatal] multi-package metaconfig API declare_packages() called for single-package; contact application package vendor' unless @installer
530
- @installer.packages = list
531
- end
532
- end
533
-
534
- end # class ConfigTable
535
-
536
-
537
- # This module requires: #verbose?, #no_harm?
538
- module FileOperations
539
-
540
- def mkdir_p(dirname, prefix = nil)
541
- dirname = prefix + File.expand_path(dirname) if prefix
542
- $stderr.puts "mkdir -p #{dirname}" if verbose?
543
- return if no_harm?
544
-
545
- # Does not check '/', it's too abnormal.
546
- dirs = File.expand_path(dirname).split(%r<(?=/)>)
547
- if /\A[a-z]:\z/i =~ dirs[0]
548
- disk = dirs.shift
549
- dirs[0] = disk + dirs[0]
550
- end
551
- dirs.each_index do |idx|
552
- path = dirs[0..idx].join('')
553
- Dir.mkdir path unless File.dir?(path)
554
- end
555
- end
556
-
557
- def rm_f(path)
558
- $stderr.puts "rm -f #{path}" if verbose?
559
- return if no_harm?
560
- force_remove_file path
561
- end
562
-
563
- def rm_rf(path)
564
- $stderr.puts "rm -rf #{path}" if verbose?
565
- return if no_harm?
566
- remove_tree path
567
- end
568
-
569
- def remove_tree(path)
570
- if File.symlink?(path)
571
- remove_file path
572
- elsif File.dir?(path)
573
- remove_tree0 path
574
- else
575
- force_remove_file path
576
- end
577
- end
578
-
579
- def remove_tree0(path)
580
- Dir.foreach(path) do |ent|
581
- next if ent == '.'
582
- next if ent == '..'
583
- entpath = "#{path}/#{ent}"
584
- if File.symlink?(entpath)
585
- remove_file entpath
586
- elsif File.dir?(entpath)
587
- remove_tree0 entpath
588
- else
589
- force_remove_file entpath
590
- end
591
- end
592
- begin
593
- Dir.rmdir path
594
- rescue Errno::ENOTEMPTY
595
- # directory may not be empty
596
- end
597
- end
598
-
599
- def move_file(src, dest)
600
- force_remove_file dest
601
- begin
602
- File.rename src, dest
603
- rescue
604
- File.open(dest, 'wb') {|f|
605
- f.write File.binread(src)
606
- }
607
- File.chmod File.stat(src).mode, dest
608
- File.unlink src
609
- end
610
- end
611
-
612
- def force_remove_file(path)
613
- begin
614
- remove_file path
615
- rescue
616
- end
617
- end
618
-
619
- def remove_file(path)
620
- File.chmod 0777, path
621
- File.unlink path
622
- end
623
-
624
- def install(from, dest, mode, prefix = nil)
625
- $stderr.puts "install #{from} #{dest}" if verbose?
626
- return if no_harm?
627
-
628
- realdest = prefix ? prefix + File.expand_path(dest) : dest
629
- realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest)
630
- str = File.binread(from)
631
- if diff?(str, realdest)
632
- verbose_off {
633
- rm_f realdest if File.exist?(realdest)
634
- }
635
- File.open(realdest, 'wb') {|f|
636
- f.write str
637
- }
638
- File.chmod mode, realdest
639
-
640
- File.open("#{objdir_root()}/InstalledFiles", 'a') {|f|
641
- if prefix
642
- f.puts realdest.sub(prefix, '')
643
- else
644
- f.puts realdest
645
- end
646
- }
647
- end
648
- end
649
-
650
- def diff?(new_content, path)
651
- return true unless File.exist?(path)
652
- new_content != File.binread(path)
653
- end
654
-
655
- def command(*args)
656
- $stderr.puts args.join(' ') if verbose?
657
- system(*args) or raise RuntimeError,
658
- "system(#{args.map{|a| a.inspect }.join(' ')}) failed"
659
- end
660
-
661
- def ruby(*args)
662
- command config('rubyprog'), *args
663
- end
664
-
665
- def make(task = nil)
666
- command(*[config('makeprog'), task].compact)
667
- end
668
-
669
- def extdir?(dir)
670
- File.exist?("#{dir}/MANIFEST") or File.exist?("#{dir}/extconf.rb")
671
- end
672
-
673
- def files_of(dir)
674
- Dir.open(dir) {|d|
675
- return d.select {|ent| File.file?("#{dir}/#{ent}") }
676
- }
677
- end
678
-
679
- DIR_REJECT = %w( . .. CVS SCCS RCS CVS.adm .svn )
680
-
681
- def directories_of(dir)
682
- Dir.open(dir) {|d|
683
- return d.select {|ent| File.dir?("#{dir}/#{ent}") } - DIR_REJECT
684
- }
685
- end
686
-
687
- end
688
-
689
-
690
- # This module requires: #srcdir_root, #objdir_root, #relpath
691
- module HookScriptAPI
692
-
693
- def get_config(key)
694
- @config[key]
695
- end
696
-
697
- alias config get_config
698
-
699
- # obsolete: use metaconfig to change configuration
700
- def set_config(key, val)
701
- @config[key] = val
702
- end
703
-
704
- #
705
- # srcdir/objdir (works only in the package directory)
706
- #
707
-
708
- def curr_srcdir
709
- "#{srcdir_root()}/#{relpath()}"
710
- end
711
-
712
- def curr_objdir
713
- "#{objdir_root()}/#{relpath()}"
714
- end
715
-
716
- def srcfile(path)
717
- "#{curr_srcdir()}/#{path}"
718
- end
719
-
720
- def srcexist?(path)
721
- File.exist?(srcfile(path))
722
- end
723
-
724
- def srcdirectory?(path)
725
- File.dir?(srcfile(path))
726
- end
727
-
728
- def srcfile?(path)
729
- File.file?(srcfile(path))
730
- end
731
-
732
- def srcentries(path = '.')
733
- Dir.open("#{curr_srcdir()}/#{path}") {|d|
734
- return d.to_a - %w(. ..)
735
- }
736
- end
737
-
738
- def srcfiles(path = '.')
739
- srcentries(path).select {|fname|
740
- File.file?(File.join(curr_srcdir(), path, fname))
741
- }
742
- end
743
-
744
- def srcdirectories(path = '.')
745
- srcentries(path).select {|fname|
746
- File.dir?(File.join(curr_srcdir(), path, fname))
747
- }
748
- end
749
-
750
- end
751
-
752
-
753
- class ToplevelInstaller
754
-
755
- Version = '3.4.1'
756
- Copyright = 'Copyright (c) 2000-2005 Minero Aoki'
757
-
758
- TASKS = [
759
- [ 'all', 'do config, setup, then install' ],
760
- [ 'config', 'saves your configurations' ],
761
- [ 'show', 'shows current configuration' ],
762
- [ 'setup', 'compiles ruby extentions and others' ],
763
- [ 'install', 'installs files' ],
764
- [ 'test', 'run all tests in test/' ],
765
- [ 'clean', "does `make clean' for each extention" ],
766
- [ 'distclean',"does `make distclean' for each extention" ]
767
- ]
768
-
769
- def ToplevelInstaller.invoke
770
- config = ConfigTable.new(load_rbconfig())
771
- config.load_standard_entries
772
- config.load_multipackage_entries if multipackage?
773
- config.fixup
774
- klass = (multipackage?() ? ToplevelInstallerMulti : ToplevelInstaller)
775
- klass.new(File.dirname($0), config).invoke
776
- end
777
-
778
- def ToplevelInstaller.multipackage?
779
- File.dir?(File.dirname($0) + '/packages')
780
- end
781
-
782
- def ToplevelInstaller.load_rbconfig
783
- if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg }
784
- ARGV.delete(arg)
785
- load File.expand_path(arg.split(/=/, 2)[1])
786
- $".push 'rbconfig.rb'
787
- else
788
- require 'rbconfig'
789
- end
790
- ::Config::CONFIG
791
- end
792
-
793
- def initialize(ardir_root, config)
794
- @ardir = File.expand_path(ardir_root)
795
- @config = config
796
- # cache
797
- @valid_task_re = nil
798
- end
799
-
800
- def config(key)
801
- @config[key]
802
- end
803
-
804
- def inspect
805
- "#<#{self.class} #{__id__()}>"
806
- end
807
-
808
- def invoke
809
- run_metaconfigs
810
- case task = parsearg_global()
811
- when nil, 'all'
812
- parsearg_config
813
- init_installers
814
- exec_config
815
- exec_setup
816
- exec_install
817
- else
818
- case task
819
- when 'config', 'test'
820
- ;
821
- when 'clean', 'distclean'
822
- @config.load_savefile if File.exist?(@config.savefile)
823
- else
824
- @config.load_savefile
825
- end
826
- __send__ "parsearg_#{task}"
827
- init_installers
828
- __send__ "exec_#{task}"
829
- end
830
- end
831
-
832
- def run_metaconfigs
833
- @config.load_script "#{@ardir}/metaconfig"
834
- end
835
-
836
- def init_installers
837
- @installer = Installer.new(@config, @ardir, File.expand_path('.'))
838
- end
839
-
840
- #
841
- # Hook Script API bases
842
- #
843
-
844
- def srcdir_root
845
- @ardir
846
- end
847
-
848
- def objdir_root
849
- '.'
850
- end
851
-
852
- def relpath
853
- '.'
854
- end
855
-
856
- #
857
- # Option Parsing
858
- #
859
-
860
- def parsearg_global
861
- while arg = ARGV.shift
862
- case arg
863
- when /\A\w+\z/
864
- setup_rb_error "invalid task: #{arg}" unless valid_task?(arg)
865
- return arg
866
- when '-q', '--quiet'
867
- @config.verbose = false
868
- when '--verbose'
869
- @config.verbose = true
870
- when '--help'
871
- print_usage $stdout
872
- exit 0
873
- when '--version'
874
- puts "#{File.basename($0)} version #{Version}"
875
- exit 0
876
- when '--copyright'
877
- puts Copyright
878
- exit 0
879
- else
880
- setup_rb_error "unknown global option '#{arg}'"
881
- end
882
- end
883
- nil
884
- end
885
-
886
- def valid_task?(t)
887
- valid_task_re() =~ t
888
- end
889
-
890
- def valid_task_re
891
- @valid_task_re ||= /\A(?:#{TASKS.map {|task,desc| task }.join('|')})\z/
892
- end
893
-
894
- def parsearg_no_options
895
- unless ARGV.empty?
896
- task = caller(0).first.slice(%r<`parsearg_(\w+)'>, 1)
897
- setup_rb_error "#{task}: unknown options: #{ARGV.join(' ')}"
898
- end
899
- end
900
-
901
- alias parsearg_show parsearg_no_options
902
- alias parsearg_setup parsearg_no_options
903
- alias parsearg_test parsearg_no_options
904
- alias parsearg_clean parsearg_no_options
905
- alias parsearg_distclean parsearg_no_options
906
-
907
- def parsearg_config
908
- evalopt = []
909
- set = []
910
- @config.config_opt = []
911
- while i = ARGV.shift
912
- if /\A--?\z/ =~ i
913
- @config.config_opt = ARGV.dup
914
- break
915
- end
916
- name, value = *@config.parse_opt(i)
917
- if @config.value_config?(name)
918
- @config[name] = value
919
- else
920
- evalopt.push [name, value]
921
- end
922
- set.push name
923
- end
924
- evalopt.each do |name, value|
925
- @config.lookup(name).evaluate value, @config
926
- end
927
- # Check if configuration is valid
928
- set.each do |n|
929
- @config[n] if @config.value_config?(n)
930
- end
931
- end
932
-
933
- def parsearg_install
934
- @config.no_harm = false
935
- @config.install_prefix = ''
936
- while a = ARGV.shift
937
- case a
938
- when '--no-harm'
939
- @config.no_harm = true
940
- when /\A--prefix=/
941
- path = a.split(/=/, 2)[1]
942
- path = File.expand_path(path) unless path[0,1] == '/'
943
- @config.install_prefix = path
944
- else
945
- setup_rb_error "install: unknown option #{a}"
946
- end
947
- end
948
- end
949
-
950
- def print_usage(out)
951
- out.puts 'Typical Installation Procedure:'
952
- out.puts " $ ruby #{File.basename $0} config"
953
- out.puts " $ ruby #{File.basename $0} setup"
954
- out.puts " # ruby #{File.basename $0} install (may require root privilege)"
955
- out.puts
956
- out.puts 'Detailed Usage:'
957
- out.puts " ruby #{File.basename $0} <global option>"
958
- out.puts " ruby #{File.basename $0} [<global options>] <task> [<task options>]"
959
-
960
- fmt = " %-24s %s\n"
961
- out.puts
962
- out.puts 'Global options:'
963
- out.printf fmt, '-q,--quiet', 'suppress message outputs'
964
- out.printf fmt, ' --verbose', 'output messages verbosely'
965
- out.printf fmt, ' --help', 'print this message'
966
- out.printf fmt, ' --version', 'print version and quit'
967
- out.printf fmt, ' --copyright', 'print copyright and quit'
968
- out.puts
969
- out.puts 'Tasks:'
970
- TASKS.each do |name, desc|
971
- out.printf fmt, name, desc
972
- end
973
-
974
- fmt = " %-24s %s [%s]\n"
975
- out.puts
976
- out.puts 'Options for CONFIG or ALL:'
977
- @config.each do |item|
978
- out.printf fmt, item.help_opt, item.description, item.help_default
979
- end
980
- out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',"running ruby's"
981
- out.puts
982
- out.puts 'Options for INSTALL:'
983
- out.printf fmt, '--no-harm', 'only display what to do if given', 'off'
984
- out.printf fmt, '--prefix=path', 'install path prefix', ''
985
- out.puts
986
- end
987
-
988
- #
989
- # Task Handlers
990
- #
991
-
992
- def exec_config
993
- @installer.exec_config
994
- @config.save # must be final
995
- end
996
-
997
- def exec_setup
998
- @installer.exec_setup
999
- end
1000
-
1001
- def exec_install
1002
- @installer.exec_install
1003
- end
1004
-
1005
- def exec_test
1006
- @installer.exec_test
1007
- end
1008
-
1009
- def exec_show
1010
- @config.each do |i|
1011
- printf "%-20s %s\n", i.name, i.value if i.value?
1012
- end
1013
- end
1014
-
1015
- def exec_clean
1016
- @installer.exec_clean
1017
- end
1018
-
1019
- def exec_distclean
1020
- @installer.exec_distclean
1021
- end
1022
-
1023
- end # class ToplevelInstaller
1024
-
1025
-
1026
- class ToplevelInstallerMulti < ToplevelInstaller
1027
-
1028
- include FileOperations
1029
-
1030
- def initialize(ardir_root, config)
1031
- super
1032
- @packages = directories_of("#{@ardir}/packages")
1033
- raise 'no package exists' if @packages.empty?
1034
- @root_installer = Installer.new(@config, @ardir, File.expand_path('.'))
1035
- end
1036
-
1037
- def run_metaconfigs
1038
- @config.load_script "#{@ardir}/metaconfig", self
1039
- @packages.each do |name|
1040
- @config.load_script "#{@ardir}/packages/#{name}/metaconfig"
1041
- end
1042
- end
1043
-
1044
- attr_reader :packages
1045
-
1046
- def packages=(list)
1047
- raise 'package list is empty' if list.empty?
1048
- list.each do |name|
1049
- raise "directory packages/#{name} does not exist"\
1050
- unless File.dir?("#{@ardir}/packages/#{name}")
1051
- end
1052
- @packages = list
1053
- end
1054
-
1055
- def init_installers
1056
- @installers = {}
1057
- @packages.each do |pack|
1058
- @installers[pack] = Installer.new(@config,
1059
- "#{@ardir}/packages/#{pack}",
1060
- "packages/#{pack}")
1061
- end
1062
- with = extract_selection(config('with'))
1063
- without = extract_selection(config('without'))
1064
- @selected = @installers.keys.select {|name|
1065
- (with.empty? or with.include?(name)) \
1066
- and not without.include?(name)
1067
- }
1068
- end
1069
-
1070
- def extract_selection(list)
1071
- a = list.split(/,/)
1072
- a.each do |name|
1073
- setup_rb_error "no such package: #{name}" unless @installers.key?(name)
1074
- end
1075
- a
1076
- end
1077
-
1078
- def print_usage(f)
1079
- super
1080
- f.puts 'Inluded packages:'
1081
- f.puts ' ' + @packages.sort.join(' ')
1082
- f.puts
1083
- end
1084
-
1085
- #
1086
- # Task Handlers
1087
- #
1088
-
1089
- def exec_config
1090
- run_hook 'pre-config'
1091
- each_selected_installers {|inst| inst.exec_config }
1092
- run_hook 'post-config'
1093
- @config.save # must be final
1094
- end
1095
-
1096
- def exec_setup
1097
- run_hook 'pre-setup'
1098
- each_selected_installers {|inst| inst.exec_setup }
1099
- run_hook 'post-setup'
1100
- end
1101
-
1102
- def exec_install
1103
- run_hook 'pre-install'
1104
- each_selected_installers {|inst| inst.exec_install }
1105
- run_hook 'post-install'
1106
- end
1107
-
1108
- def exec_test
1109
- run_hook 'pre-test'
1110
- each_selected_installers {|inst| inst.exec_test }
1111
- run_hook 'post-test'
1112
- end
1113
-
1114
- def exec_clean
1115
- rm_f @config.savefile
1116
- run_hook 'pre-clean'
1117
- each_selected_installers {|inst| inst.exec_clean }
1118
- run_hook 'post-clean'
1119
- end
1120
-
1121
- def exec_distclean
1122
- rm_f @config.savefile
1123
- run_hook 'pre-distclean'
1124
- each_selected_installers {|inst| inst.exec_distclean }
1125
- run_hook 'post-distclean'
1126
- end
1127
-
1128
- #
1129
- # lib
1130
- #
1131
-
1132
- def each_selected_installers
1133
- Dir.mkdir 'packages' unless File.dir?('packages')
1134
- @selected.each do |pack|
1135
- $stderr.puts "Processing the package `#{pack}' ..." if verbose?
1136
- Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}")
1137
- Dir.chdir "packages/#{pack}"
1138
- yield @installers[pack]
1139
- Dir.chdir '../..'
1140
- end
1141
- end
1142
-
1143
- def run_hook(id)
1144
- @root_installer.run_hook id
1145
- end
1146
-
1147
- # module FileOperations requires this
1148
- def verbose?
1149
- @config.verbose?
1150
- end
1151
-
1152
- # module FileOperations requires this
1153
- def no_harm?
1154
- @config.no_harm?
1155
- end
1156
-
1157
- end # class ToplevelInstallerMulti
1158
-
1159
-
1160
- class Installer
1161
-
1162
- FILETYPES = %w( bin lib ext data conf man )
1163
-
1164
- include FileOperations
1165
- include HookScriptAPI
1166
-
1167
- def initialize(config, srcroot, objroot)
1168
- @config = config
1169
- @srcdir = File.expand_path(srcroot)
1170
- @objdir = File.expand_path(objroot)
1171
- @currdir = '.'
1172
- end
1173
-
1174
- def inspect
1175
- "#<#{self.class} #{File.basename(@srcdir)}>"
1176
- end
1177
-
1178
- def noop(rel)
1179
- end
1180
-
1181
- #
1182
- # Hook Script API base methods
1183
- #
1184
-
1185
- def srcdir_root
1186
- @srcdir
1187
- end
1188
-
1189
- def objdir_root
1190
- @objdir
1191
- end
1192
-
1193
- def relpath
1194
- @currdir
1195
- end
1196
-
1197
- #
1198
- # Config Access
1199
- #
1200
-
1201
- # module FileOperations requires this
1202
- def verbose?
1203
- @config.verbose?
1204
- end
1205
-
1206
- # module FileOperations requires this
1207
- def no_harm?
1208
- @config.no_harm?
1209
- end
1210
-
1211
- def verbose_off
1212
- begin
1213
- save, @config.verbose = @config.verbose?, false
1214
- yield
1215
- ensure
1216
- @config.verbose = save
1217
- end
1218
- end
1219
-
1220
- #
1221
- # TASK config
1222
- #
1223
-
1224
- def exec_config
1225
- exec_task_traverse 'config'
1226
- end
1227
-
1228
- alias config_dir_bin noop
1229
- alias config_dir_lib noop
1230
-
1231
- def config_dir_ext(rel)
1232
- extconf if extdir?(curr_srcdir())
1233
- end
1234
-
1235
- alias config_dir_data noop
1236
- alias config_dir_conf noop
1237
- alias config_dir_man noop
1238
-
1239
- def extconf
1240
- ruby "#{curr_srcdir()}/extconf.rb", *@config.config_opt
1241
- end
1242
-
1243
- #
1244
- # TASK setup
1245
- #
1246
-
1247
- def exec_setup
1248
- exec_task_traverse 'setup'
1249
- end
1250
-
1251
- def setup_dir_bin(rel)
1252
- files_of(curr_srcdir()).each do |fname|
1253
- update_shebang_line "#{curr_srcdir()}/#{fname}"
1254
- end
1255
- end
1256
-
1257
- alias setup_dir_lib noop
1258
-
1259
- def setup_dir_ext(rel)
1260
- make if extdir?(curr_srcdir())
1261
- end
1262
-
1263
- alias setup_dir_data noop
1264
- alias setup_dir_conf noop
1265
- alias setup_dir_man noop
1266
-
1267
- def update_shebang_line(path)
1268
- return if no_harm?
1269
- return if config('shebang') == 'never'
1270
- old = Shebang.load(path)
1271
- if old
1272
- $stderr.puts "warning: #{path}: Shebang line includes too many args. It is not portable and your program may not work." if old.args.size > 1
1273
- new = new_shebang(old)
1274
- return if new.to_s == old.to_s
1275
- else
1276
- return unless config('shebang') == 'all'
1277
- new = Shebang.new(config('rubypath'))
1278
- end
1279
- $stderr.puts "updating shebang: #{File.basename(path)}" if verbose?
1280
- open_atomic_writer(path) {|output|
1281
- File.open(path, 'rb') {|f|
1282
- f.gets if old # discard
1283
- output.puts new.to_s
1284
- output.print f.read
1285
- }
1286
- }
1287
- end
1288
-
1289
- def new_shebang(old)
1290
- if /\Aruby/ =~ File.basename(old.cmd)
1291
- Shebang.new(config('rubypath'), old.args)
1292
- elsif File.basename(old.cmd) == 'env' and old.args.first == 'ruby'
1293
- Shebang.new(config('rubypath'), old.args[1..-1])
1294
- else
1295
- return old unless config('shebang') == 'all'
1296
- Shebang.new(config('rubypath'))
1297
- end
1298
- end
1299
-
1300
- def open_atomic_writer(path, &block)
1301
- tmpfile = File.basename(path) + '.tmp'
1302
- begin
1303
- File.open(tmpfile, 'wb', &block)
1304
- File.rename tmpfile, File.basename(path)
1305
- ensure
1306
- File.unlink tmpfile if File.exist?(tmpfile)
1307
- end
1308
- end
1309
-
1310
- class Shebang
1311
- def Shebang.load(path)
1312
- line = nil
1313
- File.open(path) {|f|
1314
- line = f.gets
1315
- }
1316
- return nil unless /\A#!/ =~ line
1317
- parse(line)
1318
- end
1319
-
1320
- def Shebang.parse(line)
1321
- cmd, *args = *line.strip.sub(/\A\#!/, '').split(' ')
1322
- new(cmd, args)
1323
- end
1324
-
1325
- def initialize(cmd, args = [])
1326
- @cmd = cmd
1327
- @args = args
1328
- end
1329
-
1330
- attr_reader :cmd
1331
- attr_reader :args
1332
-
1333
- def to_s
1334
- "#! #{@cmd}" + (@args.empty? ? '' : " #{@args.join(' ')}")
1335
- end
1336
- end
1337
-
1338
- #
1339
- # TASK install
1340
- #
1341
-
1342
- def exec_install
1343
- rm_f 'InstalledFiles'
1344
- exec_task_traverse 'install'
1345
- end
1346
-
1347
- def install_dir_bin(rel)
1348
- install_files targetfiles(), "#{config('bindir')}/#{rel}", 0755
1349
- end
1350
-
1351
- def install_dir_lib(rel)
1352
- install_files libfiles(), "#{config('rbdir')}/#{rel}", 0644
1353
- end
1354
-
1355
- def install_dir_ext(rel)
1356
- return unless extdir?(curr_srcdir())
1357
- install_files rubyextentions('.'),
1358
- "#{config('sodir')}/#{File.dirname(rel)}",
1359
- 0555
1360
- end
1361
-
1362
- def install_dir_data(rel)
1363
- install_files targetfiles(), "#{config('datadir')}/#{rel}", 0644
1364
- end
1365
-
1366
- def install_dir_conf(rel)
1367
- # FIXME: should not remove current config files
1368
- # (rename previous file to .old/.org)
1369
- install_files targetfiles(), "#{config('sysconfdir')}/#{rel}", 0644
1370
- end
1371
-
1372
- def install_dir_man(rel)
1373
- install_files targetfiles(), "#{config('mandir')}/#{rel}", 0644
1374
- end
1375
-
1376
- def install_files(list, dest, mode)
1377
- mkdir_p dest, @config.install_prefix
1378
- list.each do |fname|
1379
- install fname, dest, mode, @config.install_prefix
1380
- end
1381
- end
1382
-
1383
- def libfiles
1384
- glob_reject(%w(*.y *.output), targetfiles())
1385
- end
1386
-
1387
- def rubyextentions(dir)
1388
- ents = glob_select("*.#{@config.dllext}", targetfiles())
1389
- if ents.empty?
1390
- setup_rb_error "no ruby extention exists: 'ruby #{$0} setup' first"
1391
- end
1392
- ents
1393
- end
1394
-
1395
- def targetfiles
1396
- mapdir(existfiles() - hookfiles())
1397
- end
1398
-
1399
- def mapdir(ents)
1400
- ents.map {|ent|
1401
- if File.exist?(ent)
1402
- then ent # objdir
1403
- else "#{curr_srcdir()}/#{ent}" # srcdir
1404
- end
1405
- }
1406
- end
1407
-
1408
- # picked up many entries from cvs-1.11.1/src/ignore.c
1409
- JUNK_FILES = %w(
1410
- core RCSLOG tags TAGS .make.state
1411
- .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb
1412
- *~ *.old *.bak *.BAK *.orig *.rej _$* *$
1413
-
1414
- *.org *.in .*
1415
- )
1416
-
1417
- def existfiles
1418
- glob_reject(JUNK_FILES, (files_of(curr_srcdir()) | files_of('.')))
1419
- end
1420
-
1421
- def hookfiles
1422
- %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt|
1423
- %w( config setup install clean ).map {|t| sprintf(fmt, t) }
1424
- }.flatten
1425
- end
1426
-
1427
- def glob_select(pat, ents)
1428
- re = globs2re([pat])
1429
- ents.select {|ent| re =~ ent }
1430
- end
1431
-
1432
- def glob_reject(pats, ents)
1433
- re = globs2re(pats)
1434
- ents.reject {|ent| re =~ ent }
1435
- end
1436
-
1437
- GLOB2REGEX = {
1438
- '.' => '\.',
1439
- '$' => '\$',
1440
- '#' => '\#',
1441
- '*' => '.*'
1442
- }
1443
-
1444
- def globs2re(pats)
1445
- /\A(?:#{
1446
- pats.map {|pat| pat.gsub(/[\.\$\#\*]/) {|ch| GLOB2REGEX[ch] } }.join('|')
1447
- })\z/
1448
- end
1449
-
1450
- #
1451
- # TASK test
1452
- #
1453
-
1454
- TESTDIR = 'test'
1455
-
1456
- def exec_test
1457
- unless File.directory?('test')
1458
- $stderr.puts 'no test in this package' if verbose?
1459
- return
1460
- end
1461
- $stderr.puts 'Running tests...' if verbose?
1462
- begin
1463
- require 'test/unit'
1464
- rescue LoadError
1465
- setup_rb_error 'test/unit cannot loaded. You need Ruby 1.8 or later to invoke this task.'
1466
- end
1467
- runner = Test::Unit::AutoRunner.new(true)
1468
- runner.to_run << TESTDIR
1469
- runner.run
1470
- end
1471
-
1472
- #
1473
- # TASK clean
1474
- #
1475
-
1476
- def exec_clean
1477
- exec_task_traverse 'clean'
1478
- rm_f @config.savefile
1479
- rm_f 'InstalledFiles'
1480
- end
1481
-
1482
- alias clean_dir_bin noop
1483
- alias clean_dir_lib noop
1484
- alias clean_dir_data noop
1485
- alias clean_dir_conf noop
1486
- alias clean_dir_man noop
1487
-
1488
- def clean_dir_ext(rel)
1489
- return unless extdir?(curr_srcdir())
1490
- make 'clean' if File.file?('Makefile')
1491
- end
1492
-
1493
- #
1494
- # TASK distclean
1495
- #
1496
-
1497
- def exec_distclean
1498
- exec_task_traverse 'distclean'
1499
- rm_f @config.savefile
1500
- rm_f 'InstalledFiles'
1501
- end
1502
-
1503
- alias distclean_dir_bin noop
1504
- alias distclean_dir_lib noop
1505
-
1506
- def distclean_dir_ext(rel)
1507
- return unless extdir?(curr_srcdir())
1508
- make 'distclean' if File.file?('Makefile')
1509
- end
1510
-
1511
- alias distclean_dir_data noop
1512
- alias distclean_dir_conf noop
1513
- alias distclean_dir_man noop
1514
-
1515
- #
1516
- # Traversing
1517
- #
1518
-
1519
- def exec_task_traverse(task)
1520
- run_hook "pre-#{task}"
1521
- FILETYPES.each do |type|
1522
- if type == 'ext' and config('without-ext') == 'yes'
1523
- $stderr.puts 'skipping ext/* by user option' if verbose?
1524
- next
1525
- end
1526
- traverse task, type, "#{task}_dir_#{type}"
1527
- end
1528
- run_hook "post-#{task}"
1529
- end
1530
-
1531
- def traverse(task, rel, mid)
1532
- dive_into(rel) {
1533
- run_hook "pre-#{task}"
1534
- __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '')
1535
- directories_of(curr_srcdir()).each do |d|
1536
- traverse task, "#{rel}/#{d}", mid
1537
- end
1538
- run_hook "post-#{task}"
1539
- }
1540
- end
1541
-
1542
- def dive_into(rel)
1543
- return unless File.dir?("#{@srcdir}/#{rel}")
1544
-
1545
- dir = File.basename(rel)
1546
- Dir.mkdir dir unless File.dir?(dir)
1547
- prevdir = Dir.pwd
1548
- Dir.chdir dir
1549
- $stderr.puts '---> ' + rel if verbose?
1550
- @currdir = rel
1551
- yield
1552
- Dir.chdir prevdir
1553
- $stderr.puts '<--- ' + rel if verbose?
1554
- @currdir = File.dirname(rel)
1555
- end
1556
-
1557
- def run_hook(id)
1558
- path = [ "#{curr_srcdir()}/#{id}",
1559
- "#{curr_srcdir()}/#{id}.rb" ].detect {|cand| File.file?(cand) }
1560
- return unless path
1561
- begin
1562
- instance_eval File.read(path), path, 1
1563
- rescue
1564
- raise if $DEBUG
1565
- setup_rb_error "hook #{path} failed:\n" + $!.message
1566
- end
1567
- end
1568
-
1569
- end # class Installer
1570
-
1571
-
1572
- class SetupError < StandardError; end
1573
-
1574
- def setup_rb_error(msg)
1575
- raise SetupError, msg
1576
- end
1577
-
1578
- if $0 == __FILE__
1579
- begin
1580
- ToplevelInstaller.invoke
1581
- rescue SetupError
1582
- raise if $DEBUG
1583
- $stderr.puts $!.message
1584
- $stderr.puts "Try 'ruby #{$0} --help' for detailed usage."
1585
- exit 1
1586
- end
1587
- end
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
1588
3
 
4
+ module RQR
5
+ require 'dl'
6
+ require "rqr/QR"
7
+ require "rqr/errors"
8
+ require "rqr/qrcode"
1589
9
  end