sqlite3-ruby 1.3.2 → 1.3.3.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. metadata +25 -100
  2. data/API_CHANGES.rdoc +0 -50
  3. data/CHANGELOG.rdoc +0 -171
  4. data/ChangeLog.cvs +0 -88
  5. data/LICENSE +0 -27
  6. data/Manifest.txt +0 -50
  7. data/README.rdoc +0 -74
  8. data/Rakefile +0 -10
  9. data/ext/sqlite3/backup.c +0 -164
  10. data/ext/sqlite3/backup.h +0 -15
  11. data/ext/sqlite3/database.c +0 -762
  12. data/ext/sqlite3/database.h +0 -15
  13. data/ext/sqlite3/exception.c +0 -94
  14. data/ext/sqlite3/exception.h +0 -8
  15. data/ext/sqlite3/extconf.rb +0 -43
  16. data/ext/sqlite3/sqlite3.c +0 -36
  17. data/ext/sqlite3/sqlite3_ruby.h +0 -44
  18. data/ext/sqlite3/statement.c +0 -419
  19. data/ext/sqlite3/statement.h +0 -16
  20. data/faq/faq.rb +0 -145
  21. data/faq/faq.yml +0 -426
  22. data/lib/sqlite3.rb +0 -10
  23. data/lib/sqlite3/constants.rb +0 -49
  24. data/lib/sqlite3/database.rb +0 -587
  25. data/lib/sqlite3/errors.rb +0 -44
  26. data/lib/sqlite3/pragmas.rb +0 -280
  27. data/lib/sqlite3/resultset.rb +0 -126
  28. data/lib/sqlite3/statement.rb +0 -148
  29. data/lib/sqlite3/translator.rb +0 -118
  30. data/lib/sqlite3/value.rb +0 -57
  31. data/lib/sqlite3/version.rb +0 -25
  32. data/setup.rb +0 -1333
  33. data/tasks/faq.rake +0 -9
  34. data/tasks/gem.rake +0 -31
  35. data/tasks/native.rake +0 -61
  36. data/tasks/vendor_sqlite3.rake +0 -104
  37. data/test/helper.rb +0 -3
  38. data/test/test_backup.rb +0 -33
  39. data/test/test_collation.rb +0 -82
  40. data/test/test_database.rb +0 -312
  41. data/test/test_database_readonly.rb +0 -29
  42. data/test/test_deprecated.rb +0 -33
  43. data/test/test_encoding.rb +0 -119
  44. data/test/test_integration.rb +0 -544
  45. data/test/test_integration_open_close.rb +0 -30
  46. data/test/test_integration_pending.rb +0 -115
  47. data/test/test_integration_resultset.rb +0 -156
  48. data/test/test_integration_statement.rb +0 -194
  49. data/test/test_sqlite3.rb +0 -9
  50. data/test/test_statement.rb +0 -207
  51. data/test/test_statement_execute.rb +0 -35
