ruby-mp3info 0.6.16 → 0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
- #!/usr/bin/env ruby1.9
2
- # coding:utf-8
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
3
 
4
4
  $:.unshift("lib/")
5
5
 
@@ -10,7 +10,7 @@ require "tempfile"
10
10
  require "zlib"
11
11
  require "yaml"
12
12
 
13
- system("which id3v2 > /dev/null") || raise("id3v2 not found")
13
+ GOT_ID3V2 = system("which id3v2 > /dev/null")
14
14
 
15
15
  class Mp3InfoTest < Test::Unit::TestCase
16
16
 
@@ -36,20 +36,7 @@ class Mp3InfoTest < Test::Unit::TestCase
36
36
  "genre" => 233
37
37
  }
38
38
 
39
- FIXTURES = YAML::load_file( File.join(File.dirname(__FILE__), "fixtures.yml") )
40
-
41
39
  def setup
42
- # Command to create a gzip'ed dummy MP3
43
- # $ dd if=/dev/zero bs=1024 count=15 | \
44
- # lame --quiet --preset cbr 128 -r -s 44.1 --bitwidth 16 - - | \
45
- # ruby -rbase64 -rzlib -ryaml -e 'print(Zlib::Deflate.deflate($stdin.read)'
46
- # vbr:
47
- # $ dd if=/dev/zero of=#{tempfile.path} bs=1024 count=30000 |
48
- # system("lame -h -v -b 112 -r -s 44.1 --bitwidth 16 - /tmp/vbr.mp3
49
- @valid_mp3, @valid_mp3_2_2, @vbr_mp3 = %w{empty_mp3 2_2_tagged vbr}.collect do |fixture_key|
50
- Zlib::Inflate.inflate(FIXTURES[fixture_key])
51
- end
52
-
53
40
  @tag = {
54
41
  "title" => "title",
55
42
  "artist" => "artist",
@@ -60,7 +47,7 @@ class Mp3InfoTest < Test::Unit::TestCase
60
47
  "genre_s" => "Blues",
61
48
  "tracknum" => 36
62
49
  }
63
- File.open(TEMP_FILE, "w") { |f| f.write(@valid_mp3) }
50
+ load_fixture_to_temp_file("empty_mp3")
64
51
  end
65
52
 
66
53
  def teardown
@@ -94,7 +81,7 @@ class Mp3InfoTest < Test::Unit::TestCase
94
81
  end
95
82
 
96
83
  def test_vbr_mp3_length
97
- File.open(TEMP_FILE, "w") { |f| f.write(@vbr_mp3) }
84
+ load_fixture_to_temp_file("vbr")
98
85
 
99
86
  Mp3Info.open(TEMP_FILE) do |info|
100
87
  assert(info.vbr)
@@ -145,8 +132,7 @@ class Mp3InfoTest < Test::Unit::TestCase
145
132
 
146
133
  def id3_test(tag_str, valid_tag)
147
134
  tag = "TAG" + tag_str
148
- File.open(TEMP_FILE, "w") do |f|
149
- f.write(@valid_mp3)
135
+ File.open(TEMP_FILE, "a") do |f|
150
136
  f.write(tag)
151
137
  end
152
138
  assert(Mp3Info.hastag1?(TEMP_FILE))
@@ -156,7 +142,7 @@ class Mp3InfoTest < Test::Unit::TestCase
156
142
  end
157
143
 
158
144
  def test_removetag2
159
- w = write_tag2_to_temp_file({"TIT2" => "sdfqdsf"})
145
+ w = write_tag2_to_temp_file("TIT2" => "sdfqdsf")
160
146
 
161
147
  assert( Mp3Info.hastag2?(TEMP_FILE) )
162
148
  Mp3Info.removetag2(TEMP_FILE)
@@ -200,7 +186,7 @@ class Mp3InfoTest < Test::Unit::TestCase
200
186
 
201
187
  def test_id3v2_version
202
188
  written_tag = write_tag2_to_temp_file(DUMMY_TAG2)
203
- assert_equal( "2.#{ID3v2::WRITE_VERSION}.0", written_tag.version )
189
+ assert_equal( "2.3.0", written_tag.version )
204
190
  end
205
191
 
206
192
  def test_id3v2_methods
@@ -214,38 +200,42 @@ class Mp3InfoTest < Test::Unit::TestCase
214
200
  end
215
201
 
216
202
  def test_id3v2_basic
217
- w = write_tag2_to_temp_file(DUMMY_TAG2)
218
- assert_equal(DUMMY_TAG2, w)
219
- id3v2_prog_test(DUMMY_TAG2, w)
203
+ written_tag = write_tag2_to_temp_file(DUMMY_TAG2)
204
+ assert_equal(DUMMY_TAG2, written_tag)
205
+ id3v2_prog_test(DUMMY_TAG2, written_tag)
220
206
  end
221
207
 
222
208
  #test the tag with the "id3v2" program
223
209
  def id3v2_prog_test(tag, written_tag)
224
- return if RUBY_PLATFORM =~ /win32/
225
- return if `which id3v2`.empty?
210
+ return unless GOT_ID3V2
226
211
  start = false
227
212
  id3v2_output = {}
228
- `id3v2 -l #{TEMP_FILE}`.split(/\n/).each do |line|
213
+ =begin
214
+ id3v2 tag info for test/test_mp3info.mp3:
215
+ COMM (Comments): (~)[ENG]:
216
+ test/test_mp3info.mp3: No ID3v1 tag
217
+ =end
218
+ raw_output = `id3v2 -l #{TEMP_FILE}`
219
+ raw_output.split(/\n/).each do |line|
229
220
  if line =~ /^id3v2 tag info/
230
221
  start = true
231
222
  next
232
223
  end
233
224
  next unless start
234
- k, v = /^(.{4}) \(.+\): (.+)$/.match(line)[1,2]
235
- case k
236
- #COMM (Comments): ()[spa]: fmg
237
- when "COMM"
238
- v.sub!(/\(\)\[.{3}\]: (.+)/, '\1')
225
+ if match = /^(.{4}) \(.+\): (.+)$/.match(line)
226
+ k, v = match[1, 2]
227
+ case k
228
+ #COMM (Comments): ()[spa]: fmg
229
+ when "COMM"
230
+ v.sub!(/\(\)\[.{3}\]: (.+)/, '\1')
231
+ end
232
+ id3v2_output[k] = v
239
233
  end
