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