@@ -1,148 +0,0 @@
1
- require 'sqlite3/errors'
2
- require 'sqlite3/resultset'
3
-
4
- class String
5
- def to_blob
6
- SQLite3::Blob.new( self )
7
- end
8
- end
9
-
10
- module SQLite3
11
- # A statement represents a prepared-but-unexecuted SQL query. It will rarely
12
- # (if ever) be instantiated directly by a client, and is most often obtained
13
- # via the Database#prepare method.
14
- class Statement
15
- include Enumerable
16
-
17
- # This is any text that followed the first valid SQL statement in the text
18
- # with which the statement was initialized. If there was no trailing text,
19
- # this will be the empty string.
20
- attr_reader :remainder
21
-
22
- # Binds the given variables to the corresponding placeholders in the SQL
23
- # text.
24
- #
25
- # See Database#execute for a description of the valid placeholder
26
- # syntaxes.
27
- #
28
- # Example:
29
- #
30
- # stmt = db.prepare( "select * from table where a=? and b=?" )
31
- # stmt.bind_params( 15, "hello" )
32
- #
33
- # See also #execute, #bind_param, Statement#bind_param, and
34
- # Statement#bind_params.
35
- def bind_params( *bind_vars )
36
- index = 1
37
- bind_vars.flatten.each do |var|
38
- if Hash === var
39
- var.each { |key, val| bind_param key, val }
40
- else
41
- bind_param index, var
42
- index += 1
43
- end
44
- end
45
- end
46
-
47
- # Execute the statement. This creates a new ResultSet object for the
48
- # statement's virtual machine. If a block was given, the new ResultSet will
49
- # be yielded to it; otherwise, the ResultSet will be returned.
50
- #
51
- # Any parameters will be bound to the statement using #bind_params.
52
- #
53
- # Example:
54
- #
55
- # stmt = db.prepare( "select * from table" )
56
- # stmt.execute do |result|
57
- # ...
58
- # end
59
- #
60
- # See also #bind_params, #execute!.
61
- def execute( *bind_vars )
62
- reset! if active? || done?
63
-
64
- bind_params(*bind_vars) unless bind_vars.empty?
65
- @results = ResultSet.new(@connection, self)
66
-
67
- step if 0 == column_count
68
-
69
- yield @results if block_given?
70
- @results
71
- end
72
-
73
- # Execute the statement. If no block was given, this returns an array of
74
- # rows returned by executing the statement. Otherwise, each row will be
75
- # yielded to the block.
76
- #
77
- # Any parameters will be bound to the statement using #bind_params.
78
- #
79
- # Example:
80
- #
81
- # stmt = db.prepare( "select * from table" )
82
- # stmt.execute! do |row|
83
- # ...
84
- # end
85
- #
86
- # See also #bind_params, #execute.
87
- def execute!( *bind_vars, &block )
88
- execute(*bind_vars)
89
- block_given? ? each(&block) : to_a
90
- end
91
-
92
- # Returns true if the statement is currently active, meaning it has an
93
- # open result set.
94
- def active?
95
- !done?
96
- end
97
-
98
- # Return an array of the column names for this statement. Note that this
99
- # may execute the statement in order to obtain the metadata; this makes it
100
- # a (potentially) expensive operation.
101
- def columns
102
- get_metadata unless @columns
103
- return @columns
104
- end
105
-
106
- def each
107
- loop do
108
- val = step
109
- break self if done?
110
- yield val
111
- end
112
- end
113
-
114
- # Return an array of the data types for each column in this statement. Note
115
- # that this may execute the statement in order to obtain the metadata; this
116
- # makes it a (potentially) expensive operation.
117
- def types
118
- must_be_open!
119
- get_metadata unless @types
120
- @types
121
- end
122
-
123
- # A convenience method for obtaining the metadata about the query. Note
124
- # that this will actually execute the SQL, which means it can be a
125
- # (potentially) expensive operation.
126
- def get_metadata
127
- @columns = []
128
- @types = []
129
-
130
- column_count.times do |column|
131
- @columns << column_name(column)
132
- @types << column_decltype(column)
133
- end
134
-
135
- @columns.freeze
136
- @types.freeze
137
- end
138
- private :get_metadata
139
-
140
- # Performs a sanity check to ensure that the statement is not
141
- # closed. If it is, an exception is raised.
142
- def must_be_open! # :nodoc:
143
- if closed?
144
- raise SQLite3::Exception, "cannot use a closed statement"
145
- end
146
- end
147
- end
148
- end
@@ -1,118 +0,0 @@
1
- require 'time'
2
- require 'date'
3
-
4
- module SQLite3
5
-
6
- # The Translator class encapsulates the logic and callbacks necessary for
7
- # converting string data to a value of some specified type. Every Database
8
- # instance may have a Translator instance, in order to assist in type
9
- # translation (Database#type_translation).
10
- #
11
- # Further, applications may define their own custom type translation logic
12
- # by registering translator blocks with the corresponding database's
13
- # translator instance (Database#translator).
14
- class Translator
15
-
16
- # Create a new Translator instance. It will be preinitialized with default
17
- # translators for most SQL data types.
18
- def initialize
19
- @translators = Hash.new( proc { |type,value| value } )
20
- @type_name_cache = {}
21
- register_default_translators
22
- end
23
-
24
- # Add a new translator block, which will be invoked to process type
25
- # translations to the given type. The type should be an SQL datatype, and
26
- # may include parentheses (i.e., "VARCHAR(30)"). However, any parenthetical
27
- # information is stripped off and discarded, so type translation decisions
28
- # are made solely on the "base" type name.
29
- #
30
- # The translator block itself should accept two parameters, "type" and
31
- # "value". In this case, the "type" is the full type name (including
32
- # parentheses), so the block itself may include logic for changing how a
33
- # type is translated based on the additional data. The "value" parameter
34
- # is the (string) data to convert.
35
- #
36
- # The block should return the translated value.
37
- def add_translator( type, &block ) # :yields: type, value
38
- warn(<<-eowarn) if $VERBOSE
39
- #{caller[0]} is calling `add_translator`.
40
- Built in translators are deprecated and will be removed in version 2.0.0
41
- eowarn
42
- @translators[ type_name( type ) ] = block
43
- end
44
-
45
- # Translate the given string value to a value of the given type. In the
46
- # absense of an installed translator block for the given type, the value
47
- # itself is always returned. Further, +nil+ values are never translated,
48
- # and are always passed straight through regardless of the type parameter.
49
- def translate( type, value )
50
- unless value.nil?
51
- # FIXME: this is a hack to support Sequel
52
- if type && %w{ datetime timestamp }.include?(type.downcase)
53
- @translators[ type_name( type ) ].call( type, value.to_s )
54
- else
55
- @translators[ type_name( type ) ].call( type, value )
56
- end
57
- end
58
- end
59
-
60
- # A convenience method for working with type names. This returns the "base"
61
- # type name, without any parenthetical data.
62
- def type_name( type )
63
- @type_name_cache[type] ||= begin
64
- type = "" if type.nil?
65
- type = $1 if type =~ /^(.*?)\(/
66
- type.upcase
67
- end
68
- end
69
- private :type_name
70
-
71
- # Register the default translators for the current Translator instance.
72
- # This includes translators for most major SQL data types.
73
- def register_default_translators
74
- [ "time",
75
- "timestamp" ].each { |type| add_translator( type ) { |t, v| Time.parse( v ) } }
76
-
77
- add_translator( "date" ) { |t,v| Date.parse(v) }
78
- add_translator( "datetime" ) { |t,v| DateTime.parse(v) }
79
-
80
- [ "decimal",
81
- "float",
82
- "numeric",
83
- "double",
84
- "real",
85
- "dec",
86
- "fixed" ].each { |type| add_translator( type ) { |t,v| v.to_f } }
87
-
88
- [ "integer",
89
- "smallint",
90
- "mediumint",
91
- "int",
92
- "bigint" ].each { |type| add_translator( type ) { |t,v| v.to_i } }
93
-
94
- [ "bit",
95
- "bool",
96
- "boolean" ].each do |type|
97
- add_translator( type ) do |t,v|
98
- !( v.strip.gsub(/00+/,"0") == "0" ||
99
- v.downcase == "false" ||
100
- v.downcase == "f" ||
101
- v.downcase == "no" ||
102
- v.downcase == "n" )
103
- end
104
- end
105
-
106
- add_translator( "tinyint" ) do |type, value|
107
- if type =~ /\(\s*1\s*\)/
108
- value.to_i == 1
109
- else
110
- value.to_i
111
- end
112
- end
113
- end
114
- private :register_default_translators
115
-
116
- end
117
-
118
- end
@@ -1,57 +0,0 @@
1
- require 'sqlite3/constants'
2
-
3
- module SQLite3
4
-
5
- class Value
6
- attr_reader :handle
7
-
8
- def initialize( db, handle )
9
- @driver = db.driver
10
- @handle = handle
11
- end
12
-
13
- def null?
14
- type == :null
15
- end
16
-
17
- def to_blob
18
- @driver.value_blob( @handle )
19
- end
20
-
21
- def length( utf16=false )
22
- if utf16
23
- @driver.value_bytes16( @handle )
24
- else
25
- @driver.value_bytes( @handle )
26
- end
27
- end
28
-
29
- def to_f
30
- @driver.value_double( @handle )
31
- end
32
-
33
- def to_i
34
- @driver.value_int( @handle )
35
- end
36
-
37
- def to_int64
38
- @driver.value_int64( @handle )
39
- end
40
-
41
- def to_s( utf16=false )
42
- @driver.value_text( @handle, utf16 )
43
- end
44
-
45
- def type
46
- case @driver.value_type( @handle )
47
- when Constants::ColumnType::INTEGER then :int
48
- when Constants::ColumnType::FLOAT then :float
49
- when Constants::ColumnType::TEXT then :text
50
- when Constants::ColumnType::BLOB then :blob
51
- when Constants::ColumnType::NULL then :null
52
- end
53
- end
54
-
55
- end
56
-
57
- end
@@ -1,25 +0,0 @@
1
- module SQLite3
2
-
3
- VERSION = '1.3.2'
4
-
5
- module VersionProxy
6
-
7
- MAJOR = 1
8
- MINOR = 3
9
- TINY = 1
10
- BUILD = nil
11
-
12
- STRING = [ MAJOR, MINOR, TINY, BUILD ].compact.join( "." )
13
- #:beta-tag:
14
-
15
- VERSION = ::SQLite3::VERSION
16
- end
17
-
18
- def self.const_missing(name)
19
- return super unless name == :Version
20
- warn(<<-eowarn) if $VERBOSE
21
- #{caller[0]}: SQLite::Version will be removed in sqlite3-ruby version 2.0.0
22
- eowarn
23
- VersionProxy
24
- end
25
- end
data/setup.rb DELETED
@@ -1,1333 +0,0 @@
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 LGPL, 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
- select {|i| not yield(i) }
37
- end
38
- end
39
- end
40
-
41
- unless Enumerable.method_defined?(:inject)
42
- module Enumerable
43
- def inject(result)
44
- each do |i|
45
- result = yield(result, i)
46
- end
47
- result
48
- end
49
- end
50
- end
51
-
52
- unless Enumerable.method_defined?(:any?)
53
- module Enumerable
54
- def any?
55
- each do |i|
56
- return true if yield(i)
57
- end
58
- false
59
- end
60
- end
61
- end
62
-
63
- unless File.respond_to?(:read)
64
- def File.read(fname)
65
- open(fname) {|f|
66
- return f.read
67
- }
68
- end
69
- end
70
-
71
- #
72
- # Application independent utilities
73
- #
74
-
75
- def File.binread(fname)
76
- open(fname, 'rb') {|f|
77
- return f.read
78
- }
79
- end
80
-
81
- # for corrupted windows stat(2)
82
- def File.dir?(path)
83
- File.directory?((path[-1,1] == '/') ? path : path + '/')
84
- end
85
-
86
- #
87
- # Config
88
- #
89
-
90
- if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg }
91
- ARGV.delete(arg)
92
- require arg.split(/=/, 2)[1]
93
- $".push 'rbconfig.rb'
94
- else
95
- require 'rbconfig'
96
- end
97
-
98
- def multipackage_install?
99
- FileTest.directory?(File.dirname($0) + '/packages')
100
- end
101
-
102
-
103
- class ConfigTable
104
-
105
- c = ::Config::CONFIG
106
-
107
- rubypath = c['bindir'] + '/' + c['ruby_install_name']
108
-
109
- major = c['MAJOR'].to_i
110
- minor = c['MINOR'].to_i
111
- teeny = c['TEENY'].to_i
112
- version = "#{major}.#{minor}"
113
-
114
- # ruby ver. >= 1.4.4?
115
- newpath_p = ((major >= 2) or
116
- ((major == 1) and
117
- ((minor >= 5) or
118
- ((minor == 4) and (teeny >= 4)))))
119
-
120
- subprefix = lambda {|path|
121
- path.sub(/\A#{Regexp.quote(c['prefix'])}/o, '$prefix')
122
- }
123
-
124
- if c['rubylibdir']
125
- # V < 1.6.3
126
- stdruby = subprefix.call(c['rubylibdir'])
127
- siteruby = subprefix.call(c['sitedir'])
128
- versite = subprefix.call(c['sitelibdir'])
129
- sodir = subprefix.call(c['sitearchdir'])
130
- elsif newpath_p
131
- # 1.4.4 <= V <= 1.6.3
132
- stdruby = "$prefix/lib/ruby/#{version}"
133
- siteruby = subprefix.call(c['sitedir'])
134
- versite = siteruby + '/' + version
135
- sodir = "$site-ruby/#{c['arch']}"
136
- else
137
- # V < 1.4.4
138
- stdruby = "$prefix/lib/ruby/#{version}"
139
- siteruby = "$prefix/lib/ruby/#{version}/site_ruby"
140
- versite = siteruby
141
- sodir = "$site-ruby/#{c['arch']}"
142
- end
143
-
144
- if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg }
145
- makeprog = arg.sub(/'/, '').split(/=/, 2)[1]
146
- else
147
- makeprog = 'make'
148
- end
149
-
150
- common_descripters = [
151
- [ 'prefix', [ c['prefix'],
152
- 'path',
153
- 'path prefix of target environment' ] ],
154
- [ 'std-ruby', [ stdruby,
155
- 'path',
156
- 'the directory for standard ruby libraries' ] ],
157
- [ 'site-ruby-common', [ siteruby,
158
- 'path',
159
- 'the directory for version-independent non-standard ruby libraries' ] ],
160
- [ 'site-ruby', [ versite,
161
- 'path',
162
- 'the directory for non-standard ruby libraries' ] ],
163
- [ 'bin-dir', [ '$prefix/bin',
164
- 'path',
165
- 'the directory for commands' ] ],
166
- [ 'rb-dir', [ '$site-ruby',
167
- 'path',
168
- 'the directory for ruby scripts' ] ],
169
- [ 'so-dir', [ sodir,
170
- 'path',
171
- 'the directory for ruby extentions' ] ],
172
- [ 'data-dir', [ '$prefix/share',
173
- 'path',
174
- 'the directory for shared data' ] ],
175
- [ 'ruby-path', [ rubypath,
176
- 'path',
177
- 'path to set to #! line' ] ],
178
- [ 'ruby-prog', [ rubypath,
179
- 'name',
180
- 'the ruby program using for installation' ] ],
181
- [ 'make-prog', [ makeprog,
182
- 'name',
183
- 'the make program to compile ruby extentions' ] ],
184
- [ 'without-ext', [ 'no',
185
- 'yes/no',
186
- 'does not compile/install ruby extentions' ] ]
187
- ]
188
- multipackage_descripters = [
189
- [ 'with', [ '',
190
- 'name,name...',
191
- 'package names that you want to install',
192
- 'ALL' ] ],
193
- [ 'without', [ '',
194
- 'name,name...',
195
- 'package names that you do not want to install',
196
- 'NONE' ] ]
197
- ]
198
- if multipackage_install?
199
- DESCRIPTER = common_descripters + multipackage_descripters
200
- else
201
- DESCRIPTER = common_descripters
202
- end
203
-
204
- SAVE_FILE = '.config'
205
-
206
- def ConfigTable.each_name(&block)
207
- keys().each(&block)
208
- end
209
-
210
- def ConfigTable.keys
211
- DESCRIPTER.map {|name, *dummy| name }
212
- end
213
-
214
- def ConfigTable.each_definition(&block)
215
- DESCRIPTER.each(&block)
216
- end
217
-
218
- def ConfigTable.get_entry(name)
219
- name, ent = DESCRIPTER.assoc(name)
220
- ent
221
- end
222
-
223
- def ConfigTable.get_entry!(name)
224
- get_entry(name) or raise ArgumentError, "no such config: #{name}"
225
- end
226
-
227
- def ConfigTable.add_entry(name, vals)
228
- ConfigTable::DESCRIPTER.push [name,vals]
229
- end
230
-
231
- def ConfigTable.remove_entry(name)
232
- get_entry(name) or raise ArgumentError, "no such config: #{name}"
233
- DESCRIPTER.delete_if {|n, arr| n == name }
234
- end
235
-
236
- def ConfigTable.config_key?(name)
237
- get_entry(name) ? true : false
238
- end
239
-
240
- def ConfigTable.bool_config?(name)
241
- ent = get_entry(name) or return false
242
- ent[1] == 'yes/no'
243
- end
244
-
245
- def ConfigTable.value_config?(name)
246
- ent = get_entry(name) or return false
247
- ent[1] != 'yes/no'
248
- end
249
-
250
- def ConfigTable.path_config?(name)
251
- ent = get_entry(name) or return false
252
- ent[1] == 'path'
253
- end
254
-
255
-
256
- class << self
257
- alias newobj new
258
- end
259
-
260
- def ConfigTable.new
261
- c = newobj()
262
- c.initialize_from_table
263
- c
264
- end
265
-
266
- def ConfigTable.load
267
- c = newobj()
268
- c.initialize_from_file
269
- c
270
- end
271
-
272
- def initialize_from_table
273
- @table = {}
274
- DESCRIPTER.each do |k, (default, vname, desc, default2)|
275
- @table[k] = default
276
- end
277
- end
278
-
279
- def initialize_from_file
280
- raise InstallError, "#{File.basename $0} config first"\
281
- unless File.file?(SAVE_FILE)
282
- @table = {}
283
- File.foreach(SAVE_FILE) do |line|
284
- k, v = line.split(/=/, 2)
285
- @table[k] = v.strip
286
- end
287
- end
288
-
289
- def save
290
- File.open(SAVE_FILE, 'w') {|f|
291
- @table.each do |k, v|
292
- f.printf "%s=%s\n", k, v if v
293
- end
294
- }
295
- end
296
-
297
- def []=(k, v)
298
- raise InstallError, "unknown config option #{k}"\
299
- unless ConfigTable.config_key?(k)
300
- @table[k] = v
301
- end
302
-
303
- def [](key)
304
- return nil unless @table[key]
305
- @table[key].gsub(%r<\$([^/]+)>) { self[$1] }
306
- end
307
-
308
- def set_raw(key, val)
309
- @table[key] = val
310
- end
311
-
312
- def get_raw(key)
313
- @table[key]
314
- end
315
-
316
- end
317
-
318
-
319
- module MetaConfigAPI
320
-
321
- def eval_file_ifexist(fname)
322
- instance_eval File.read(fname), fname, 1 if File.file?(fname)
323
- end
324
-
325
- def config_names
326
- ConfigTable.keys
327
- end
328
-
329
- def config?(name)
330
- ConfigTable.config_key?(name)
331
- end
332
-
333
- def bool_config?(name)
334
- ConfigTable.bool_config?(name)
335
- end
336
-
337
- def value_config?(name)
338
- ConfigTable.value_config?(name)
339
- end
340
-
341
- def path_config?(name)
342
- ConfigTable.path_config?(name)
343
- end
344
-
345
- def add_config(name, argname, default, desc)
346
- ConfigTable.add_entry name,[default,argname,desc]
347
- end
348
-
349
- def add_path_config(name, default, desc)
350
- add_config name, 'path', default, desc
351
- end
352
-
353
- def add_bool_config(name, default, desc)
354
- add_config name, 'yes/no', default ? 'yes' : 'no', desc
355
- end
356
-
357
- def set_config_default(name, default)
358
- if bool_config?(name)
359
- ConfigTable.get_entry!(name)[0] = (default ? 'yes' : 'no')
360
- else
361
- ConfigTable.get_entry!(name)[0] = default
362
- end
363
- end
364
-
365
- def remove_config(name)
366
- ent = ConfigTable.get_entry(name)
367
- ConfigTable.remove_entry name
368
- ent
369
- end
370
-
371
- end
372
-
373
- #
374
- # File Operations
375
- #
376
-
377
- module FileOperations
378
-
379
- def mkdir_p(dirname, prefix = nil)
380
- dirname = prefix + dirname if prefix
381
- $stderr.puts "mkdir -p #{dirname}" if verbose?
382
- return if no_harm?
383
-
384
- # does not check '/'... it's too abnormal case
385
- dirs = dirname.split(%r<(?=/)>)
386
- if /\A[a-z]:\z/i =~ dirs[0]
387
- disk = dirs.shift
388
- dirs[0] = disk + dirs[0]
389
- end
390
- dirs.each_index do |idx|
391
- path = dirs[0..idx].join('')
392
- Dir.mkdir path unless File.dir?(path)
393
- end
394
- end
395
-
396
- def rm_f(fname)
397
- $stderr.puts "rm -f #{fname}" if verbose?
398
- return if no_harm?
399
-
400
- if File.exist?(fname) or File.symlink?(fname)
401
- File.chmod 0777, fname
402
- File.unlink fname
403
- end
404
- end
405
-
406
- def rm_rf(dn)
407
- $stderr.puts "rm -rf #{dn}" if verbose?
408
- return if no_harm?
409
-
410
- Dir.chdir dn
411
- Dir.foreach('.') do |fn|
412
- next if fn == '.'
413
- next if fn == '..'
414
- if File.dir?(fn)
415
- verbose_off {
416
- rm_rf fn
417
- }
418
- else
419
- verbose_off {
420
- rm_f fn
421
- }
422
- end
423
- end
424
- Dir.chdir '..'
425
- Dir.rmdir dn
426
- end
427
-
428
- def move_file(src, dest)
429
- File.unlink dest if File.exist?(dest)
430
- begin
431
- File.rename src, dest
432
- rescue
433
- File.open(dest, 'wb') {|f| f.write File.binread(src) }
434
- File.chmod File.stat(src).mode, dest
435
- File.unlink src
436
- end
437
- end
438
-
439
- def install(from, dest, mode, prefix = nil)
440
- $stderr.puts "install #{from} #{dest}" if verbose?
441
- return if no_harm?
442
-
443
- realdest = prefix ? prefix + dest : dest
444
- realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest)
445
- str = File.binread(from)
446
- if diff?(str, realdest)
447
- verbose_off {
448
- rm_f realdest if File.exist?(realdest)
449
- }
450
- File.open(realdest, 'wb') {|f|
451
- f.write str
452
- }
453
- File.chmod mode, realdest
454
-
455
- File.open("#{objdir_root()}/InstalledFiles", 'a') {|f|
456
- if prefix
457
- f.puts realdest.sub(prefix, '')
458
- else
459
- f.puts realdest
460
- end
461
- }
462
- end
463
- end
464
-
465
- def diff?(new_content, path)
466
- return true unless File.exist?(path)
467
- new_content != File.binread(path)
468
- end
469
-
470
- def command(str)
471
- $stderr.puts str if verbose?
472
- system str or raise RuntimeError, "'system #{str}' failed"
473
- end
474
-
475
- def ruby(str)
476
- command config('ruby-prog') + ' ' + str
477
- end
478
-
479
- def make(task = '')
480
- command config('make-prog') + ' ' + task
481
- end
482
-
483
- def extdir?(dir)
484
- File.exist?(dir + '/MANIFEST') or File.exist?("#{dir}/extconf.rb")
485
- end
486
-
487
- def all_files_in(dirname)
488
- Dir.open(dirname) {|d|
489
- return d.select {|ent| File.file?("#{dirname}/#{ent}") }
490
- }
491
- end
492
-
493
- REJECT_DIRS = %w(
494
- CVS SCCS RCS CVS.adm .svn
495
- )
496
-
497
- def all_dirs_in(dirname)
498
- Dir.open(dirname) {|d|
499
- return d.select {|n| File.dir?("#{dirname}/#{n}") } - %w(. ..) - REJECT_DIRS
500
- }
501
- end
502
-
503
- end
504
-
505
- #
506
- # Main Installer
507
- #
508
-
509
- class InstallError < StandardError; end
510
-
511
-
512
- module HookUtils
513
-
514
- def run_hook(name)
515
- try_run_hook "#{curr_srcdir()}/#{name}" or
516
- try_run_hook "#{curr_srcdir()}/#{name}.rb"
517
- end
518
-
519
- def try_run_hook(fname)
520
- return false unless File.file?(fname)
521
- begin
522
- instance_eval File.read(fname), fname, 1
523
- rescue
524
- raise InstallError, "hook #{fname} failed:\n" + $!.message
525
- end
526
- true
527
- end
528
-
529
- end
530
-
531
-
532
- module HookScriptAPI
533
-
534
- def get_config(key)
535
- @config[key]
536
- end
537
-
538
- alias config get_config
539
-
540
- def set_config(key, val)
541
- @config[key] = val
542
- end
543
-
544
- #
545
- # srcdir/objdir (works only in the package directory)
546
- #
547
-
548
- #abstract srcdir_root
549
- #abstract objdir_root
550
- #abstract relpath
551
-
552
- def curr_srcdir
553
- "#{srcdir_root()}/#{relpath()}"
554
- end
555
-
556
- def curr_objdir
557
- "#{objdir_root()}/#{relpath()}"
558
- end
559
-
560
- def srcfile(path)
561
- "#{curr_srcdir()}/#{path}"
562
- end
563
-
564
- def srcexist?(path)
565
- File.exist?(srcfile(path))
566
- end
567
-
568
- def srcdirectory?(path)
569
- File.dir?(srcfile(path))
570
- end
571
-
572
- def srcfile?(path)
573
- File.file? srcfile(path)
574
- end
575
-
576
- def srcentries(path = '.')
577
- Dir.open("#{curr_srcdir()}/#{path}") {|d|
578
- return d.to_a - %w(. ..)
579
- }
580
- end
581
-
582
- def srcfiles(path = '.')
583
- srcentries(path).select {|fname|
584
- File.file?(File.join(curr_srcdir(), path, fname))
585
- }
586
- end
587
-
588
- def srcdirectories(path = '.')
589
- srcentries(path).select {|fname|
590
- File.dir?(File.join(curr_srcdir(), path, fname))
591
- }
592
- end
593
-
594
- end
595
-
596
-
597
- class ToplevelInstaller
598
-
599
- Version = '3.3.0'
600
- Copyright = 'Copyright (c) 2000-2004 Minero Aoki'
601
-
602
- TASKS = [
603
- [ 'all', 'do config, setup, then install' ],
604
- [ 'config', 'saves your configurations' ],
605
- [ 'show', 'shows current configuration' ],
606
- [ 'setup', 'compiles ruby extentions and others' ],
607
- [ 'install', 'installs files' ],
608
- [ 'clean', "does `make clean' for each extention" ],
609
- [ 'distclean',"does `make distclean' for each extention" ]
610
- ]
611
-
612
- def ToplevelInstaller.invoke
613
- instance().invoke
614
- end
615
-
616
- @singleton = nil
617
-
618
- def ToplevelInstaller.instance
619
- @singleton ||= new(File.dirname($0))
620
- @singleton
621
- end
622
-
623
- include MetaConfigAPI
624
-
625
- def initialize(ardir_root)
626
- @config = nil
627
- @options = { 'verbose' => true }
628
- @ardir = File.expand_path(ardir_root)
629
- end
630
-
631
- def inspect
632
- "#<#{self.class} #{__id__()}>"
633
- end
634
-
635
- def invoke
636
- run_metaconfigs
637
- case task = parsearg_global()
638
- when nil, 'all'
639
- @config = load_config('config')
640
- parsearg_config
641
- init_installers
642
- exec_config
643
- exec_setup
644
- exec_install
645
- else
646
- @config = load_config(task)
647
- __send__ "parsearg_#{task}"
648
- init_installers
649
- __send__ "exec_#{task}"
650
- end
651
- end
652
-
653
- def run_metaconfigs
654
- eval_file_ifexist "#{@ardir}/metaconfig"
655
- end
656
-
657
- def load_config(task)
658
- case task
659
- when 'config'
660
- ConfigTable.new
661
- when 'clean', 'distclean'
662
- if File.exist?(ConfigTable::SAVE_FILE)
663
- then ConfigTable.load
664
- else ConfigTable.new
665
- end
666
- else
667
- ConfigTable.load
668
- end
669
- end
670
-
671
- def init_installers
672
- @installer = Installer.new(@config, @options, @ardir, File.expand_path('.'))
673
- end
674
-
675
- #
676
- # Hook Script API bases
677
- #
678
-
679
- def srcdir_root
680
- @ardir
681
- end
682
-
683
- def objdir_root
684
- '.'
685
- end
686
-
687
- def relpath
688
- '.'
689
- end
690
-
691
- #
692
- # Option Parsing
693
- #
694
-
695
- def parsearg_global
696
- valid_task = /\A(?:#{TASKS.map {|task,desc| task }.join '|'})\z/
697
-
698
- while arg = ARGV.shift
699
- case arg
700
- when /\A\w+\z/
701
- raise InstallError, "invalid task: #{arg}" unless valid_task =~ arg
702
- return arg
703
-
704
- when '-q', '--quiet'
705
- @options['verbose'] = false
706
-
707
- when '--verbose'
708
- @options['verbose'] = true
709
-
710
- when '-h', '--help'
711
- print_usage $stdout
712
- exit 0
713
-
714
- when '-v', '--version'
715
- puts "#{File.basename($0)} version #{Version}"
716
- exit 0
717
-
718
- when '--copyright'
719
- puts Copyright
720
- exit 0
721
-
722
- else
723
- raise InstallError, "unknown global option '#{arg}'"
724
- end
725
- end
726
-
727
- nil
728
- end
729
-
730
-
731
- def parsearg_no_options
732
- raise InstallError, "#{task}: unknown options: #{ARGV.join ' '}"\
733
- unless ARGV.empty?
734
- end
735
-
736
- alias parsearg_show parsearg_no_options
737
- alias parsearg_setup parsearg_no_options
738
- alias parsearg_clean parsearg_no_options
739
- alias parsearg_distclean parsearg_no_options
740
-
741
- def parsearg_config
742
- re = /\A--(#{ConfigTable.keys.join '|'})(?:=(.*))?\z/
743
- @options['config-opt'] = []
744
-
745
- while i = ARGV.shift
746
- if /\A--?\z/ =~ i
747
- @options['config-opt'] = ARGV.dup
748
- break
749
- end
750
- m = re.match(i) or raise InstallError, "config: unknown option #{i}"
751
- name, value = m.to_a[1,2]
752
- if value
753
- if ConfigTable.bool_config?(name)
754
- raise InstallError, "config: --#{name} allows only yes/no for argument"\
755
- unless /\A(y(es)?|n(o)?|t(rue)?|f(alse))\z/i =~ value
756
- value = (/\Ay(es)?|\At(rue)/i =~ value) ? 'yes' : 'no'
757
- end
758
- else
759
- raise InstallError, "config: --#{name} requires argument"\
760
- unless ConfigTable.bool_config?(name)
761
- value = 'yes'
762
- end
763
- @config[name] = value
764
- end
765
- end
766
-
767
- def parsearg_install
768
- @options['no-harm'] = false
769
- @options['install-prefix'] = ''
770
- while a = ARGV.shift
771
- case a
772
- when /\A--no-harm\z/
773
- @options['no-harm'] = true
774
- when /\A--prefix=(.*)\z/
775
- path = $1
776
- path = File.expand_path(path) unless path[0,1] == '/'
777
- @options['install-prefix'] = path
778
- else
779
- raise InstallError, "install: unknown option #{a}"
780
- end
781
- end
782
- end
783
-
784
- def print_usage(out)
785
- out.puts 'Typical Installation Procedure:'
786
- out.puts " $ ruby #{File.basename $0} config"
787
- out.puts " $ ruby #{File.basename $0} setup"
788
- out.puts " # ruby #{File.basename $0} install (may require root privilege)"
789
- out.puts
790
- out.puts 'Detailed Usage:'
791
- out.puts " ruby #{File.basename $0} <global option>"
792
- out.puts " ruby #{File.basename $0} [<global options>] <task> [<task options>]"
793
-
794
- fmt = " %-20s %s\n"
795
- out.puts
796
- out.puts 'Global options:'
797
- out.printf fmt, '-q,--quiet', 'suppress message outputs'
798
- out.printf fmt, ' --verbose', 'output messages verbosely'
799
- out.printf fmt, '-h,--help', 'print this message'
800
- out.printf fmt, '-v,--version', 'print version and quit'
801
- out.printf fmt, ' --copyright', 'print copyright and quit'
802
-
803
- out.puts
804
- out.puts 'Tasks:'
805
- TASKS.each do |name, desc|
806
- out.printf " %-10s %s\n", name, desc
807
- end
808
-
809
- out.puts
810
- out.puts 'Options for CONFIG or ALL:'
811
- ConfigTable.each_definition do |name, (default, arg, desc, default2)|
812
- out.printf " %-20s %s [%s]\n",
813
- '--'+ name + (ConfigTable.bool_config?(name) ? '' : '='+arg),
814
- desc,
815
- default2 || default
816
- end
817
- out.printf " %-20s %s [%s]\n",
818
- '--rbconfig=path', 'your rbconfig.rb to load', "running ruby's"
819
-
820
- out.puts
821
- out.puts 'Options for INSTALL:'
822
- out.printf " %-20s %s [%s]\n",
823
- '--no-harm', 'only display what to do if given', 'off'
824
- out.printf " %-20s %s [%s]\n",
825
- '--prefix', 'install path prefix', '$prefix'
826
-
827
- out.puts
828
- end
829
-
830
- #
831
- # Task Handlers
832
- #
833
-
834
- def exec_config
835
- @installer.exec_config
836
- @config.save # must be final
837
- end
838
-
839
- def exec_setup
840
- @installer.exec_setup
841
- end
842
-
843
- def exec_install
844
- @installer.exec_install
845
- end
846
-
847
- def exec_show
848
- ConfigTable.each_name do |k|
849
- v = @config.get_raw(k)
850
- if not v or v.empty?
851
- v = '(not specified)'
852
- end
853
- printf "%-10s %s\n", k, v
854
- end
855
- end
856
-
857
- def exec_clean
858
- @installer.exec_clean
859
- end
860
-
861
- def exec_distclean
862
- @installer.exec_distclean
863
- end
864
-
865
- end
866
-
867
-
868
- class ToplevelInstallerMulti < ToplevelInstaller
869
-
870
- include HookUtils
871
- include HookScriptAPI
872
- include FileOperations
873
-
874
- def initialize(ardir)
875
- super
876
- @packages = all_dirs_in("#{@ardir}/packages")
877
- raise 'no package exists' if @packages.empty?
878
- end
879
-
880
- def run_metaconfigs
881
- eval_file_ifexist "#{@ardir}/metaconfig"
882
- @packages.each do |name|
883
- eval_file_ifexist "#{@ardir}/packages/#{name}/metaconfig"
884
- end
885
- end
886
-
887
- def init_installers
888
- @installers = {}
889
- @packages.each do |pack|
890
- @installers[pack] = Installer.new(@config, @options,
891
- "#{@ardir}/packages/#{pack}",
892
- "packages/#{pack}")
893
- end
894
-
895
- with = extract_selection(config('with'))
896
- without = extract_selection(config('without'))
897
- @selected = @installers.keys.select {|name|
898
- (with.empty? or with.include?(name)) \
899
- and not without.include?(name)
900
- }
901
- end
902
-
903
- def extract_selection(list)
904
- a = list.split(/,/)
905
- a.each do |name|
906
- raise InstallError, "no such package: #{name}" \
907
- unless @installers.key?(name)
908
- end
909
- a
910
- end
911
-
912
- def print_usage(f)
913
- super
914
- f.puts 'Inluded packages:'
915
- f.puts ' ' + @packages.sort.join(' ')
916
- f.puts
917
- end
918
-
919
- #
920
- # multi-package metaconfig API
921
- #
922
-
923
- attr_reader :packages
924
-
925
- def declare_packages(list)
926
- raise 'package list is empty' if list.empty?
927
- list.each do |name|
928
- raise "directory packages/#{name} does not exist"\
929
- unless File.dir?("#{@ardir}/packages/#{name}")
930
- end
931
- @packages = list
932
- end
933
-
934
- #
935
- # Task Handlers
936
- #
937
-
938
- def exec_config
939
- run_hook 'pre-config'
940
- each_selected_installers {|inst| inst.exec_config }
941
- run_hook 'post-config'
942
- @config.save # must be final
943
- end
944
-
945
- def exec_setup
946
- run_hook 'pre-setup'
947
- each_selected_installers {|inst| inst.exec_setup }
948
- run_hook 'post-setup'
949
- end
950
-
951
- def exec_install
952
- run_hook 'pre-install'
953
- each_selected_installers {|inst| inst.exec_install }
954
- run_hook 'post-install'
955
- end
956
-
957
- def exec_clean
958
- rm_f ConfigTable::SAVE_FILE
959
- run_hook 'pre-clean'
960
- each_selected_installers {|inst| inst.exec_clean }
961
- run_hook 'post-clean'
962
- end
963
-
964
- def exec_distclean
965
- rm_f ConfigTable::SAVE_FILE
966
- run_hook 'pre-distclean'
967
- each_selected_installers {|inst| inst.exec_distclean }
968
- run_hook 'post-distclean'
969
- end
970
-
971
- #
972
- # lib
973
- #
974
-
975
- def each_selected_installers
976
- Dir.mkdir 'packages' unless File.dir?('packages')
977
- @selected.each do |pack|
978
- $stderr.puts "Processing the package `#{pack}' ..." if @options['verbose']
979
- Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}")
980
- Dir.chdir "packages/#{pack}"
981
- yield @installers[pack]
982
- Dir.chdir '../..'
983
- end
984
- end
985
-
986
- def verbose?
987
- @options['verbose']
988
- end
989
-
990
- def no_harm?
991
- @options['no-harm']
992
- end
993
-
994
- end
995
-
996
-
997
- class Installer
998
-
999
- FILETYPES = %w( bin lib ext data )
1000
-
1001
- include HookScriptAPI
1002
- include HookUtils
1003
- include FileOperations
1004
-
1005
- def initialize(config, opt, srcroot, objroot)
1006
- @config = config
1007
- @options = opt
1008
- @srcdir = File.expand_path(srcroot)
1009
- @objdir = File.expand_path(objroot)
1010
- @currdir = '.'
1011
- end
1012
-
1013
- def inspect
1014
- "#<#{self.class} #{File.basename(@srcdir)}>"
1015
- end
1016
-
1017
- #
1018
- # Hook Script API bases
1019
- #
1020
-
1021
- def srcdir_root
1022
- @srcdir
1023
- end
1024
-
1025
- def objdir_root
1026
- @objdir
1027
- end
1028
-
1029
- def relpath
1030
- @currdir
1031
- end
1032
-
1033
- #
1034
- # configs/options
1035
- #
1036
-
1037
- def no_harm?
1038
- @options['no-harm']
1039
- end
1040
-
1041
- def verbose?
1042
- @options['verbose']
1043
- end
1044
-
1045
- def verbose_off
1046
- begin
1047
- save, @options['verbose'] = @options['verbose'], false
1048
- yield
1049
- ensure
1050
- @options['verbose'] = save
1051
- end
1052
- end
1053
-
1054
- #
1055
- # TASK config
1056
- #
1057
-
1058
- def exec_config
1059
- exec_task_traverse 'config'
1060
- end
1061
-
1062
- def config_dir_bin(rel)
1063
- end
1064
-
1065
- def config_dir_lib(rel)
1066
- end
1067
-
1068
- def config_dir_ext(rel)
1069
- extconf if extdir?(curr_srcdir())
1070
- end
1071
-
1072
- def extconf
1073
- opt = @options['config-opt'].join(' ')
1074
- command "#{config('ruby-prog')} #{curr_srcdir()}/extconf.rb #{opt}"
1075
- end
1076
-
1077
- def config_dir_data(rel)
1078
- end
1079
-
1080
- #
1081
- # TASK setup
1082
- #
1083
-
1084
- def exec_setup
1085
- exec_task_traverse 'setup'
1086
- end
1087
-
1088
- def setup_dir_bin(rel)
1089
- all_files_in(curr_srcdir()).each do |fname|
1090
- adjust_shebang "#{curr_srcdir()}/#{fname}"
1091
- end
1092
- end
1093
-
1094
- def adjust_shebang(path)
1095
- return if no_harm?
1096
- tmpfile = File.basename(path) + '.tmp'
1097
- begin
1098
- File.open(path, 'rb') {|r|
1099
- File.open(tmpfile, 'wb') {|w|
1100
- first = r.gets
1101
- return unless should_modify_shebang?(first)
1102
- $stderr.puts "adjusting shebang: #{File.basename(path)}" if verbose?
1103
- w.print first.sub(SHEBANG_RE, '#!' + config('ruby-path'))
1104
- w.write r.read
1105
- }
1106
- }
1107
- move_file tmpfile, File.basename(path)
1108
- ensure
1109
- File.unlink tmpfile if File.exist?(tmpfile)
1110
- end
1111
- end
1112
-
1113
- def should_modify_shebang?(line)
1114
- File.basename(config('ruby-path')) == 'ruby' or
1115
- shebang_command(line) == 'ruby'
1116
- end
1117
-
1118
- def shebang_command(line)
1119
- cmd, arg = *line.sub(/\A\#!/, '').strip.split(/\s+/, 2)
1120
- cmd
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')}/#{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\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 = /\.#{ ::Config::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 ConfigTable::SAVE_FILE
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 ConfigTable::SAVE_FILE
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