240
- id3v2_output[k] = v
241
234
  end
242
235
 
243
236
  assert_equal( id3v2_output, written_tag, "id3v2 program output doesn't match")
244
237
  end
245
238
 
246
- def test_id3v2_trash
247
- end
248
-
249
239
  def test_id3v2_complex
250
240
  tag = {}
251
241
  #ID3v2::TAGS.keys.each do |k|
@@ -262,16 +252,13 @@ class Mp3InfoTest < Test::Unit::TestCase
262
252
  assert_equal(tag, write_tag2_to_temp_file(tag))
263
253
  end
264
254
 
265
- def test_infinite_loop_on_seek_to_v2_end
266
-
267
- end
268
-
269
255
  def test_leading_char_gets_chopped
270
256
  tag2 = DUMMY_TAG2.dup
271
257
  tag2["WOAR"] = "http://foo.bar"
272
258
  w = write_tag2_to_temp_file(tag2)
273
259
  assert_equal("http://foo.bar", w["WOAR"])
274
260
 
261
+ return unless GOT_ID3V2
275
262
  system(%(id3v2 --WOAR "http://foo.bar" "#{TEMP_FILE}"))
276
263
 
277
264
  Mp3Info.open(TEMP_FILE) do |mp3|
@@ -280,7 +267,7 @@ class Mp3InfoTest < Test::Unit::TestCase
280
267
  end
281
268
 
282
269
  def test_reading2_2_tags
283
- File.open(TEMP_FILE, "w") { |f| f.write(@valid_mp3_2_2) }
270
+ load_fixture_to_temp_file("2_2_tagged")
284
271
 
285
272
  Mp3Info.open(TEMP_FILE) do |mp3|
286
273
  assert_equal "2.2.0", mp3.tag2.version
@@ -313,7 +300,8 @@ class Mp3InfoTest < Test::Unit::TestCase
313
300
  end
314
301
 
315
302
  def test_writing_universal_tag_from_2_2_tags
316
- File.open(TEMP_FILE, "w") { |f| f.write(@valid_mp3_2_2) }
303
+ load_fixture_to_temp_file("2_2_tagged")
304
+
317
305
  Mp3Info.open(TEMP_FILE) do |mp3|
318
306
  mp3.tag.artist = "toto"
319
307
  mp3.tag.comments = "comments"
@@ -352,7 +340,7 @@ class Mp3InfoTest < Test::Unit::TestCase
352
340
  Mp3Info.open(fn) do |mp3|
353
341
  mp3.tag.title = fn
354
342
  mp3.flush
355
- if RUBY_VERSION < "1.9.0"
343
+ if RUBY_VERSION[0..2] == "1.8"
356
344
  assert_equal fn, mp3.tag.title
357
345
  else
358
346
  assert_equal fn, mp3.tag.title.force_encoding("utf-8")
@@ -363,58 +351,6 @@ class Mp3InfoTest < Test::Unit::TestCase
363
351
  end
364
352
  end
365
353
 
366
- def test_validity_of_id3v2_options
367
- info = Mp3Info.new(TEMP_FILE)
368
- expected_hash = { :lang => "ENG", :encoding => "iso-8859-1" }
369
- assert_equal( expected_hash, info.tag2.options)
370
-
371
- assert_raises(ArgumentError) do
372
- Mp3Info.new(TEMP_FILE, :encoding => "bad encoding")
373
- end
374
- end
375
-
376
- def test_encoding_read
377
- Mp3Info.open(TEMP_FILE) do |mp3|
378
- mp3.tag2['TEST'] = "all\xe9"
379
- end
380
-
381
- Mp3Info.open(TEMP_FILE, :encoding => "utf-8") do |mp3|
382
- assert_equal "allé", mp3.tag2['TEST']
383
- end
384
-
385
- Mp3Info.open(TEMP_FILE, :encoding => "iso-8859-1") do |mp3|
386
- if RUBY_VERSION < "1.9.0"
387
- assert_equal "all\xe9", mp3.tag2['TEST']
388
- else
389
- assert_equal "all\xe9".force_encoding("binary"), mp3.tag2['TEST']
390
- end
391
- end
392
- end
393
-
394
- def test_encoding_write
395
- Mp3Info.open(TEMP_FILE, :encoding => 'utf-8') do |mp3|
396
- mp3.tag2['TEST'] = "all\xc3\xa9"
397
- end
398
-
399
- Mp3Info.open(TEMP_FILE, :encoding => "iso-8859-1") do |mp3|
400
- if RUBY_VERSION < "1.9.0"
401
- assert_equal "all\xe9", mp3.tag2['TEST']
402
- else
403
- assert_equal "all\xe9".force_encoding("iso-8859-1"), mp3.tag2['TEST']
404
- end
405
- end
406
- end
407
-
408
- =begin
409
- def test_should_raises_exception_when_writing_badly_encoded_frames
410
- assert_raises(Iconv::Failure) do
411
- Mp3Info.open(TEMP_FILE, :encoding => 'utf-8') do |mp3|
412
- mp3.tag2['TEST'] = "all\xc3"
413
- end
414
- end
415
- end
416
- =end
417
-
418
354
  def test_audio_content
419
355
  require "digest/md5"
420
356
 
@@ -441,7 +377,7 @@ class Mp3InfoTest < Test::Unit::TestCase
441
377
  end
442
378
 
443
379
  def test_audio_content_problematic
444
- File.open(TEMP_FILE, "w") { |f| f.write(FIXTURES["audio_content_fixture"]) }
380
+ load_fixture_to_temp_file("audio_content_fixture", false)
445
381
  Mp3Info.open(TEMP_FILE) do |mp3|
446
382
  expected_pos = 150
447
383
  audio_content_pos, audio_content_size = mp3.audio_content
