roll 0.8.0 → 1.1.0
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.
- data/{LICENSE → COPYING} +1 -1
- data/HISTORY +62 -0
- data/README.rdoc +169 -0
- data/TODO +4 -0
- data/bin/roll +3 -44
- data/lib/oll.rb +1 -2
- data/lib/roll.rb +87 -0
- data/lib/roll/command.rb +207 -0
- data/lib/roll/config.rb +80 -0
- data/lib/roll/environment.rb +317 -0
- data/lib/roll/errors.rb +13 -0
- data/lib/roll/kernel.rb +41 -0
- data/lib/roll/ledger.rb +299 -0
- data/lib/roll/library.rb +241 -558
- data/lib/roll/locals.rb +96 -0
- data/lib/roll/metadata.rb +112 -0
- data/lib/roll/original.rb +10 -0
- data/lib/roll/version.rb +91 -101
- data/meta/active +1 -0
- data/meta/authors +1 -0
- data/meta/contact +1 -0
- data/meta/created +1 -0
- data/meta/description +5 -0
- data/meta/homepage +1 -0
- data/meta/maintainer +1 -0
- data/meta/name +1 -0
- data/meta/repository +1 -0
- data/meta/ruby +2 -0
- data/meta/suite +1 -0
- data/meta/summary +1 -0
- data/meta/version +1 -0
- data/script/rdoc +4 -0
- data/script/setup +1344 -0
- data/script/test +23 -0
- data/test/benchmarks/vsgems.rb +11 -0
- data/test/benchmarks/vsgems_bm.rb +17 -0
- data/test/demonstrations/01_library.rdoc +33 -0
- data/test/demonstrations/04_version.rdoc +56 -0
- data/test/fixtures/env.list +1 -0
- data/{demo/sample → test/fixtures}/inspect.rb +0 -0
- data/test/fixtures/tryme/1.0/lib/tryme.rb +1 -0
- data/test/fixtures/tryme/1.0/meta/homepage +1 -0
- data/test/fixtures/tryme/1.0/meta/name +1 -0
- data/test/fixtures/tryme/1.0/meta/version +1 -0
- data/test/fixtures/tryme/1.1/lib/tryme.rb +1 -0
- data/test/fixtures/tryme/1.1/meta/homepage +1 -0
- data/test/fixtures/tryme/1.1/meta/name +1 -0
- data/test/fixtures/tryme/1.1/meta/version +1 -0
- data/test/{test_version.rb → unit/version_test.rb} +21 -21
- data/test/unitcases/version_case.rb +69 -0
- metadata +102 -65
- data/README +0 -17
- data/demo/bench/bench_load.rb +0 -7
- data/demo/sample/tryme/1.0/lib/tryme.rb +0 -1
- data/demo/sample/tryme/1.1/lib/tryme.rb +0 -1
- data/lib/roll/attributes.rb +0 -72
- data/lib/roll/package.rb +0 -300
- data/lib/roll/remote.rb +0 -37
- data/meta/ROLL-0.8.0.roll +0 -21
- data/task/rdoc +0 -9
- data/task/setup +0 -1616
- data/task/test +0 -5
- data/test/test_library.rb +0 -10
data/meta/description
ADDED
data/meta/homepage
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
http://proutils.github.com/roll
|
data/meta/maintainer
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
7rans <transfire@gmail.com>
|
data/meta/name
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
roll
|
data/meta/repository
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
git://github.com/proutils/roll.git
|
data/meta/ruby
ADDED
data/meta/suite
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
proutils
|
data/meta/summary
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Ruby Object-Oriented Library Ledger
|
data/meta/version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.1.0
|
data/script/rdoc
ADDED
data/script/setup
ADDED
@@ -0,0 +1,1344 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Setup.rb, 2010-02-07 08:33:15
|
4
|
+
#
|
5
|
+
# This is a stand-alone bundle of the setup.rb application.
|
6
|
+
# You can place it in your projects script/ directory, or
|
7
|
+
# rename it to 'setup.rb' and place it in your project's
|
8
|
+
# root directory (just like old times).
|
9
|
+
#
|
10
|
+
module Setup
|
11
|
+
VERSION = '5.0.1'
|
12
|
+
end
|
13
|
+
class << File #:nodoc: all
|
14
|
+
unless respond_to?(:read) # Ruby 1.6 and less
|
15
|
+
def read(fname)
|
16
|
+
open(fname){ |f| return f.read }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
def dir?(path)
|
20
|
+
directory?((path[-1,1] == '/') ? path : path + '/')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
unless Errno.const_defined?(:ENOTEMPTY) # Windows?
|
24
|
+
module Errno #:nodoc:
|
25
|
+
class ENOTEMPTY #:nodoc:
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
module Setup
|
30
|
+
META_EXTENSION_DIR = '.setup'
|
31
|
+
FILETYPES = %w( bin lib ext data etc man doc )
|
32
|
+
INSTALL_RECORD = 'SetupReceipt' #'.cache/setup/installedfiles'
|
33
|
+
end
|
34
|
+
module Setup
|
35
|
+
class Project
|
36
|
+
ROOT_MARKER = '{setup.rb,script/setup,meta/,MANIFEST,lib/}'
|
37
|
+
def rootdir
|
38
|
+
@rootdir ||= (
|
39
|
+
root = Dir[File.join(Dir.pwd, ROOT_MARKER)].first
|
40
|
+
if !root
|
41
|
+
raise Error, "not a project directory"
|
42
|
+
else
|
43
|
+
Dir.pwd
|
44
|
+
end
|
45
|
+
)
|
46
|
+
end
|
47
|
+
def name
|
48
|
+
@name = (
|
49
|
+
if file = Dir["{script/setup,meta,.meta}/name"].first
|
50
|
+
File.read(file).strip
|
51
|
+
else
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
)
|
55
|
+
end
|
56
|
+
def loadpath
|
57
|
+
@loadpath ||= (
|
58
|
+
if file = Dir.glob('{script/setup,meta,.meta}/loadpath').first
|
59
|
+
raw = File.read(file).strip.chomp(']')
|
60
|
+
raw.split(/[\n,]/).map do |e|
|
61
|
+
e.strip.sub(/^[\[-]\s*/,'')
|
62
|
+
end
|
63
|
+
else
|
64
|
+
nil
|
65
|
+
end
|
66
|
+
)
|
67
|
+
end
|
68
|
+
def extconfs
|
69
|
+
@extconfs ||= Dir['ext/**/extconf.rb']
|
70
|
+
end
|
71
|
+
def extensions
|
72
|
+
@extensions ||= extconfs.collect{ |f| File.dirname(f) }
|
73
|
+
end
|
74
|
+
def compiles?
|
75
|
+
!extensions.empty?
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
module Setup
|
80
|
+
class Session
|
81
|
+
attr :options
|
82
|
+
def initialize(options={})
|
83
|
+
@options = options
|
84
|
+
self.io ||= StringIO.new # log instead ?
|
85
|
+
end
|
86
|
+
def io
|
87
|
+
@options[:io]
|
88
|
+
end
|
89
|
+
def io=(anyio)
|
90
|
+
@options[:io] = anyio
|
91
|
+
end
|
92
|
+
def trace?; @options[:trace]; end
|
93
|
+
def trace=(val)
|
94
|
+
@options[:trace] = val
|
95
|
+
end
|
96
|
+
def trial?; @options[:trial]; end
|
97
|
+
def trial=(val)
|
98
|
+
@options[:trial] = val
|
99
|
+
end
|
100
|
+
def quiet?; @options[:quiet]; end
|
101
|
+
def quiet=(val)
|
102
|
+
@options[:quiet] = val
|
103
|
+
end
|
104
|
+
def force?; @options[:force]; end
|
105
|
+
def force=(val)
|
106
|
+
@options[:force] = val
|
107
|
+
end
|
108
|
+
def compile?
|
109
|
+
configuration.compile? && project.compiles?
|
110
|
+
end
|
111
|
+
def all
|
112
|
+
config
|
113
|
+
if compile?
|
114
|
+
make
|
115
|
+
end
|
116
|
+
if configuration.test?
|
117
|
+
ok = test
|
118
|
+
exit 1 unless ok
|
119
|
+
end
|
120
|
+
install
|
121
|
+
if configuration.ri?
|
122
|
+
document
|
123
|
+
end
|
124
|
+
end
|
125
|
+
def config
|
126
|
+
log_header('Configure')
|
127
|
+
if configuration.save_config
|
128
|
+
io.puts "Configuration saved." unless quiet?
|
129
|
+
else
|
130
|
+
io.puts "Configuration current." unless quiet?
|
131
|
+
end
|
132
|
+
puts configuration if trace? && !quiet?
|
133
|
+
compiler.configure if compile? #compiler.compiles?
|
134
|
+
end
|
135
|
+
def make
|
136
|
+
abort "must run 'setup config' first" unless configuration.exist?
|
137
|
+
log_header('Compile')
|
138
|
+
compiler.compile
|
139
|
+
end
|
140
|
+
alias_method :setup, :make
|
141
|
+
def install
|
142
|
+
abort "must run 'setup config' first" unless configuration.exist?
|
143
|
+
log_header('Install')
|
144
|
+
installer.install
|
145
|
+
end
|
146
|
+
def test
|
147
|
+
return true unless tester.testable?
|
148
|
+
log_header('Test')
|
149
|
+
tester.test
|
150
|
+
end
|
151
|
+
def document
|
152
|
+
log_header('Document')
|
153
|
+
documentor.document
|
154
|
+
end
|
155
|
+
def clean
|
156
|
+
log_header('Clean')
|
157
|
+
compiler.clean
|
158
|
+
end
|
159
|
+
def distclean
|
160
|
+
log_header('Distclean')
|
161
|
+
compiler.distclean
|
162
|
+
end
|
163
|
+
def uninstall
|
164
|
+
if !File.exist?(INSTALL_RECORD)
|
165
|
+
io.puts "Nothing is installed."
|
166
|
+
return
|
167
|
+
end
|
168
|
+
log_header('Uninstall')
|
169
|
+
uninstaller.uninstall
|
170
|
+
io.puts('Ok.')
|
171
|
+
end
|
172
|
+
def show
|
173
|
+
puts configuration
|
174
|
+
end
|
175
|
+
def project
|
176
|
+
@project ||= Project.new
|
177
|
+
end
|
178
|
+
def configuration
|
179
|
+
@configuration ||= Configuration.new
|
180
|
+
end
|
181
|
+
def compiler
|
182
|
+
@compiler ||= Compiler.new(project, configuration, options)
|
183
|
+
end
|
184
|
+
def installer
|
185
|
+
@installer ||= Installer.new(project, configuration, options)
|
186
|
+
end
|
187
|
+
def tester
|
188
|
+
@tester ||= Tester.new(project, configuration, options)
|
189
|
+
end
|
190
|
+
def documentor
|
191
|
+
@documentor ||= Documentor.new(project, configuration, options)
|
192
|
+
end
|
193
|
+
def uninstaller
|
194
|
+
@uninstaller ||= Uninstaller.new(project, configuration, options)
|
195
|
+
end
|
196
|
+
def log_header(phase)
|
197
|
+
return if quiet?
|
198
|
+
if trial?
|
199
|
+
str = "#{phase.upcase} (trail run)"
|
200
|
+
else
|
201
|
+
str = "#{phase.upcase}"
|
202
|
+
end
|
203
|
+
line = "- " * 35
|
204
|
+
line[0..str.size+3] = str
|
205
|
+
io.puts("\n- - #{line}\n\n")
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
module Setup
|
210
|
+
class Base
|
211
|
+
attr :project
|
212
|
+
attr :config
|
213
|
+
attr_accessor :trial
|
214
|
+
attr_accessor :trace
|
215
|
+
attr_accessor :quiet
|
216
|
+
attr_accessor :force
|
217
|
+
attr_accessor :io
|
218
|
+
def initialize(project, configuration, options={})
|
219
|
+
@project = project
|
220
|
+
@config = configuration
|
221
|
+
initialize_hooks
|
222
|
+
options.each do |k,v|
|
223
|
+
__send__("#{k}=", v) if respond_to?("#{k}=")
|
224
|
+
end
|
225
|
+
end
|
226
|
+
def initialize_hooks
|
227
|
+
file = META_EXTENSION_DIR + "/#{self.class.name.downcase}.rb"
|
228
|
+
if File.exist?(file)
|
229
|
+
script = File.read(file)
|
230
|
+
(class << self; self; end).class_eval(script)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
def trial? ; @trial ; end
|
234
|
+
def trace? ; @trace ; end
|
235
|
+
def quiet? ; @quiet ; end
|
236
|
+
def force? ; @force ; end
|
237
|
+
def rootdir
|
238
|
+
project.rootdir
|
239
|
+
end
|
240
|
+
def bash(*args)
|
241
|
+
$stderr.puts args.join(' ') if trace?
|
242
|
+
system(*args) or raise RuntimeError, "system(#{args.map{|a| a.inspect }.join(' ')}) failed"
|
243
|
+
end
|
244
|
+
alias_method :command, :bash
|
245
|
+
def ruby(*args)
|
246
|
+
bash(config.rubyprog, *args)
|
247
|
+
end
|
248
|
+
def trace_off #:yield:
|
249
|
+
begin
|
250
|
+
save, @trace = trace?, false
|
251
|
+
yield
|
252
|
+
ensure
|
253
|
+
@trace = save
|
254
|
+
end
|
255
|
+
end
|
256
|
+
def rm_f(path)
|
257
|
+
io.puts "rm -f #{path}" if trace? or trial?
|
258
|
+
return if trial?
|
259
|
+
force_remove_file(path)
|
260
|
+
end
|
261
|
+
def force_remove_file(path)
|
262
|
+
begin
|
263
|
+
remove_file(path)
|
264
|
+
rescue
|
265
|
+
end
|
266
|
+
end
|
267
|
+
def remove_file(path)
|
268
|
+
File.chmod 0777, path
|
269
|
+
File.unlink(path)
|
270
|
+
end
|
271
|
+
def rmdir(path)
|
272
|
+
io.puts "rmdir #{path}" if trace? or trial?
|
273
|
+
return if trial?
|
274
|
+
Dir.rmdir(path)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
class Error < StandardError
|
278
|
+
end
|
279
|
+
end
|
280
|
+
module Setup
|
281
|
+
class Compiler < Base
|
282
|
+
def compiles?
|
283
|
+
!extdirs.empty?
|
284
|
+
end
|
285
|
+
def configure
|
286
|
+
extdirs.each do |dir|
|
287
|
+
Dir.chdir(dir) do
|
288
|
+
if File.exist?('extconf.rb') && !FileUtils.uptodate?('Makefile', ['extconf.rb'])
|
289
|
+
ruby("extconf.rb")
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
def compile
|
295
|
+
extdirs.each do |dir|
|
296
|
+
Dir.chdir(dir) do
|
297
|
+
make
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
def clean
|
302
|
+
extdirs.each do |dir|
|
303
|
+
Dir.chdir(dir) do
|
304
|
+
make('clean')
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
def distclean
|
309
|
+
extdirs.each do |dir|
|
310
|
+
Dir.chdir(dir) do
|
311
|
+
make('distclean')
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
315
|
+
def extdirs
|
316
|
+
Dir['ext/**/*/{MANIFEST,extconf.rb}'].map do |f|
|
317
|
+
File.dirname(f)
|
318
|
+
end.uniq
|
319
|
+
end
|
320
|
+
def make(task=nil)
|
321
|
+
return unless File.exist?('Makefile')
|
322
|
+
bash(*[config.makeprog, task].compact)
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
326
|
+
require 'rbconfig'
|
327
|
+
require 'fileutils'
|
328
|
+
require 'erb'
|
329
|
+
require 'yaml'
|
330
|
+
require 'shellwords'
|
331
|
+
module Setup
|
332
|
+
class Configuration
|
333
|
+
RBCONFIG = ::Config::CONFIG
|
334
|
+
CONFIG_FILE = 'SetupConfig' # '.cache/setup/config'
|
335
|
+
META_CONFIG_FILE = META_EXTENSION_DIR + '/configuration.rb'
|
336
|
+
def self.options
|
337
|
+
@@options ||= []
|
338
|
+
end
|
339
|
+
def self.option(name, *args) #type, description)
|
340
|
+
options << [name.to_s, *args] #type, description]
|
341
|
+
attr_accessor(name)
|
342
|
+
end
|
343
|
+
option :prefix , :path, 'path prefix of target environment'
|
344
|
+
option :bindir , :path, 'directory for commands'
|
345
|
+
option :libdir , :path, 'directory for libraries'
|
346
|
+
option :datadir , :path, 'directory for shared data'
|
347
|
+
option :mandir , :path, 'directory for man pages'
|
348
|
+
option :docdir , :path, 'directory for documentation'
|
349
|
+
option :rbdir , :path, 'directory for ruby scripts'
|
350
|
+
option :sodir , :path, 'directory for ruby extentions'
|
351
|
+
option :sysconfdir , :path, 'directory for system configuration files'
|
352
|
+
option :localstatedir , :path, 'directory for local state data'
|
353
|
+
option :libruby , :path, 'directory for ruby libraries'
|
354
|
+
option :librubyver , :path, 'directory for standard ruby libraries'
|
355
|
+
option :librubyverarch , :path, 'directory for standard ruby extensions'
|
356
|
+
option :siteruby , :path, 'directory for version-independent aux ruby libraries'
|
357
|
+
option :siterubyver , :path, 'directory for aux ruby libraries'
|
358
|
+
option :siterubyverarch , :path, 'directory for aux ruby binaries'
|
359
|
+
option :rubypath , :prog, 'path to set to #! line'
|
360
|
+
option :rubyprog , :prog, 'ruby program used for installation'
|
361
|
+
option :makeprog , :prog, 'make program to compile ruby extentions'
|
362
|
+
option :extconfopt , :opts, 'options to pass-thru to extconf.rb'
|
363
|
+
option :shebang , :pick, 'shebang line (#!) editing mode (all,ruby,never)'
|
364
|
+
option :no_test, :t , :bool, 'run pre-installation tests'
|
365
|
+
option :no_ri, :d , :bool, 'generate ri documentation'
|
366
|
+
option :no_doc , :bool, 'install doc/ directory'
|
367
|
+
option :no_ext , :bool, 'compile/install ruby extentions'
|
368
|
+
option :install_prefix , :path, 'install to alternate root location'
|
369
|
+
option :root , :path, 'install to alternate root location'
|
370
|
+
option :installdirs , :pick, 'install location mode (site,std,home)' #, local)
|
371
|
+
option :type , :pick, 'install location mode (site,std,home)'
|
372
|
+
::Config::CONFIG.each do |key,val|
|
373
|
+
next if key == "configure_args"
|
374
|
+
name = key.to_s.downcase
|
375
|
+
define_method(name){ val }
|
376
|
+
end
|
377
|
+
config_args = Shellwords.shellwords(::Config::CONFIG["configure_args"])
|
378
|
+
config_args.each do |ent|
|
379
|
+
if ent.index("=")
|
380
|
+
key, val = *ent.split("=")
|
381
|
+
else
|
382
|
+
key, val = ent, true
|
383
|
+
end
|
384
|
+
name = key.downcase
|
385
|
+
name = name.sub(/^--/,'')
|
386
|
+
name = name.gsub(/-/,'_')
|
387
|
+
define_method(name){ val }
|
388
|
+
end
|
389
|
+
def options
|
390
|
+
self.class.options
|
391
|
+
end
|
392
|
+
def initialize(values={})
|
393
|
+
initialize_metaconfig
|
394
|
+
initialize_defaults
|
395
|
+
initialize_environment
|
396
|
+
initialize_configfile
|
397
|
+
values.each{ |k,v| __send__("#{k}=", v) }
|
398
|
+
yeild(self) if block_given?
|
399
|
+
end
|
400
|
+
def initialize_metaconfig
|
401
|
+
if File.exist?(META_CONFIG_FILE)
|
402
|
+
script = File.read(META_CONFIG_FILE)
|
403
|
+
(class << self; self; end).class_eval(script)
|
404
|
+
end
|
405
|
+
end
|
406
|
+
def initialize_defaults
|
407
|
+
self.type = 'site'
|
408
|
+
self.no_ri = true
|
409
|
+
self.no_test = true
|
410
|
+
self.no_doc = false
|
411
|
+
self.no_ext = false
|
412
|
+
end
|
413
|
+
def initialize_environment
|
414
|
+
options.each do |name, *args|
|
415
|
+
if value = ENV["RUBYSETUP_#{name.to_s.upcase}"]
|
416
|
+
__send__("#{name}=", value)
|
417
|
+
end
|
418
|
+
end
|
419
|
+
end
|
420
|
+
def initialize_configfile
|
421
|
+
if File.exist?(CONFIG_FILE)
|
422
|
+
erb = ERB.new(File.read(CONFIG_FILE))
|
423
|
+
txt = erb.result(binding)
|
424
|
+
dat = YAML.load(txt)
|
425
|
+
dat.each do |k, v|
|
426
|
+
next if 'type' == k
|
427
|
+
next if 'installdirs' == k
|
428
|
+
k = k.gsub('-','_')
|
429
|
+
__send__("#{k}=", v)
|
430
|
+
end
|
431
|
+
if dat['type']
|
432
|
+
self.type = dat['type']
|
433
|
+
end
|
434
|
+
if dat['installdirs']
|
435
|
+
self.installdirs = dat['installdirs']
|
436
|
+
end
|
437
|
+
end
|
438
|
+
end
|
439
|
+
def base_bindir
|
440
|
+
@base_bindir ||= subprefix('bindir')
|
441
|
+
end
|
442
|
+
def base_libdir
|
443
|
+
@base_libdir ||= subprefix('libdir')
|
444
|
+
end
|
445
|
+
def base_datadir
|
446
|
+
@base_datadir ||= subprefix('datadir')
|
447
|
+
end
|
448
|
+
def base_mandir
|
449
|
+
@base_mandir ||= subprefix('mandir')
|
450
|
+
end
|
451
|
+
def base_docdir
|
452
|
+
@base_docdir || File.dirname(subprefix('docdir'))
|
453
|
+
end
|
454
|
+
def base_rubylibdir
|
455
|
+
@rubylibdir ||= subprefix('rubylibdir')
|
456
|
+
end
|
457
|
+
def base_rubyarchdir
|
458
|
+
@base_rubyarchdir ||= subprefix('archdir')
|
459
|
+
end
|
460
|
+
def base_sysconfdir
|
461
|
+
@base_sysconfdir ||= subprefix('sysconfdir')
|
462
|
+
end
|
463
|
+
def base_localstatedir
|
464
|
+
@base_localstatedir ||= subprefix('localstatedir')
|
465
|
+
end
|
466
|
+
def type
|
467
|
+
@type ||= 'site'
|
468
|
+
end
|
469
|
+
def type=(val)
|
470
|
+
@type = val
|
471
|
+
case val.to_s
|
472
|
+
when 'std', 'ruby'
|
473
|
+
@rbdir = librubyver #'$librubyver'
|
474
|
+
@sodir = librubyverarch #'$librubyverarch'
|
475
|
+
when 'site'
|
476
|
+
@rbdir = siterubyver #'$siterubyver'
|
477
|
+
@sodir = siterubyverarch #'$siterubyverarch'
|
478
|
+
when 'home'
|
479
|
+
self.prefix = File.join(home, '.local') # TODO: Use XDG
|
480
|
+
@rbdir = nil #'$libdir/ruby'
|
481
|
+
@sodir = nil #'$libdir/ruby'
|
482
|
+
else
|
483
|
+
raise Error, "bad config: use type=(std|site|home) [#{val}]"
|
484
|
+
end
|
485
|
+
end
|
486
|
+
alias_method :installdirs, :type
|
487
|
+
alias_method :installdirs=, :type=
|
488
|
+
alias_method :install_prefix, :root
|
489
|
+
alias_method :install_prefix=, :root=
|
490
|
+
def prefix
|
491
|
+
@prefix ||= RBCONFIG['prefix']
|
492
|
+
end
|
493
|
+
def prefix=(path)
|
494
|
+
@prefix = pathname(path)
|
495
|
+
end
|
496
|
+
def libruby
|
497
|
+
@libruby ||= RBCONFIG['prefix'] + "/lib/ruby"
|
498
|
+
end
|
499
|
+
def libruby=(path)
|
500
|
+
path = pathname(path)
|
501
|
+
@librubyver = librubyver.sub(libruby, path)
|
502
|
+
@librubyverarch = librubyverarch.sub(libruby, path)
|
503
|
+
@libruby = path
|
504
|
+
end
|
505
|
+
def librubyver
|
506
|
+
@librubyver ||= RBCONFIG['rubylibdir']
|
507
|
+
end
|
508
|
+
def librubyver=(path)
|
509
|
+
@librubyver = pathname(path)
|
510
|
+
end
|
511
|
+
def librubyverarch
|
512
|
+
@librubyverarch ||= RBCONFIG['archdir']
|
513
|
+
end
|
514
|
+
def librubyverarch=(path)
|
515
|
+
@librubyverarch = pathname(path)
|
516
|
+
end
|
517
|
+
def siteruby
|
518
|
+
@siteruby ||= RBCONFIG['sitedir']
|
519
|
+
end
|
520
|
+
def siteruby=(path)
|
521
|
+
path = pathname(path)
|
522
|
+
@siterubyver = siterubyver.sub(siteruby, path)
|
523
|
+
@siterubyverarch = siterubyverarch.sub(siteruby, path)
|
524
|
+
@siteruby = path
|
525
|
+
end
|
526
|
+
def siterubyver
|
527
|
+
@siterubyver ||= RBCONFIG['sitelibdir']
|
528
|
+
end
|
529
|
+
def siterubyver=(path)
|
530
|
+
@siterubyver = pathname(path)
|
531
|
+
end
|
532
|
+
def siterubyverarch
|
533
|
+
@siterubyverarch ||= RBCONFIG['sitearchdir']
|
534
|
+
end
|
535
|
+
def siterubyverarch=(path)
|
536
|
+
@siterubyverarch = pathname(path)
|
537
|
+
end
|
538
|
+
def bindir
|
539
|
+
@bindir || File.join(prefix, base_bindir)
|
540
|
+
end
|
541
|
+
def bindir=(path)
|
542
|
+
@bindir = pathname(path)
|
543
|
+
end
|
544
|
+
def libdir
|
545
|
+
@libdir || File.join(prefix, base_libdir)
|
546
|
+
end
|
547
|
+
def libdir=(path)
|
548
|
+
@libdir = pathname(path)
|
549
|
+
end
|
550
|
+
def datadir
|
551
|
+
@datadir || File.join(prefix, base_datadir)
|
552
|
+
end
|
553
|
+
def datadir=(path)
|
554
|
+
@datadir = pathname(path)
|
555
|
+
end
|
556
|
+
def mandir
|
557
|
+
@mandir || File.join(prefix, base_mandir)
|
558
|
+
end
|
559
|
+
def mandir=(path)
|
560
|
+
@mandir = pathname(path)
|
561
|
+
end
|
562
|
+
def docdir
|
563
|
+
@docdir || File.join(prefix, base_docdir)
|
564
|
+
end
|
565
|
+
def docdir=(path)
|
566
|
+
@docdir = pathname(path)
|
567
|
+
end
|
568
|
+
def rbdir
|
569
|
+
@rbdir || File.join(prefix, base_rubylibdir)
|
570
|
+
end
|
571
|
+
def sodir
|
572
|
+
@sodir || File.join(prefix, base_rubyarchdir)
|
573
|
+
end
|
574
|
+
def sysconfdir
|
575
|
+
@sysconfdir ||= base_sysconfdir
|
576
|
+
end
|
577
|
+
def sysconfdir=(path)
|
578
|
+
@sysconfdir = pathname(path)
|
579
|
+
end
|
580
|
+
def localstatedir
|
581
|
+
@localstatedir ||= base_localstatedir
|
582
|
+
end
|
583
|
+
def localstatedir=(path)
|
584
|
+
@localstatedir = pathname(path)
|
585
|
+
end
|
586
|
+
def rubypath
|
587
|
+
@rubypath ||= File.join(RBCONFIG['bindir'], RBCONFIG['ruby_install_name'] + RBCONFIG['EXEEXT'])
|
588
|
+
end
|
589
|
+
def rubypath=(path)
|
590
|
+
@rubypath = pathname(path)
|
591
|
+
end
|
592
|
+
def rubyprog
|
593
|
+
@rubyprog || rubypath
|
594
|
+
end
|
595
|
+
def rubyprog=(command)
|
596
|
+
@rubyprog = command
|
597
|
+
end
|
598
|
+
def makeprog
|
599
|
+
@makeprog ||= (
|
600
|
+
if arg = RBCONFIG['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg }
|
601
|
+
arg.sub(/'/, '').split(/=/, 2)[1]
|
602
|
+
else
|
603
|
+
'make'
|
604
|
+
end
|
605
|
+
)
|
606
|
+
end
|
607
|
+
def makeprog=(command)
|
608
|
+
@makeprog = command
|
609
|
+
end
|
610
|
+
def extconfopt
|
611
|
+
@extconfopt ||= ''
|
612
|
+
end
|
613
|
+
def extconfopt=(string)
|
614
|
+
@extconfopt = string
|
615
|
+
end
|
616
|
+
def shebang
|
617
|
+
@shebang ||= 'ruby'
|
618
|
+
end
|
619
|
+
def shebang=(val)
|
620
|
+
if %w(all ruby never).include?(val)
|
621
|
+
@shebang = val
|
622
|
+
else
|
623
|
+
raise Error, "bad config: use SHEBANG=(all|ruby|never) [#{val}]"
|
624
|
+
end
|
625
|
+
end
|
626
|
+
def no_ext
|
627
|
+
@no_ext
|
628
|
+
end
|
629
|
+
def no_ext=(val)
|
630
|
+
@no_ext = boolean(val)
|
631
|
+
end
|
632
|
+
def no_test
|
633
|
+
@no_test
|
634
|
+
end
|
635
|
+
def no_test=(val)
|
636
|
+
@no_test = boolean(val)
|
637
|
+
end
|
638
|
+
def no_doc
|
639
|
+
@no_doc
|
640
|
+
end
|
641
|
+
def no_doc=(val)
|
642
|
+
@no_doc = boolean(val)
|
643
|
+
end
|
644
|
+
def no_ri
|
645
|
+
@no_ri
|
646
|
+
end
|
647
|
+
def no_ri=(val)
|
648
|
+
@no_ri = boolean(val)
|
649
|
+
end
|
650
|
+
def compile?
|
651
|
+
!no_ext
|
652
|
+
end
|
653
|
+
def test?
|
654
|
+
!no_test
|
655
|
+
end
|
656
|
+
def ri?
|
657
|
+
!no_ri
|
658
|
+
end
|
659
|
+
def doc?
|
660
|
+
!no_doc
|
661
|
+
end
|
662
|
+
def to_h
|
663
|
+
h = {}
|
664
|
+
options.each do |name, *args|
|
665
|
+
h[name.to_s] = __send__(name)
|
666
|
+
end
|
667
|
+
h
|
668
|
+
end
|
669
|
+
def to_s
|
670
|
+
to_yaml.sub(/\A---\s*\n/,'')
|
671
|
+
end
|
672
|
+
def to_yaml(*args)
|
673
|
+
to_h.to_yaml(*args)
|
674
|
+
end
|
675
|
+
def save_config
|
676
|
+
out = to_yaml
|
677
|
+
if not File.exist?(File.dirname(CONFIG_FILE))
|
678
|
+
FileUtils.mkdir_p(File.dirname(CONFIG_FILE))
|
679
|
+
end
|
680
|
+
if File.exist?(CONFIG_FILE)
|
681
|
+
txt = File.read(CONFIG_FILE)
|
682
|
+
return nil if txt == out
|
683
|
+
end
|
684
|
+
File.open(CONFIG_FILE, 'w'){ |f| f << out }
|
685
|
+
true
|
686
|
+
end
|
687
|
+
def exist?
|
688
|
+
File.exist?(CONFIG_FILE)
|
689
|
+
end
|
690
|
+
private
|
691
|
+
def pathname(path)
|
692
|
+
path.gsub(%r<\\$([^/]+)>){ self[$1] }
|
693
|
+
end
|
694
|
+
def boolean(val, name=nil)
|
695
|
+
case val
|
696
|
+
when true, false, nil
|
697
|
+
val
|
698
|
+
else
|
699
|
+
case val.to_s.downcase
|
700
|
+
when 'y', 'yes', 't', 'true'
|
701
|
+
true
|
702
|
+
when 'n', 'no', 'f', 'false'
|
703
|
+
false
|
704
|
+
else
|
705
|
+
raise Error, "bad config: use --#{name}=(yes|no) [\#{val}]"
|
706
|
+
end
|
707
|
+
end
|
708
|
+
end
|
709
|
+
def subprefix(path, with='')
|
710
|
+
val = RBCONFIG[path]
|
711
|
+
raise "Unknown path -- #{path}" if val.nil?
|
712
|
+
prefix = Regexp.quote(RBCONFIG['prefix'])
|
713
|
+
val.sub(/\A#{prefix}/, with)
|
714
|
+
end
|
715
|
+
def home
|
716
|
+
ENV['HOME'] || raise(Error, 'HOME is not set.')
|
717
|
+
end
|
718
|
+
end #class ConfigTable
|
719
|
+
end #module Setup
|
720
|
+
=begin
|
721
|
+
def inintialize_metaconfig
|
722
|
+
path = Dir.glob(METACONFIG_FILE).first
|
723
|
+
if path && File.file?(path)
|
724
|
+
MetaConfigEnvironment.new(self).instance_eval(File.read(path), path)
|
725
|
+
end
|
726
|
+
end
|
727
|
+
class MetaConfigEnvironment
|
728
|
+
def initialize(config) #, installer)
|
729
|
+
@config = config
|
730
|
+
end
|
731
|
+
def config_names
|
732
|
+
@config.descriptions.collect{ |n, t, d| n.to_s }
|
733
|
+
end
|
734
|
+
def config?(name)
|
735
|
+
@config.descriptions.find do |sym, type, desc|
|
736
|
+
sym.to_s == name.to_s
|
737
|
+
end
|
738
|
+
end
|
739
|
+
def bool_config?(name)
|
740
|
+
@config.descriptions.find do |sym, type, desc|
|
741
|
+
sym.to_s == name.to_s && type == :bool
|
742
|
+
end
|
743
|
+
end
|
744
|
+
def path_config?(name)
|
745
|
+
@config.descriptions.find do |sym, type, desc|
|
746
|
+
sym.to_s == name.to_s && type == :path
|
747
|
+
end
|
748
|
+
end
|
749
|
+
def value_config?(name)
|
750
|
+
@config.descriptions.find do |sym, type, desc|
|
751
|
+
sym.to_s == name.to_s && type != :prog
|
752
|
+
end
|
753
|
+
end
|
754
|
+
def add_config(name, default, desc)
|
755
|
+
@config.descriptions << [name.to_sym, nil, desc]
|
756
|
+
end
|
757
|
+
def add_bool_config(name, default, desc)
|
758
|
+
@config.descriptions << [name.to_sym, :bool, desc]
|
759
|
+
end
|
760
|
+
def add_path_config(name, default, desc)
|
761
|
+
@config.descriptions << [name.to_sym, :path, desc]
|
762
|
+
end
|
763
|
+
def set_config_default(name, default)
|
764
|
+
@config[name] = default
|
765
|
+
end
|
766
|
+
def remove_config(name)
|
767
|
+
item = @config.descriptions.find do |sym, type, desc|
|
768
|
+
sym.to_s == name.to_s
|
769
|
+
end
|
770
|
+
index = @config.descriptions.index(item)
|
771
|
+
@config.descriptions.delete(index)
|
772
|
+
end
|
773
|
+
end
|
774
|
+
=end
|
775
|
+
module Setup
|
776
|
+
class Documentor < Base
|
777
|
+
def document
|
778
|
+
return if config.no_doc
|
779
|
+
exec_ri
|
780
|
+
end
|
781
|
+
def exec_ri
|
782
|
+
case config.type #installdirs
|
783
|
+
when 'std', 'ruby'
|
784
|
+
output = "--ri-site"
|
785
|
+
when 'site'
|
786
|
+
output = "--ri-site"
|
787
|
+
when 'home'
|
788
|
+
output = "--ri"
|
789
|
+
else
|
790
|
+
abort "bad config: should not be possible -- type=#{config.type}"
|
791
|
+
end
|
792
|
+
if File.exist?('.document')
|
793
|
+
files = File.read('.document').split("\n")
|
794
|
+
files.reject!{ |l| l =~ /^\s*[#]/ || l !~ /\S/ }
|
795
|
+
files.collect!{ |f| f.strip }
|
796
|
+
else
|
797
|
+
files = []
|
798
|
+
files << 'lib' if File.directory?('lib')
|
799
|
+
files << 'ext' if File.directory?('ext')
|
800
|
+
end
|
801
|
+
opt = []
|
802
|
+
opt << "-U"
|
803
|
+
opt << "-q" #if quiet?
|
804
|
+
opt << output
|
805
|
+
opt << files
|
806
|
+
opt = opt.flatten
|
807
|
+
cmd = "rdoc " + opt.join(' ')
|
808
|
+
if trial?
|
809
|
+
puts cmd
|
810
|
+
else
|
811
|
+
begin
|
812
|
+
success = system(cmd)
|
813
|
+
raise unless success
|
814
|
+
io.puts "Ok ri." #unless quiet?
|
815
|
+
rescue Exception
|
816
|
+
$stderr.puts "ri generation failed"
|
817
|
+
$stderr.puts "command was: '#{cmd}'"
|
818
|
+
end
|
819
|
+
end
|
820
|
+
end
|
821
|
+
def exec_rdoc
|
822
|
+
main = Dir.glob("README{,.*}", File::FNM_CASEFOLD).first
|
823
|
+
if File.exist?('.document')
|
824
|
+
files = File.read('.document').split("\n")
|
825
|
+
files.reject!{ |l| l =~ /^\s*[#]/ || l !~ /\S/ }
|
826
|
+
files.collect!{ |f| f.strip }
|
827
|
+
else
|
828
|
+
files = []
|
829
|
+
files << main if main
|
830
|
+
files << 'lib' if File.directory?('lib')
|
831
|
+
files << 'ext' if File.directory?('ext')
|
832
|
+
end
|
833
|
+
checkfiles = (files + files.map{ |f| Dir[File.join(f,'*','**')] }).flatten.uniq
|
834
|
+
if FileUtils.uptodate?('doc/rdoc', checkfiles)
|
835
|
+
puts "RDocs look current."
|
836
|
+
return
|
837
|
+
end
|
838
|
+
output = 'doc/rdoc'
|
839
|
+
title = (PACKAGE.capitalize + " API").strip if PACKAGE
|
840
|
+
template = config.doctemplate || 'html'
|
841
|
+
opt = []
|
842
|
+
opt << "-U"
|
843
|
+
opt << "-q" #if quiet?
|
844
|
+
opt << "--op=#{output}"
|
845
|
+
opt << "--title=#{title}"
|
846
|
+
opt << "--main=#{main}" if main
|
847
|
+
opt << files
|
848
|
+
opt = opt.flatten
|
849
|
+
cmd = "rdoc " + opt.join(' ')
|
850
|
+
if trial?
|
851
|
+
puts cmd
|
852
|
+
else
|
853
|
+
begin
|
854
|
+
system(cmd)
|
855
|
+
puts "Ok rdoc." unless quiet?
|
856
|
+
rescue Exception
|
857
|
+
puts "Fail rdoc."
|
858
|
+
puts "Command was: '#{cmd}'"
|
859
|
+
puts "Proceeding with install anyway."
|
860
|
+
end
|
861
|
+
end
|
862
|
+
end
|
863
|
+
end
|
864
|
+
end
|
865
|
+
module Setup
|
866
|
+
class Installer < Base
|
867
|
+
def install_prefix
|
868
|
+
config.install_prefix
|
869
|
+
end
|
870
|
+
def install
|
871
|
+
Dir.chdir(rootdir) do
|
872
|
+
install_bin
|
873
|
+
install_ext
|
874
|
+
install_lib
|
875
|
+
install_data
|
876
|
+
install_man
|
877
|
+
install_doc
|
878
|
+
install_etc
|
879
|
+
prune_install_record
|
880
|
+
end
|
881
|
+
end
|
882
|
+
def install_bin
|
883
|
+
return unless directory?('bin')
|
884
|
+
report_transfer('bin', config.bindir)
|
885
|
+
files = files('bin')
|
886
|
+
install_files('bin', files, config.bindir, 0755)
|
887
|
+
end
|
888
|
+
def install_ext
|
889
|
+
return unless directory?('ext')
|
890
|
+
report_transfer('ext', config.sodir)
|
891
|
+
files = files('ext')
|
892
|
+
files = select_dllext(files)
|
893
|
+
files.each do |file|
|
894
|
+
name = File.join(File.dirname(File.dirname(file)), File.basename(file))
|
895
|
+
dest = destination(config.sodir, name)
|
896
|
+
install_file('ext', file, dest, 0555, install_prefix)
|
897
|
+
end
|
898
|
+
end
|
899
|
+
def install_lib
|
900
|
+
return unless directory?('lib')
|
901
|
+
report_transfer('lib', config.rbdir)
|
902
|
+
files = files('lib')
|
903
|
+
install_files('lib', files, config.rbdir, 0644)
|
904
|
+
end
|
905
|
+
def install_data
|
906
|
+
return unless directory?('data')
|
907
|
+
report_transfer('data', config.datadir)
|
908
|
+
files = files('data')
|
909
|
+
install_files('data', files, config.datadir, 0644)
|
910
|
+
end
|
911
|
+
def install_etc
|
912
|
+
return unless directory?('etc')
|
913
|
+
report_transfer('etc', config.sysconfdir)
|
914
|
+
files = files('etc')
|
915
|
+
install_files('etc', files, config.sysconfdir, 0644)
|
916
|
+
end
|
917
|
+
def install_man
|
918
|
+
return unless directory?('man')
|
919
|
+
report_transfer('man', config.mandir)
|
920
|
+
files = files('man')
|
921
|
+
install_files('man', files, config.mandir, 0644)
|
922
|
+
end
|
923
|
+
def install_doc
|
924
|
+
return unless config.doc?
|
925
|
+
return unless directory?('doc')
|
926
|
+
return unless project.name
|
927
|
+
dir = File.join(config.docdir, "ruby-{project.name}")
|
928
|
+
report_transfer('doc', dir)
|
929
|
+
files = files('doc')
|
930
|
+
install_files('doc', files, dir, 0644)
|
931
|
+
end
|
932
|
+
private
|
933
|
+
def report_transfer(source, directory)
|
934
|
+
unless quiet?
|
935
|
+
if install_prefix
|
936
|
+
out = File.join(install_prefix, directory)
|
937
|
+
else
|
938
|
+
out = directory
|
939
|
+
end
|
940
|
+
io.puts "* #{source} -> #{out}"
|
941
|
+
end
|
942
|
+
end
|
943
|
+
def directory?(path)
|
944
|
+
File.directory?(path)
|
945
|
+
end
|
946
|
+
def files(dir)
|
947
|
+
files = Dir["#{dir}/**/*"]
|
948
|
+
files = files.select{ |f| File.file?(f) }
|
949
|
+
files = files.map{ |f| f.sub("#{dir}/", '') }
|
950
|
+
files
|
951
|
+
end
|
952
|
+
def select_dllext(files)
|
953
|
+
ents = files.select do |file|
|
954
|
+
File.extname(file) == ".#{dllext}"
|
955
|
+
end
|
956
|
+
if ents.empty? && !files.empty?
|
957
|
+
raise Error, "ruby extention not compiled: 'setup.rb make' first"
|
958
|
+
end
|
959
|
+
ents
|
960
|
+
end
|
961
|
+
def dllext
|
962
|
+
config.dlext
|
963
|
+
end
|
964
|
+
def install_files(dir, list, dest, mode)
|
965
|
+
list.each do |fname|
|
966
|
+
rdest = destination(dest, fname)
|
967
|
+
install_file(dir, fname, rdest, mode, install_prefix)
|
968
|
+
end
|
969
|
+
end
|
970
|
+
def install_file(dir, from, dest, mode, prefix=nil)
|
971
|
+
mkdir_p(File.dirname(dest))
|
972
|
+
if trace? or trial?
|
973
|
+
io.puts "install #{dir}/#{from} #{dest}"
|
974
|
+
end
|
975
|
+
return if trial?
|
976
|
+
str = binread(File.join(dir, from))
|
977
|
+
if diff?(str, dest)
|
978
|
+
trace_off {
|
979
|
+
rm_f(dest) if File.exist?(dest)
|
980
|
+
}
|
981
|
+
File.open(dest, 'wb'){ |f| f.write(str) }
|
982
|
+
File.chmod(mode, dest)
|
983
|
+
end
|
984
|
+
record_installation(dest) # record file as installed
|
985
|
+
end
|
986
|
+
def mkdir_p(dirname) #, prefix=nil)
|
987
|
+
return if File.directory?(dirname)
|
988
|
+
io.puts "mkdir -p #{dirname}" if trace? or trial?
|
989
|
+
return if trial?
|
990
|
+
dirs = File.expand_path(dirname).split(%r<(?=/)>)
|
991
|
+
if /\A[a-z]:\z/i =~ dirs[0]
|
992
|
+
disk = dirs.shift
|
993
|
+
dirs[0] = disk + dirs[0]
|
994
|
+
end
|
995
|
+
dirs.each_index do |idx|
|
996
|
+
path = dirs[0..idx].join('')
|
997
|
+
unless File.dir?(path)
|
998
|
+
Dir.mkdir(path)
|
999
|
+
end
|
1000
|
+
record_installation(path) # record directories made
|
1001
|
+
end
|
1002
|
+
end
|
1003
|
+
def record_installation(path)
|
1004
|
+
File.open(install_record, 'a') do |f|
|
1005
|
+
f.puts(path)
|
1006
|
+
end
|
1007
|
+
end
|
1008
|
+
def prune_install_record
|
1009
|
+
entries = File.read(install_record).split("\n")
|
1010
|
+
entries.uniq!
|
1011
|
+
File.open(install_record, 'w') do |f|
|
1012
|
+
f << entries.join("\n")
|
1013
|
+
f << "\n"
|
1014
|
+
end
|
1015
|
+
end
|
1016
|
+
def install_record
|
1017
|
+
@install_record ||= (
|
1018
|
+
file = INSTALL_RECORD
|
1019
|
+
dir = File.dirname(file)
|
1020
|
+
unless File.directory?(dir)
|
1021
|
+
FileUtils.mkdir_p(dir)
|
1022
|
+
end
|
1023
|
+
file
|
1024
|
+
)
|
1025
|
+
end
|
1026
|
+
def destination(dir, file)
|
1027
|
+
dest = install_prefix ? File.join(install_prefix, File.expand_path(dir)) : dir
|
1028
|
+
dest = File.join(dest, file) #if File.dir?(dest)
|
1029
|
+
dest = File.expand_path(dest)
|
1030
|
+
dest
|
1031
|
+
end
|
1032
|
+
def diff?(new_content, path)
|
1033
|
+
return true unless File.exist?(path)
|
1034
|
+
new_content != binread(path)
|
1035
|
+
end
|
1036
|
+
def binread(fname)
|
1037
|
+
File.open(fname, 'rb') do |f|
|
1038
|
+
return f.read
|
1039
|
+
end
|
1040
|
+
end
|
1041
|
+
def install_shebang(files, dir)
|
1042
|
+
files.each do |file|
|
1043
|
+
path = File.join(dir, File.basename(file))
|
1044
|
+
update_shebang_line(path)
|
1045
|
+
end
|
1046
|
+
end
|
1047
|
+
def update_shebang_line(path)
|
1048
|
+
return if trial?
|
1049
|
+
return if config.shebang == 'never'
|
1050
|
+
old = Shebang.load(path)
|
1051
|
+
if old
|
1052
|
+
if old.args.size > 1
|
1053
|
+
$stderr.puts "warning: #{path}"
|
1054
|
+
$stderr.puts "Shebang line has too many args."
|
1055
|
+
$stderr.puts "It is not portable and your program may not work."
|
1056
|
+
end
|
1057
|
+
new = new_shebang(old)
|
1058
|
+
return if new.to_s == old.to_s
|
1059
|
+
else
|
1060
|
+
return unless config.shebang == 'all'
|
1061
|
+
new = Shebang.new(config.rubypath)
|
1062
|
+
end
|
1063
|
+
$stderr.puts "updating shebang: #{File.basename(path)}" if trace?
|
1064
|
+
open_atomic_writer(path) do |output|
|
1065
|
+
File.open(path, 'rb') do |f|
|
1066
|
+
f.gets if old # discard
|
1067
|
+
output.puts new.to_s
|
1068
|
+
output.print f.read
|
1069
|
+
end
|
1070
|
+
end
|
1071
|
+
end
|
1072
|
+
def new_shebang(old)
|
1073
|
+
if /\Aruby/ =~ File.basename(old.cmd)
|
1074
|
+
Shebang.new(config.rubypath, old.args)
|
1075
|
+
elsif File.basename(old.cmd) == 'env' and old.args.first == 'ruby'
|
1076
|
+
Shebang.new(config.rubypath, old.args[1..-1])
|
1077
|
+
else
|
1078
|
+
return old unless config.shebang == 'all'
|
1079
|
+
Shebang.new(config.rubypath)
|
1080
|
+
end
|
1081
|
+
end
|
1082
|
+
def open_atomic_writer(path, &block)
|
1083
|
+
tmpfile = File.basename(path) + '.tmp'
|
1084
|
+
begin
|
1085
|
+
File.open(tmpfile, 'wb', &block)
|
1086
|
+
File.rename tmpfile, File.basename(path)
|
1087
|
+
ensure
|
1088
|
+
File.unlink tmpfile if File.exist?(tmpfile)
|
1089
|
+
end
|
1090
|
+
end
|
1091
|
+
class Shebang
|
1092
|
+
def Shebang.load(path)
|
1093
|
+
line = nil
|
1094
|
+
File.open(path) {|f|
|
1095
|
+
line = f.gets
|
1096
|
+
}
|
1097
|
+
return nil unless /\A#!/ =~ line
|
1098
|
+
parse(line)
|
1099
|
+
end
|
1100
|
+
def Shebang.parse(line)
|
1101
|
+
cmd, *args = *line.strip.sub(/\A\#!/, '').split(' ')
|
1102
|
+
new(cmd, args)
|
1103
|
+
end
|
1104
|
+
def initialize(cmd, args = [])
|
1105
|
+
@cmd = cmd
|
1106
|
+
@args = args
|
1107
|
+
end
|
1108
|
+
attr_reader :cmd
|
1109
|
+
attr_reader :args
|
1110
|
+
def to_s
|
1111
|
+
"#! #{@cmd}" + (@args.empty? ? '' : " #{@args.join(' ')}")
|
1112
|
+
end
|
1113
|
+
end
|
1114
|
+
end
|
1115
|
+
end
|
1116
|
+
module Setup
|
1117
|
+
class Tester < Base
|
1118
|
+
RUBYSCRIPT = META_EXTENSION_DIR + '/testrc.rb'
|
1119
|
+
SHELLSCRIPT = 'script/test'
|
1120
|
+
def testable?
|
1121
|
+
return false if config.no_test
|
1122
|
+
return true if File.exist?(RUBYSCRIPT)
|
1123
|
+
return true if File.exist?(SHELLSCRIPT)
|
1124
|
+
false
|
1125
|
+
end
|
1126
|
+
def test
|
1127
|
+
return true if !testable?
|
1128
|
+
if File.exist?(RUBYSCRIPT)
|
1129
|
+
test_rubyscript
|
1130
|
+
elsif File.exist?(SHELLSCRIPT)
|
1131
|
+
test_shellscript
|
1132
|
+
end
|
1133
|
+
end
|
1134
|
+
def test_shellscript
|
1135
|
+
bash(SHELLSCRIPT)
|
1136
|
+
end
|
1137
|
+
def test_rubyscript
|
1138
|
+
ruby(RUBYSCRIPT)
|
1139
|
+
end
|
1140
|
+
end
|
1141
|
+
end
|
1142
|
+
module Setup
|
1143
|
+
class Uninstaller < Base
|
1144
|
+
def uninstall
|
1145
|
+
return unless File.exist?(INSTALL_RECORD)
|
1146
|
+
files = []
|
1147
|
+
dirs = []
|
1148
|
+
paths.each do |path|
|
1149
|
+
dirs << path if File.dir?(path)
|
1150
|
+
files << path if File.file?(path)
|
1151
|
+
end
|
1152
|
+
if dirs.empty? && files.empty?
|
1153
|
+
io.outs "Nothing to remove."
|
1154
|
+
return
|
1155
|
+
end
|
1156
|
+
files.sort!{ |a,b| b.size <=> a.size }
|
1157
|
+
dirs.sort!{ |a,b| b.size <=> a.size }
|
1158
|
+
if !force? && !trial?
|
1159
|
+
puts (files + dirs).collect{ |f| "#{f}" }.join("\n")
|
1160
|
+
puts
|
1161
|
+
puts "Must use --force option to remove these files and directories that become empty."
|
1162
|
+
return
|
1163
|
+
end
|
1164
|
+
files.each do |file|
|
1165
|
+
rm_f(file)
|
1166
|
+
end
|
1167
|
+
dirs.each do |dir|
|
1168
|
+
entries = Dir.entries(dir)
|
1169
|
+
entries.delete('.')
|
1170
|
+
entries.delete('..')
|
1171
|
+
rmdir(dir) if entries.empty?
|
1172
|
+
end
|
1173
|
+
rm_f(INSTALL_RECORD)
|
1174
|
+
end
|
1175
|
+
private
|
1176
|
+
def paths
|
1177
|
+
@paths ||= (
|
1178
|
+
lines = File.read(INSTALL_RECORD).split(/\s*\n/)
|
1179
|
+
lines = lines.map{ |line| line.strip }
|
1180
|
+
lines = lines.uniq
|
1181
|
+
lines = lines.reject{ |line| line.empty? } # skip blank lines
|
1182
|
+
lines = lines.reject{ |line| line[0,1] == '#' } # skip blank lines
|
1183
|
+
lines
|
1184
|
+
)
|
1185
|
+
end
|
1186
|
+
end
|
1187
|
+
end
|
1188
|
+
require 'optparse'
|
1189
|
+
module Setup
|
1190
|
+
class Command
|
1191
|
+
def self.run(*argv)
|
1192
|
+
new.run(*argv)
|
1193
|
+
end
|
1194
|
+
def self.tasks
|
1195
|
+
@tasks ||= {}
|
1196
|
+
end
|
1197
|
+
def self.order
|
1198
|
+
@order ||= []
|
1199
|
+
end
|
1200
|
+
def self.task(name, description)
|
1201
|
+
tasks[name] = description
|
1202
|
+
order << name
|
1203
|
+
end
|
1204
|
+
task 'all' , "config, setup, test, install"
|
1205
|
+
task 'config' , "saves your configuration"
|
1206
|
+
task 'show' , "show current configuration"
|
1207
|
+
task 'make' , "compile ruby extentions"
|
1208
|
+
task 'test' , "run test suite"
|
1209
|
+
task 'doc' , "generate ri documentation"
|
1210
|
+
task 'install' , "install project files"
|
1211
|
+
task 'uninstall', "uninstall previously installed files"
|
1212
|
+
task 'clean' , "does `make clean' for each extention"
|
1213
|
+
task 'distclean', "does `make distclean' for each extention"
|
1214
|
+
def run(*argv)
|
1215
|
+
ARGV.replace(argv) unless argv.empty?
|
1216
|
+
task = ARGV.find{ |a| a !~ /^[-]/ }
|
1217
|
+
task = 'all' unless task
|
1218
|
+
unless task_names.include?(task)
|
1219
|
+
$stderr.puts "Not a valid task -- #{task}"
|
1220
|
+
exit 1
|
1221
|
+
end
|
1222
|
+
parser = OptionParser.new
|
1223
|
+
options = {}
|
1224
|
+
parser.banner = "Usage: #{File.basename($0)} [TASK] [OPTIONS]"
|
1225
|
+
optparse_header(parser, options)
|
1226
|
+
case task
|
1227
|
+
when 'all'
|
1228
|
+
optparse_all(parser, options)
|
1229
|
+
when 'config'
|
1230
|
+
optparse_config(parser, options)
|
1231
|
+
when 'install'
|
1232
|
+
optparse_install(parser, options)
|
1233
|
+
end
|
1234
|
+
optparse_common(parser, options)
|
1235
|
+
begin
|
1236
|
+
parser.parse!(ARGV)
|
1237
|
+
rescue OptionParser::InvalidOption
|
1238
|
+
$stderr.puts $!.to_s.capitalize
|
1239
|
+
exit 1
|
1240
|
+
end
|
1241
|
+
rootdir = session.project.rootdir
|
1242
|
+
print_header
|
1243
|
+
begin
|
1244
|
+
session.__send__(task)
|
1245
|
+
rescue Error => err
|
1246
|
+
raise err if $DEBUG
|
1247
|
+
$stderr.puts $!.message
|
1248
|
+
$stderr.puts "Try 'setup.rb --help' for detailed usage."
|
1249
|
+
abort $!.message #exit 1
|
1250
|
+
end
|
1251
|
+
puts unless session.quiet?
|
1252
|
+
end
|
1253
|
+
def session
|
1254
|
+
@session ||= Session.new(:io=>$stdout)
|
1255
|
+
end
|
1256
|
+
def configuration
|
1257
|
+
@configuration ||= session.configuration
|
1258
|
+
end
|
1259
|
+
def optparse_header(parser, options)
|
1260
|
+
parser.banner = "USAGE: #{File.basename($0)} [command] [options]"
|
1261
|
+
end
|
1262
|
+
def optparse_all(parser, options)
|
1263
|
+
optparse_config(parser, options)
|
1264
|
+
end
|
1265
|
+
def optparse_config(parser, options)
|
1266
|
+
parser.separator ""
|
1267
|
+
parser.separator "Configuration options:"
|
1268
|
+
configuration.options.each do |args|
|
1269
|
+
args = args.dup
|
1270
|
+
desc = args.pop
|
1271
|
+
type = args.pop
|
1272
|
+
name, shortcut = *args
|
1273
|
+
optname = name.to_s.gsub('_', '-')
|
1274
|
+
case type
|
1275
|
+
when :bool
|
1276
|
+
if optname.index('no-') == 0
|
1277
|
+
optname = "[no-]" + optname.sub(/^no-/, '')
|
1278
|
+
opts = shortcut ? ["-#{shortcut}", "--#{optname}", desc] : ["--#{optname}", desc]
|
1279
|
+
parser.on(*opts) do |val|
|
1280
|
+
configuration.__send__("#{name}=", !val)
|
1281
|
+
end
|
1282
|
+
else
|
1283
|
+
optname = "[no-]" + optname.sub(/^no-/, '')
|
1284
|
+
opts = shortcut ? ["-#{shortcut}", "--#{optname}", desc] : ["--#{optname}", desc]
|
1285
|
+
parser.on(*opts) do |val|
|
1286
|
+
configuration.__send__("#{name}=", val)
|
1287
|
+
end
|
1288
|
+
end
|
1289
|
+
else
|
1290
|
+
opts = shortcut ? ["-#{shortcut}", "--#{optname} #{type.to_s.upcase}", desc] : ["--#{optname} #{type.to_s.upcase}", desc]
|
1291
|
+
parser.on(*opts) do |val|
|
1292
|
+
configuration.__send__("#{name}=", val)
|
1293
|
+
end
|
1294
|
+
end
|
1295
|
+
end
|
1296
|
+
end
|
1297
|
+
def optparse_install(parser, options)
|
1298
|
+
parser.separator ""
|
1299
|
+
parser.separator "Install options:"
|
1300
|
+
parser.on("--prefix PATH", "Installation prefix") do |val|
|
1301
|
+
configuration.install_prefix = val
|
1302
|
+
end
|
1303
|
+
end
|
1304
|
+
def optparse_common(parser, options)
|
1305
|
+
parser.separator ""
|
1306
|
+
parser.separator "General options:"
|
1307
|
+
parser.on("-q", "--quiet", "Suppress output") do
|
1308
|
+
session.quiet = true
|
1309
|
+
end
|
1310
|
+
parser.on("-f", "--force", "Force operation") do
|
1311
|
+
session.force = true
|
1312
|
+
end
|
1313
|
+
parser.on("--trace", "--verbose", "Watch execution") do |val|
|
1314
|
+
session.trace = true
|
1315
|
+
end
|
1316
|
+
parser.on("--trial", "--no-harm", "Do not write to disk") do |val|
|
1317
|
+
session.trial = true
|
1318
|
+
end
|
1319
|
+
parser.on("--debug", "Turn on debug mode") do |val|
|
1320
|
+
$DEBUG = true
|
1321
|
+
end
|
1322
|
+
parser.separator ""
|
1323
|
+
parser.separator "Inform options:"
|
1324
|
+
parser.on_tail("-h", "--help", "display this help information") do
|
1325
|
+
puts parser
|
1326
|
+
exit
|
1327
|
+
end
|
1328
|
+
parser.on_tail("--version", "-v", "Show version") do
|
1329
|
+
puts File.basename($0) + ' v' + Setup::VERSION #Version.join('.')
|
1330
|
+
exit
|
1331
|
+
end
|
1332
|
+
parser.on_tail("--copyright", "Show copyright") do
|
1333
|
+
puts Setup::COPYRIGHT #opyright
|
1334
|
+
exit
|
1335
|
+
end
|
1336
|
+
end
|
1337
|
+
def task_names
|
1338
|
+
self.class.tasks.keys
|
1339
|
+
end
|
1340
|
+
def print_header
|
1341
|
+
end
|
1342
|
+
end
|
1343
|
+
end
|
1344
|
+
Setup::Command.run
|