@@ -452,9 +388,7 @@ class Mp3InfoTest < Test::Unit::TestCase
452
388
 
453
389
  def test_headerless_vbr_file
454
390
  mp3_length = 3
455
- # this will generate a 15 sec mp3 file (44100hz*16bit*2channels) = 60/4 = 15
456
- system("dd if=/dev/urandom bs=44100 count=#{mp3_length*4} 2>/dev/null | \
457
- lame -v -m s --vbr-new --preset 128 -r -s 44.1 --bitwidth 16 - - > #{TEMP_FILE} 2>/dev/null")
391
+ load_fixture_to_temp_file("small_vbr_mp3")
458
392
 
459
393
  Mp3Info.open(TEMP_FILE) do |mp3|
460
394
  assert mp3.vbr
@@ -555,6 +489,29 @@ class Mp3InfoTest < Test::Unit::TestCase
555
489
  io
556
490
  end
557
491
 
492
+ FIXTURES = YAML::load_file( File.join(File.dirname(__FILE__), "fixtures.yml") )
493
+
494
+ def load_fixture_to_temp_file(fixture_key, zlibed = true)
495
+ # Command to create a gzip'ed dummy MP3
496
+ # $ dd if=/dev/zero bs=1024 count=15 | \
497
+ # lame --quiet --preset cbr 128 -r -s 44.1 --bitwidth 16 - - | \
498
+ # ruby -rbase64 -rzlib -ryaml -e 'print(Zlib::Deflate.deflate($stdin.read)'
499
+ # vbr:
500
+ # $ dd if=/dev/zero of=#{tempfile.path} bs=1024 count=30000 |
501
+ # system("lame -h -v -b 112 -r -s 44.1 --bitwidth 16 - /tmp/vbr.mp3
502
+ #
503
+ # this will generate a #{mp3_length} sec mp3 file (44100hz*16bit*2channels) = 60/4 = 15
504
+ # system("dd if=/dev/urandom bs=44100 count=#{mp3_length*4} 2>/dev/null | \
505
+ # lame -v -m s --vbr-new --preset 128 -r -s 44.1 --bitwidth 16 - - > #{TEMP_FILE} 2>/dev/null")
506
+ content = FIXTURES[fixture_key]
507
+ if zlibed
508
+ content = Zlib::Inflate.inflate(content)
509
+ end
510
+
511
+ File.open(TEMP_FILE, "w") do |f|
512
+ f.write(content)
513
+ end
514
+ end
558
515
  =begin
559
516
 
560
517
  def test_encoder
metadata CHANGED
@@ -1,94 +1,86 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: ruby-mp3info
3
- version: !ruby/object:Gem::Version
4
- hash: 39
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.7'
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 6
9
- - 16
10
- version: 0.6.16
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Guillaume Pierronnet
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-11-10 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
21
- name: hoe
12
+ date: 2012-03-02 00:00:00.000000000 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rdoc
17
+ requirement: &79955210 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: '3.10'
23
+ type: :development
22
24
  prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
25
+ version_requirements: *79955210
26
+ - !ruby/object:Gem::Dependency
27
+ name: hoe
28
+ requirement: &79954780 !ruby/object:Gem::Requirement
24
29
  none: false
25
- requirements:
30
+ requirements:
26
31
  - - ~>
27
- - !ruby/object:Gem::Version
28
- hash: 23
29
- segments:
30
- - 2
31
- - 10
32
- version: "2.10"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.12'
33
34
  type: :development
34
- version_requirements: *id001
35
- description: |-
36
- ruby-mp3info read low-level informations and manipulate tags on
37
- mp3 files.
38
- email:
39
- - moumar@rubyforge.org
40
- executables: []
35
+ prerelease: false
36
+ version_requirements: *79954780
37
+ description: ! 'ruby-mp3info read low-level informations and manipulate tags on
41
38
 
39
+ mp3 files.'
40
+ email:
41
+ - guillaume.pierronnet@gmail.com
42
+ executables: []
42
43
  extensions: []
43
-
44
- extra_rdoc_files:
44
+ extra_rdoc_files:
45
45
  - History.txt
46
46
  - Manifest.txt
47
47
  - README.txt
48
- files:
48
+ files:
49
49
  - History.txt
50
50
  - Manifest.txt
51
51
  - README.txt
52
52
  - Rakefile
53
- - install.rb
54
53
  - lib/mp3info.rb
55
54
  - lib/mp3info/extension_modules.rb
56
55
  - lib/mp3info/id3v2.rb
57
56
  - test/test_ruby-mp3info.rb
58
57
  - .gemtest
58
+ has_rdoc: true
59
59
  homepage: http://github.com/moumar/ruby-mp3info
60
60
  licenses: []
61
-
62
61
  post_install_message:
63
- rdoc_options:
62
+ rdoc_options:
64
63
  - --main
65
64
  - README.txt
66
- require_paths:
65
+ require_paths:
67
66
  - lib
68
- required_ruby_version: !ruby/object:Gem::Requirement
67
+ required_ruby_version: !ruby/object:Gem::Requirement
69
68
  none: false
70
- requirements:
71
- - - ">="
72
- - !ruby/object:Gem::Version
73
- hash: 3
74
- segments:
75
- - 0
76
- version: "0"
77
- required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
74
  none: false
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- hash: 3
83
- segments:
84
- - 0
85
- version: "0"
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
86
79
  requirements: []
87
-
88
80
  rubyforge_project: ruby-mp3info
89
- rubygems_version: 1.8.10
81
+ rubygems_version: 1.6.2
90
82
  signing_key:
91
83
  specification_version: 3
92
84
  summary: ruby-mp3info read low-level informations and manipulate tags on mp3 files.
93
- test_files:
85
+ test_files:
94
86
  - test/test_ruby-mp3info.rb
data/install.rb DELETED
@@ -1,1022 +0,0 @@
1
- #
2
- # This file is automatically generated. DO NOT MODIFY!
3
- #
4
- # install.rb
5
- #
6
- # Copyright (c) 2000-2002 Minero Aoki <aamine@loveruby.net>
7
- #
8
- # This program is free software.
9
- # You can distribute/modify this program under the terms of
10
- # the GNU Lesser General Public License version 2.
11
- #
12
-
13
- ### begin compat.rb
14
-
15
- unless Enumerable.instance_methods.include? 'inject'
16
- module Enumerable
17
- def inject( result )
18
- each do |i|
19
- result = yield(result, i)
20
- end
21
- result
22
- end
23
- end
24
- end
25
-
26
- def File.read_all( fname )
27
- File.open(fname, 'rb') {|f| return f.read }
28
- end
29
-
30
- def File.write( fname, str )
31
- File.open(fname, 'wb') {|f| f.write str }
32
- end
33
-
34
- ### end compat.rb
35
- ### begin config.rb
36
-
37
- if i = ARGV.index(/\A--rbconfig=/)
38
- file = $'
39
- ARGV.delete_at(i)
40
- require file
41
- else
42
- require 'rbconfig'
43
- end
44
-
45
-
46
- class ConfigTable
47
-
48
- c = ::Config::CONFIG
49
-
50
- rubypath = c['bindir'] + '/' + c['ruby_install_name']
51
-
52
- major = c['MAJOR'].to_i
53
- minor = c['MINOR'].to_i
54
- teeny = c['TEENY'].to_i
55
- version = "#{major}.#{minor}"
56
-
57
- # ruby ver. >= 1.4.4?
58
- newpath_p = ((major >= 2) or
59
- ((major == 1) and
60
- ((minor >= 5) or
61
- ((minor == 4) and (teeny >= 4)))))
62
-
63
- re = Regexp.new('\A' + Regexp.quote(c['prefix']))
64
- subprefix = lambda {|path|
65
- re === path and path.sub(re, '$prefix')
66
- }
67
-
68
- if c['rubylibdir']
69
- # V < 1.6.3
70
- stdruby = subprefix.call(c['rubylibdir'])
71
- siteruby = subprefix.call(c['sitedir'])
72
- versite = subprefix.call(c['sitelibdir'])
73
- sodir = subprefix.call(c['sitearchdir'])
74
- elsif newpath_p
75
- # 1.4.4 <= V <= 1.6.3
76
- stdruby = "$prefix/lib/ruby/#{version}"
77
- siteruby = subprefix.call(c['sitedir'])
78
- versite = siteruby + '/' + version
79
- sodir = "$site-ruby/#{c['arch']}"
80
- else
81
- # V < 1.4.4
82
- stdruby = "$prefix/lib/ruby/#{version}"
83
- siteruby = "$prefix/lib/ruby/#{version}/site_ruby"
84
- versite = siteruby
85
- sodir = "$site-ruby/#{c['arch']}"
86
- end
87
-
88
- DESCRIPTER = [
89
- [ 'prefix', [ c['prefix'],
90
- 'path',
91
- 'path prefix of target environment' ] ],
92
- [ 'std-ruby', [ stdruby,
93
- 'path',
94
- 'the directory for standard ruby libraries' ] ],
95
- [ 'site-ruby-common', [ siteruby,
96
- 'path',
97
- 'the directory for version-independent non-standard ruby libraries' ] ],
98
- [ 'site-ruby', [ versite,
99
- 'path',
100
- 'the directory for non-standard ruby libraries' ] ],
101
- [ 'bin-dir', [ '$prefix/bin',
102
- 'path',
103
- 'the directory for commands' ] ],
104
- [ 'rb-dir', [ '$site-ruby',
105
- 'path',
106
- 'the directory for ruby scripts' ] ],
107
- [ 'so-dir', [ sodir,
108
- 'path',
109
- 'the directory for ruby extentions' ] ],
110
- [ 'data-dir', [ '$prefix/share',
111
- 'path',
112
- 'the directory for shared data' ] ],
113
- [ 'ruby-path', [ rubypath,
114
- 'path',
115
- 'path to set to #! line' ] ],
116
- [ 'ruby-prog', [ rubypath,
117
- 'name',
118
- 'the ruby program using for installation' ] ],
119
- [ 'make-prog', [ 'make',
120
- 'name',
121
- 'the make program to compile ruby extentions' ] ],
122
- [ 'without-ext', [ 'no',
123
- 'yes/no',
124
- 'does not compile/install ruby extentions' ] ]
125
- ]
126
-
127
- SAVE_FILE = 'config.save'
128
-
129
- def ConfigTable.each_name( &block )
130
- keys().each(&block)
131
- end
132
-
133
- def ConfigTable.keys
134
- DESCRIPTER.collect {|k,*dummy| k }
135
- end
136
-
137
- def ConfigTable.each_definition( &block )
138
- DESCRIPTER.each(&block)
139
- end
140
-
141
- def ConfigTable.get_entry( name )
142
- name, ent = DESCRIPTER.assoc(name)
143
- ent
144
- end
145
-
146
- def ConfigTable.get_entry!( name )
147
- get_entry(name) or raise ArgumentError, "no such config: #{name}"
148
- end
149
-
150
- def ConfigTable.add_entry( name, vals )
151
- ConfigTable::DESCRIPTER.push [name,vals]
152
- end
153
-
154
- def ConfigTable.remove_entry( name )
155
- get_entry name or raise ArgumentError, "no such config: #{name}"
156
- DESCRIPTER.delete_if {|n,arr| n == name }
157
- end
158
-
159
- def ConfigTable.config_key?( name )
160
- get_entry(name) ? true : false
161
- end
162
-
163
- def ConfigTable.bool_config?( name )
164
- ent = get_entry(name) or return false
165
- ent[1] == 'yes/no'
166
- end
167
-
168
- def ConfigTable.value_config?( name )
169
- ent = get_entry(name) or return false
170
- ent[1] != 'yes/no'
171
- end
172
-
173
- def ConfigTable.path_config?( name )
174
- ent = get_entry(name) or return false
175
- ent[1] == 'path'
176
- end
177
-
178
-
179
- class << self
180
-
181
- alias newobj new
182
-
183
- def new
184
- c = newobj()
185
- c.__send__ :init
186
- c
187
- end
188
-
189
- def load
190
- c = newobj()
191
- raise InstallError, "#{File.basename $0} config first"\
192
- unless File.file? SAVE_FILE
193
- File.foreach(SAVE_FILE) do |line|
194
- k, v = line.split(/=/, 2)
195
- c.instance_eval {
196
- @table[k] = v.strip
197
- }
198
- end
199
- c
200
- end
201
-
202
- end
203
-
204
- def initialize
205
- @table = {}
206
- end
207
-
208
- def init
209
- DESCRIPTER.each do |k, (default, vname, desc, default2)|
210
- @table[k] = default
211
- end
212
- end
213
- private :init
214
-
215
- def save
216
- File.open(SAVE_FILE, 'w') {|f|
217
- @table.each do |k, v|
218
- f.printf "%s=%s\n", k, v if v
219
- end
220
- }
221
- end
222
-
223
- def []=( k, v )
224
- ConfigTable.config_key? k or raise InstallError, "unknown config option #{k}"
225
- if ConfigTable.path_config? k
226
- @table[k] = (v[0,1] != '$') ? File.expand_path(v) : v
227
- else
228
- @table[k] = v
229
- end
230
- end
231
-
232
- def []( key )
233
- @table[key] or return nil
234
- @table[key].gsub(%r<\$([^/]+)>) { self[$1] }
235
- end
236
-
237
- def set_raw( key, val )
238
- @table[key] = val
239
- end
240
-
241
- def get_raw( key )
242
- @table[key]
243
- end
244
-
245
- end
246
-
247
-
248
- class MetaConfigEnvironment
249
-
250
- def self.eval_file( file )
251
- return unless File.file? file
252
- new.instance_eval File.read_all(file), file, 1
253
- end
254
-
255
- private
256
-
257
- def config_names
258
- ConfigTable.keys
259
- end
260
-
261
- def config?( name )
262
- ConfigTable.config_key? name
263
- end
264
-
265
- def bool_config?( name )
266
- ConfigTable.bool_config? name
267
- end
268
-
269
- def value_config?( name )
270
- ConfigTable.value_config? name
271
- end
272
-
273
- def path_config?( name )
274
- ConfigTable.path_config? name
275
- end
276
-
277
- def add_config( name, argname, default, desc )
278
- ConfigTable.add_entry name,[default,argname,desc]
279
- end
280
-
281
- def add_path_config( name, default, desc )
282
- add_config name, 'path', default, desc
283
- end
284
-
285
- def add_bool_config( name, default, desc )
286
- add_config name, 'yes/no', default ? 'yes' : 'no', desc
287
- end
288
-
289
- def set_config_default( name, default )
290
- if bool_config? name
291
- ConfigTable.get_entry!(name)[0] = default ? 'yes' : 'no'
292
- else
293
- ConfigTable.get_entry!(name)[0] = default
294
- end
295
- end
296
-
297
- def remove_config( name )
298
- ent = ConfigTable.get_entry(name)
299
- ConfigTable.remove_entry name
300
- ent
301
- end
302
-
303
- end
304
-
305
- ### end config.rb
306
- ### begin fileop.rb
307
-
308
- module FileOperations
309
-
310
- def mkdir_p( dname, prefix = nil )
311
- dname = prefix + dname if prefix
312
- $stderr.puts "mkdir -p #{dname}" if verbose?
313
- return if no_harm?
314
-
315
- # does not check '/'... it's too abnormal case
316
- dirs = dname.split(%r<(?=/)>)
317
- if /\A[a-z]:\z/i === dirs[0]
318
- disk = dirs.shift
319
- dirs[0] = disk + dirs[0]
320
- end
321
- dirs.each_index do |idx|
322
- path = dirs[0..idx].join('')
323
- Dir.mkdir path unless dir? path
324
- end
325
- end
326
-
327
- def rm_f( fname )
328
- $stderr.puts "rm -f #{fname}" if verbose?
329
- return if no_harm?
330
-
331
- if File.exist? fname or File.symlink? fname
332
- File.chmod 0777, fname
333
- File.unlink fname
334
- end
335
- end
336
-
337
- def rm_rf( dn )
338
- $stderr.puts "rm -rf #{dn}" if verbose?
339
- return if no_harm?
340
-
341
- Dir.chdir dn
342
- Dir.foreach('.') do |fn|
343
- next if fn == '.'
344
- next if fn == '..'
345
- if dir? fn
346
- verbose_off {
347
- rm_rf fn
348
- }
349
- else
350
- verbose_off {
351
- rm_f fn
352
- }
353
- end
354
- end
355
- Dir.chdir '..'
356
- Dir.rmdir dn
357
- end
358
-
359
- def mv( src, dest )
360
- rm_f dest
361
- begin
362
- File.link src, dest
363
- rescue
364
- File.write dest, File.read_all(src)
365
- File.chmod File.stat(src).mode, dest
366
- end
367
- rm_f src
368
- end
369
-
370
- def install( from, dest, mode, prefix = nil )
371
- $stderr.puts "install #{from} #{dest}" if verbose?
372
- return if no_harm?
373
-
374
- realdest = prefix + dest if prefix
375
- if dir? realdest
376
- realdest += '/' + File.basename(from)
377
- end
378
- str = File.read_all(from)
379
- if diff? str, realdest
380
- verbose_off {
381
- rm_f realdest if File.exist? realdest
382
- }
383
- File.write realdest, str
384
- File.chmod mode, realdest
385
-
386
- File.open(objdir + '/InstalledFiles', 'a') {|f| f.puts realdest }
387
- end
388
- end
389
-
390
- def diff?( orig, targ )
391
- return true unless File.exist? targ
392
- orig != File.read_all(targ)
393
- end
394
-
395
- def command( str )
396
- $stderr.puts str if verbose?
397
- system str or raise RuntimeError, "'system #{str}' failed"
398
- end
399
-
400
- def ruby( str )
401
- command config('ruby-prog') + ' ' + str
402
- end
403
-
404
- def dir?( dname )
405
- # for corrupted windows stat()
406
- File.directory?((dname[-1,1] == '/') ? dname : dname + '/')
407
- end
408
-
409
- def all_files( dname )
410
- Dir.open(dname) {|d|
411
- return d.find_all {|n| File.file? "#{dname}/#{n}" }
412
- }
413
- end
414
-
415
- def all_dirs( dname )
416
- Dir.open(dname) {|d|
417
- return d.find_all {|n| dir? "#{dname}/#{n}" } - %w(. ..)
418
- }
419
- end
420
-
421
- end
422
-
423
- ### end fileop.rb
424
- ### begin base.rb
425
-
426
- class InstallError < StandardError; end
427
-
428
-
429
- class Installer
430
-
431
- Version = '3.1.3'
432
- Copyright = 'Copyright (c) 2000-2002 Minero Aoki'
433
-
434
-
435
- @toplevel = nil
436
-
437
- def self.declear_toplevel_installer( inst )
438
- @toplevel and
439
- raise ArgumentError, 'more than one toplevel installer decleared'
440
- @toplevel = inst
441
- end
442
-
443
- def self.toplevel_installer
444
- @toplevel
445
- end
446
-
447
-
448
- FILETYPES = %w( bin lib ext data )
449
-
450
- include FileOperations
451
-
452
- def initialize( config, opt, srcroot, objroot )
453
- @config = config
454
- @options = opt
455
- @srcdir = File.expand_path(srcroot)
456
- @objdir = File.expand_path(objroot)
457
- @currdir = '.'
458
- end
459
-
460
- def inspect
461
- "#<#{self.class} #{__id__}>"
462
- end
463
-
464
- #
465
- # configs/options
466
- #
467
-
468
- def get_config( key )
469
- @config[key]
470
- end
471
-
472
- alias config get_config
473
-
474
- def set_config( key, val )
475
- @config[key] = val
476
- end
477
-
478
- def no_harm?
479
- @options['no-harm']
480
- end
481
-
482
- def verbose?
483
- @options['verbose']
484
- end
485
-
486
- def verbose_off
487
- save, @options['verbose'] = @options['verbose'], false
488
- yield
489
- @options['verbose'] = save
490
- end
491
-
492
- #
493
- # srcdir/objdir
494
- #
495
-
496
- attr_reader :srcdir
497
- alias srcdir_root srcdir
498
- alias package_root srcdir
499
-
500
- def curr_srcdir
501
- "#{@srcdir}/#{@currdir}"
502
- end
503
-
504
- attr_reader :objdir
505
- alias objdir_root objdir
506
-
507
- def curr_objdir
508
- "#{@objdir}/#{@currdir}"
509
- end
510
-
511
- def srcfile( path )
512
- curr_srcdir + '/' + path
513
- end
514
-
515
- def srcexist?( path )
516
- File.exist? srcfile(path)
517
- end
518
-
519
- def srcdirectory?( path )
520
- dir? srcfile(path)
521
- end
522
-
523
- def srcfile?( path )
524
- File.file? srcfile(path)
525
- end
526
-
527
- def srcentries( path = '.' )
528
- Dir.open(curr_srcdir + '/' + path) {|d|
529
- return d.to_a - %w(. ..) - hookfilenames
530
- }
531
- end
532
-
533
- def srcfiles( path = '.' )
534
- srcentries(path).find_all {|fname|
535
- File.file? File.join(curr_srcdir, path, fname)
536
- }
537
- end
538
-
539
- def srcdirectories( path = '.' )
540
- srcentries(path).find_all {|fname|
541
- dir? File.join(curr_srcdir, path, fname)
542
- }
543
- end
544
-
545
- def dive_into( rel )
546
- return unless dir? "#{@srcdir}/#{rel}"
547
-
548
- dir = File.basename(rel)
549
- Dir.mkdir dir unless dir? dir
550
- save = Dir.pwd
551
- Dir.chdir dir
552
- $stderr.puts '---> ' + rel if verbose?
553
- @currdir = rel
554
- yield
555
- Dir.chdir save
556
- $stderr.puts '<--- ' + rel if verbose?
557
- @currdir = File.dirname(rel)
558
- end
559
-
560
- #
561
- # config
562
- #
563
-
564
- def exec_config
565
- exec_task_traverse 'config'
566
- end
567
-
568
- def config_dir_bin( rel )
569
- end
570
-
571
- def config_dir_lib( rel )
572
- end
573
-
574
- def config_dir_ext( rel )
575
- extconf if extdir? curr_srcdir
576
- end
577
-
578
- def extconf
579
- opt = @options['config-opt'].join(' ')
580
- command "#{config('ruby-prog')} #{curr_srcdir}/extconf.rb #{opt}"
581
- end
582
-
583
- def config_dir_data( rel )
584
- end
585
-
586
- #
587
- # setup
588
- #
589
-
590
- def exec_setup
591
- exec_task_traverse 'setup'
592
- end
593
-
594
- def setup_dir_bin( relpath )
595
- all_files(curr_srcdir).each do |fname|
596
- add_rubypath "#{curr_srcdir}/#{fname}"
597
- end
598
- end
599
-
600
- SHEBANG_RE = /\A\#!\s*\S*ruby\S*/
601
-
602
- def add_rubypath( path )
603
- $stderr.puts %Q<set #! line to "\#!#{config('ruby-path')}" for #{path} ...> if verbose?
604
- return if no_harm?
605
-
606
- tmpfile = File.basename(path) + '.tmp'
607
- begin
608
- File.open(path) {|r|
609
- File.open(tmpfile, 'w') {|w|
610
- first = r.gets
611
- return unless SHEBANG_RE === first # reject '/usr/bin/env ruby'
612
-
613
- w.print first.sub(SHEBANG_RE, '#!' + config('ruby-path'))
614
- w.write r.read
615
- } }
616
- mv tmpfile, File.basename(path)
617
- ensure
618
- rm_f tmpfile if File.exist? tmpfile
619
- end
620
- end
621
-
622
- def setup_dir_lib( relpath )
623
- end
624
-
625
- def setup_dir_ext( relpath )
626
- make if extdir?(curr_srcdir)
627
- end
628
-
629
- def make
630
- command config('make-prog')
631
- end
632
-
633
- def setup_dir_data( relpath )
634
- end
635
-
636
- #
637
- # install
638
- #
639
-
640
- def exec_install
641
- exec_task_traverse 'install'
642
- end
643
-
644
- def install_dir_bin( rel )
645
- install_files targfiles, config('bin-dir') + '/' + rel, 0755
646
- end
647
-
648
- def install_dir_lib( rel )
649
- install_files targfiles, config('rb-dir') + '/' + rel, 0644
650
- end
651
-
652
- def install_dir_ext( rel )
653
- install_dir_ext_main File.dirname(rel) if extdir?(curr_srcdir)
654
- end
655
-
656
- def install_dir_ext_main( rel )
657
- install_files allext('.'), config('so-dir') + '/' + rel, 0555
658
- end
659
-
660
- def install_dir_data( rel )
661
- install_files targfiles, config('data-dir') + '/' + rel, 0644
662
- end
663
-
664
- def install_files( list, dest, mode )
665
- mkdir_p dest, @options['install-prefix']
666
- list.each do |fname|
667
- install fname, dest, mode, @options['install-prefix']
668
- end
669
- end
670
-
671
- def targfiles
672
- (targfilenames() - hookfilenames()).collect {|fname|
673
- File.exist?(fname) ? fname : File.join(curr_srcdir(), fname)
674
- }
675
- end
676
-
677
- def targfilenames
678
- [ curr_srcdir(), '.' ].inject([]) {|ret, dir|
679
- ret | all_files(dir)
680
- }
681
- end
682
-
683
- def hookfilenames
684
- %w( pre-%s post-%s pre-%s.rb post-%s.rb ).collect {|fmt|
685
- %w( config setup install clean ).collect {|t| sprintf fmt, t }
686
- }.flatten
687
- end
688
-
689
- def allext( dir )
690
- _allext(dir) or raise InstallError,
691
- "no extention exists: Have you done 'ruby #{$0} setup' ?"
692
- end
693
-
694
- DLEXT = /\.#{ ::Config::CONFIG['DLEXT'] }\z/
695
-
696
- def _allext( dir )
697
- Dir.open(dir) {|d|
698
- return d.find_all {|fname| DLEXT === fname }
699
- }
700
- end
701
-
702
- #
703
- # clean
704
- #
705
-
706
- def exec_clean
707
- exec_task_traverse 'clean'
708
- rm_f 'config.save'
709
- rm_f 'InstalledFiles'
710
- end
711
-
712
- def clean_dir_bin( rel )
713
- end
714
-
715
- def clean_dir_lib( rel )
716
- end
717
-
718
- def clean_dir_ext( rel )
719
- clean
720
- end
721
-
722
- def clean
723
- command config('make-prog') + ' clean' if File.file? 'Makefile'
724
- end
725
-
726
- def clean_dir_data( rel )
727
- end
728
-
729
- #
730
- # lib
731
- #
732
-
733
- def exec_task_traverse( task )
734
- run_hook 'pre-' + task
735
- FILETYPES.each do |type|
736
- if config('without-ext') == 'yes' and type == 'ext'
737
- $stderr.puts 'skipping ext/* by user option' if verbose?
738
- next
739
- end
740
- traverse task, type, task + '_dir_' + type
741
- end
742
- run_hook 'post-' + task
743
- end
744
-
745
- def traverse( task, rel, mid )
746
- dive_into(rel) {
747
- run_hook 'pre-' + task
748
- __send__ mid, rel.sub(%r_\A.*?(?:/|\z)_, '')
749
- all_dirs(curr_srcdir).each do |d|
750
- traverse task, rel + '/' + d, mid
751
- end
752
- run_hook 'post-' + task
753
- }
754
- end
755
-
756
- def run_hook( name )
757
- try_run_hook curr_srcdir + '/' + name or
758
- try_run_hook curr_srcdir + '/' + name + '.rb'
759
- end
760
-
761
- def try_run_hook( fname )
762
- return false unless File.file? fname
763
-
764
- env = self.dup
765
- begin
766
- env.instance_eval File.read_all(fname), fname, 1
767
- rescue
768
- raise InstallError, "hook #{fname} failed:\n" + $!.message
769
- end
770
- true
771
- end
772
-
773
- def extdir?( dir )
774
- File.exist? dir + '/MANIFEST'
775
- end
776
-
777
- end
778
-
779
- ### end base.rb
780
- ### begin toplevel.rb
781
-
782
- class ToplevelInstaller < Installer
783
-
784
- TASKS = [
785
- [ 'config', 'saves your configurations' ],
786
- [ 'show', 'shows current configuration' ],
787
- [ 'setup', 'compiles extention or else' ],
788
- [ 'install', 'installs files' ],
789
- [ 'clean', "does `make clean' for each extention" ]
790
- ]
791
-
792
-
793
- def initialize( root )
794
- super nil, {'verbose' => true}, root, '.'
795
- Installer.declear_toplevel_installer self
796
- end
797
-
798
-
799
- def execute
800
- run_metaconfigs
801
-
802
- case task = parsearg_global()
803
- when 'config'
804
- @config = ConfigTable.new
805
- else
806
- @config = ConfigTable.load
807
- end
808
- parsearg_TASK task
809
-
810
- exectask task
811
- end
812
-
813
-
814
- def run_metaconfigs
815
- MetaConfigEnvironment.eval_file "#{srcdir_root()}/#{metaconfig()}"
816
- end
817
-
818
- def metaconfig
819
- 'metaconfig'
820
- end
821
-
822
-
823
- def exectask( task )
824
- if task == 'show'
825
- exec_show
826
- else
827
- try task
828
- end
829
- end
830
-
831
- def try( task )
832
- $stderr.printf "#{File.basename $0}: entering %s phase...\n", task if verbose?
833
- begin
834
- __send__ 'exec_' + task
835
- rescue
836
- $stderr.printf "%s failed\n", task
837
- raise
838
- end
839
- $stderr.printf "#{File.basename $0}: %s done.\n", task if verbose?
840
- end
841
-
842
- #
843
- # processing arguments
844
- #
845
-
846
- def parsearg_global
847
- task_re = /\A(?:#{TASKS.collect {|i| i[0] }.join '|'})\z/
848
-
849
- while arg = ARGV.shift
850
- case arg
851
- when /\A\w+\z/
852
- task_re === arg or raise InstallError, "wrong task: #{arg}"
853
- return arg
854
-
855
- when '-q', '--quiet'
856
- @options['verbose'] = false
857
-
858
- when '--verbose'
859
- @options['verbose'] = true
860
-
861
- when '-h', '--help'
862
- print_usage $stdout
863
- exit 0
864
-
865
- when '-v', '--version'
866
- puts "#{File.basename $0} version #{Version}"
867
- exit 0
868
-
869
- when '--copyright'
870
- puts Copyright
871
- exit 0
872
-
873
- else
874
- raise InstallError, "unknown global option '#{arg}'"
875
- end
876
- end
877
-
878
- raise InstallError, "No task or global option given.
879
- Typical installation procedure is:
880
- $ ruby #{File.basename $0} config
881
- $ ruby #{File.basename $0} setup
882
- # ruby #{File.basename $0} install (may require root privilege)
883
- "
884
- end
885
-
886
-
887
- def parsearg_TASK( task )
888
- mid = "parsearg_#{task}"
889
- if respond_to? mid, true
890
- __send__ mid
891
- else
892
- ARGV.empty? or
893
- raise InstallError, "#{task}: unknown options: #{ARGV.join ' '}"
894
- end
895
- end
896
-
897
- def parsearg_config
898
- re = /\A--(#{ConfigTable.keys.join '|'})(?:=(.*))?\z/
899
- @options['config-opt'] = []
900
-
901
- while i = ARGV.shift
902
- if /\A--?\z/ === i
903
- @options['config-opt'] = ARGV.dup
904
- break
905
- end
906
- m = re.match(i) or raise InstallError, "config: unknown option #{i}"
907
- name, value = m.to_a[1,2]
908
- if value
909
- if ConfigTable.bool_config?(name)
910
- /\A(y(es)?|n(o)?|t(rue)?|f(alse))\z/i === value or raise InstallError, "config: --#{name} allows only yes/no for argument"
911
- value = (/\Ay(es)?|\At(rue)/i === value) ? 'yes' : 'no'
912
- end
913
- else
914
- ConfigTable.bool_config?(name) or raise InstallError, "config: --#{name} requires argument"
915
- value = 'yes'
916
- end
917
- @config[name] = value
918
- end
919
- end
920
-
921
- def parsearg_install
922
- @options['no-harm'] = false
923
- @options['install-prefix'] = ''
924
- while a = ARGV.shift
925
- case a
926
- when /\A--no-harm\z/
927
- @options['no-harm'] = true
928
- when /\A--prefix=(.*)\z/
929
- path = $1
930
- path = File.expand_path(path) unless path[0,1] == '/'
931
- @options['install-prefix'] = path
932
- else
933
- raise InstallError, "install: unknown option #{a}"
934
- end
935
- end
936
- end
937
-
938
-
939
- def print_usage( out )
940
- out.puts 'Typical Installation Procedure:'
941
- out.puts " $ ruby #{File.basename $0} config"
942
- out.puts " $ ruby #{File.basename $0} setup"
943
- out.puts " # ruby #{File.basename $0} install (may require root privilege)"
944
- out.puts
945
- out.puts 'Detailed Usage:'
946
- out.puts " ruby #{File.basename $0} <global option>"
947
- out.puts " ruby #{File.basename $0} [<global options>] <task> [<task options>]"
948
-
949
- fmt = " %-20s %s\n"
950
- out.puts
951
- out.puts 'Global options:'
952
- out.printf fmt, '-q,--quiet', 'suppress message outputs'
953
- out.printf fmt, ' --verbose', 'output messages verbosely'
954
- out.printf fmt, '-h,--help', 'print this message'
955
- out.printf fmt, '-v,--version', 'print version and quit'
956
- out.printf fmt, ' --copyright', 'print copyright and quit'
957
-
958
- out.puts
959
- out.puts 'Tasks:'
960
- TASKS.each do |name, desc|
961
- out.printf " %-10s %s\n", name, desc
962
- end
963
-
964
- out.puts
965
- out.puts 'Options for config:'
966
- ConfigTable.each_definition do |name, (default, arg, desc, default2)|
967
- out.printf " %-20s %s [%s]\n",
968
- '--'+ name + (ConfigTable.bool_config?(name) ? '' : '='+arg),
969
- desc,
970
- default2 || default
971
- end
972
- out.printf " %-20s %s [%s]\n",
973
- '--rbconfig=path', 'your rbconfig.rb to load', "running ruby's"
974
-
975
- out.puts
976
- out.puts 'Options for install:'
977
- out.printf " %-20s %s [%s]\n",
978
- '--no-harm', 'only display what to do if given', 'off'
979
- out.printf " %-20s %s [%s]\n",
980
- '--prefix', 'install path prefix', '$prefix'
981
-
982
- out.puts
983
- end
984
-
985
- #
986
- # config
987
- #
988
-
989
- def exec_config
990
- super
991
- @config.save
992
- end
993
-
994
- #
995
- # show
996
- #
997
-
998
- def exec_show
999
- ConfigTable.each_name do |k|
1000
- v = @config.get_raw(k)
1001
- if not v or v.empty?
1002
- v = '(not specified)'
1003
- end
1004
- printf "%-10s %s\n", k, v
1005
- end
1006
- end
1007
-
1008
- end
1009
-
1010
- ### end toplevel.rb
1011
-
1012
- if $0 == __FILE__
1013
- begin
1014
- installer = ToplevelInstaller.new(File.dirname($0))
1015
- installer.execute
1016
- rescue
1017
- raise if $DEBUG
1018
- $stderr.puts $!.message
1019
- $stderr.puts "Try 'ruby #{$0} --help' for detailed usage."
1020
- exit 1
1021
- end
1022
- end