setup 4.2.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/HISTORY +47 -3
  2. data/MANIFEST +49 -16
  3. data/README.rdoc +148 -0
  4. data/bin/setup.rb +1 -5
  5. data/lib/setup.rb +2 -2
  6. data/lib/setup/base.rb +143 -0
  7. data/lib/setup/command.rb +218 -114
  8. data/lib/setup/compiler.rb +69 -0
  9. data/lib/setup/configuration.rb +822 -0
  10. data/lib/setup/constants.rb +12 -0
  11. data/lib/setup/{rubyver.rb → core_ext.rb} +0 -0
  12. data/lib/setup/documentor.rb +149 -0
  13. data/lib/setup/installer.rb +363 -0
  14. data/lib/setup/project.rb +68 -0
  15. data/lib/setup/rake.rb +44 -45
  16. data/lib/setup/session.rb +233 -0
  17. data/lib/setup/tester.rb +92 -0
  18. data/lib/setup/uninstaller.rb +76 -0
  19. data/meta/active +1 -0
  20. data/meta/collection +1 -0
  21. data/meta/{abstract → description} +0 -0
  22. data/meta/{package → name} +0 -0
  23. data/meta/repository +1 -0
  24. data/meta/ruby +3 -0
  25. data/meta/version +1 -1
  26. data/script/bstrap +5 -0
  27. data/script/bundle +64 -0
  28. data/script/setup +1338 -0
  29. data/script/test +3 -0
  30. data/test/cases/installer.rb +28 -0
  31. data/test/features/config.feature +16 -0
  32. data/test/features/document.feature +2 -0
  33. data/test/features/install.feature +72 -0
  34. data/test/features/make.feature +18 -0
  35. data/test/features/step_definitions/common_steps.rb +34 -0
  36. data/test/features/step_definitions/config_steps.rb +24 -0
  37. data/test/features/step_definitions/env.rb +37 -0
  38. data/test/features/step_definitions/install_steps.rb +75 -0
  39. data/test/features/step_definitions/setup_steps.rb +30 -0
  40. data/test/features/step_definitions/uninstall_steps.rb +8 -0
  41. data/test/features/test.feature +2 -0
  42. data/test/features/uninstall.feature +13 -0
  43. data/test/fixtures/faux-project/bin/faux +3 -0
  44. data/test/fixtures/faux-project/ext/faux/extconf.rb +12 -0
  45. data/test/fixtures/faux-project/ext/faux/faux.c +24 -0
  46. data/test/fixtures/faux-project/lib/faux.rb +1 -0
  47. metadata +58 -29
  48. data/README +0 -106
  49. data/RELEASE +0 -41
  50. data/lib/setup/build.rb +0 -2
  51. data/lib/setup/config.rb +0 -452
  52. data/lib/setup/error.rb +0 -4
  53. data/lib/setup/install.rb +0 -1007
  54. data/meta/setup/metaconfig.rb +0 -3
  55. data/test/test_installer.rb +0 -139
@@ -0,0 +1,76 @@
1
+ require 'setup/base'
2
+
3
+ module Setup
4
+
5
+ # TODO: It would be nice to improve this such that
6
+ # files to be removed are taken out of the list of
7
+ # directories that may be removed when they become
8
+ # empty. That way the end-user can see an exact list
9
+ # before commiting to the uninstall (using --force).
10
+ #
11
+ class Uninstaller < Base
12
+
13
+ #
14
+ def uninstall
15
+ return unless File.exist?(INSTALL_RECORD)
16
+
17
+ files = []
18
+ dirs = []
19
+
20
+ paths.each do |path|
21
+ dirs << path if File.dir?(path)
22
+ files << path if File.file?(path)
23
+ end
24
+
25
+ if dirs.empty? && files.empty?
26
+ io.outs "Nothing to remove."
27
+ return
28
+ end
29
+
30
+ files.sort!{ |a,b| b.size <=> a.size }
31
+ dirs.sort!{ |a,b| b.size <=> a.size }
32
+
33
+ if !force? && !trial?
34
+ puts (files + dirs).collect{ |f| "#{f}" }.join("\n")
35
+ puts
36
+ puts "Must use --force option to remove these files and directories that become empty."
37
+ return
38
+ end
39
+
40
+ files.each do |file|
41
+ rm_f(file)
42
+ end
43
+
44
+ dirs.each do |dir|
45
+ entries = Dir.entries(dir)
46
+ entries.delete('.')
47
+ entries.delete('..')
48
+
49
+ #begin
50
+ rmdir(dir) if entries.empty?
51
+ #rescue Errno::ENOTEMPTY
52
+ # io.puts "not empty -- #{dir}"
53
+ #end
54
+ end
55
+
56
+ rm_f(INSTALL_RECORD)
57
+ end
58
+
59
+ private
60
+
61
+ # path list from install record
62
+ def paths
63
+ @paths ||= (
64
+ lines = File.read(INSTALL_RECORD).split(/\s*\n/)
65
+ lines = lines.map{ |line| line.strip }
66
+ lines = lines.uniq
67
+ lines = lines.reject{ |line| line.empty? } # skip blank lines
68
+ lines = lines.reject{ |line| line[0,1] == '#' } # skip blank lines
69
+ lines
70
+ )
71
+ end
72
+
73
+ end
74
+
75
+ end
76
+
@@ -0,0 +1 @@
1
+ false
@@ -0,0 +1 @@
1
+ proutils
File without changes
File without changes
@@ -0,0 +1 @@
1
+ git://github.com/proutils/setup.git
@@ -0,0 +1,3 @@
1
+ ---
2
+ - 1.8.6
3
+ - 1.8.7
@@ -1 +1 @@
1
- 4.2.0
1
+ 5.0.0
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift('lib')
3
+ require 'setup/command'
4
+ Setup::Command.run(*ARGV)
5
+
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ raise "Not the right place #{Dir.pwd}" unless File.directory?('lib')
4
+
5
+ #scripts = (Dir['lib/*.rb'] + Dir['lib/**/*']).uniq
6
+ #scripts = scripts.reject{ |f| File.directory?(f) }
7
+ # We don't want the rake helper.
8
+ #scripts = scripts - ["lib/setup/rake.rb"]
9
+ #scripts = scripts + ["bin/setup.rb"]
10
+
11
+ scripts = %w{
12
+ lib/setup.rb
13
+ lib/setup/core_ext.rb
14
+ lib/setup/constants.rb
15
+ lib/setup/project.rb
16
+ lib/setup/session.rb
17
+ lib/setup/base.rb
18
+ lib/setup/compiler.rb
19
+ lib/setup/configuration.rb
20
+ lib/setup/documentor.rb
21
+ lib/setup/installer.rb
22
+ lib/setup/tester.rb
23
+ lib/setup/uninstaller.rb
24
+ lib/setup/command.rb
25
+ bin/setup.rb
26
+ }
27
+
28
+ comment = <<-HERE
29
+ #
30
+ # Setup.rb, #{Time.now.strftime("%Y-%m-%d %H:%M:%S")}
31
+ #
32
+ # This is a stand-alone bundle of the setup.rb application.
33
+ # You can place it in your projects script/ directory, or
34
+ # rename it to 'setup.rb' and place it in your project's
35
+ # root directory (just like old times).
36
+ #
37
+ HERE
38
+
39
+ #
40
+ bundle = ""
41
+
42
+ # insert scripts
43
+ scripts.each do |script|
44
+ bundle << "\n\n# %-16s #{"#" * 60}\n\n" % File.basename(script)
45
+ bundle << File.read(script)
46
+ end
47
+
48
+ # remove setup requires
49
+ bundle.gsub!(/require\s+["']setup\/(.*?)["']\s*$/, '')
50
+
51
+ # remove blank lines
52
+ bundle.gsub!(/^\s*\n/, '')
53
+
54
+ # remove comments
55
+ bundle.gsub!(/^\s*\#.*?\n/, '')
56
+
57
+ # save
58
+ File.open('script/setup', 'w') do |f|
59
+ f << "#!/usr/bin/env ruby\n"
60
+ f << comment
61
+ f << bundle
62
+ end
63
+
64
+ FileUtils.chmod(0744, 'script/setup')
@@ -0,0 +1,1338 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Setup.rb, 2010-01-13 04:14:39
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.0'
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 = 'InstalledFiles' #'.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 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 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
+ module Setup
331
+ class Configuration
332
+ RBCONFIG = ::Config::CONFIG
333
+ CONFIG_FILE = 'SetupConfig' # '.cache/setup/config'
334
+ META_CONFIG_FILE = META_EXTENSION_DIR + '/configuration.rb'
335
+ def self.options
336
+ @@options ||= []
337
+ end
338
+ def self.option(name, *args) #type, description)
339
+ options << [name.to_s, *args] #type, description]
340
+ attr_accessor(name)
341
+ end
342
+ option :prefix , :path, 'path prefix of target environment'
343
+ option :bindir , :path, 'directory for commands'
344
+ option :libdir , :path, 'directory for libraries'
345
+ option :datadir , :path, 'directory for shared data'
346
+ option :mandir , :path, 'directory for man pages'
347
+ option :docdir , :path, 'directory for documentation'
348
+ option :rbdir , :path, 'directory for ruby scripts'
349
+ option :sodir , :path, 'directory for ruby extentions'
350
+ option :sysconfdir , :path, 'directory for system configuration files'
351
+ option :localstatedir , :path, 'directory for local state data'
352
+ option :libruby , :path, 'directory for ruby libraries'
353
+ option :librubyver , :path, 'directory for standard ruby libraries'
354
+ option :librubyverarch , :path, 'directory for standard ruby extensions'
355
+ option :siteruby , :path, 'directory for version-independent aux ruby libraries'
356
+ option :siterubyver , :path, 'directory for aux ruby libraries'
357
+ option :siterubyverarch , :path, 'directory for aux ruby binaries'
358
+ option :rubypath , :prog, 'path to set to #! line'
359
+ option :rubyprog , :prog, 'ruby program used for installation'
360
+ option :makeprog , :prog, 'make program to compile ruby extentions'
361
+ option :extconfopt , :opts, 'options to pass-thru to extconf.rb'
362
+ option :shebang , :pick, 'shebang line (#!) editing mode (all,ruby,never)'
363
+ option :no_test, :t , :bool, 'run pre-installation tests'
364
+ option :no_ri, :d , :bool, 'generate ri documentation'
365
+ option :no_doc, , :bool, 'install doc/ directory'
366
+ option :no_ext , :bool, 'compile/install ruby extentions'
367
+ option :install_prefix , :path, 'install to alternate root location'
368
+ option :root , :path, 'install to alternate root location'
369
+ option :installdirs , :pick, 'install location mode (site,std,home)' #, local)
370
+ option :type , :pick, 'install location mode (site,std,home)'
371
+ ::Config::CONFIG.each do |key,val|
372
+ next if key == "configure_args"
373
+ name = key.to_s.downcase
374
+ define_method(name){ val }
375
+ end
376
+ ::Config::CONFIG["configure_args"].each do |ent|
377
+ key, val = *ent.split("=")
378
+ name = key.downcase
379
+ name = name.sub(/^--/,'')
380
+ name = name.gsub(/-/,'_')
381
+ define_method(name){ val }
382
+ end
383
+ def options
384
+ self.class.options
385
+ end
386
+ def initialize(values={})
387
+ initialize_metaconfig
388
+ initialize_defaults
389
+ initialize_environment
390
+ initialize_configfile
391
+ values.each{ |k,v| __send__("#{k}=", v) }
392
+ yeild(self) if block_given?
393
+ end
394
+ def initialize_metaconfig
395
+ if File.exist?(META_CONFIG_FILE)
396
+ script = File.read(META_CONFIG_FILE)
397
+ (class << self; self; end).class_eval(script)
398
+ end
399
+ end
400
+ def initialize_defaults
401
+ self.type = 'site'
402
+ self.no_ri = true
403
+ self.no_test = true
404
+ self.no_doc = false
405
+ self.no_ext = false
406
+ end
407
+ def initialize_environment
408
+ options.each do |name, *args|
409
+ if value = ENV["RUBYSETUP_#{name.to_s.upcase}"]
410
+ __send__("#{name}=", value)
411
+ end
412
+ end
413
+ end
414
+ def initialize_configfile
415
+ if File.exist?(CONFIG_FILE)
416
+ erb = ERB.new(File.read(CONFIG_FILE))
417
+ txt = erb.result(binding)
418
+ dat = YAML.load(txt)
419
+ dat.each do |k, v|
420
+ next if 'type' == k
421
+ next if 'installdirs' == k
422
+ k = k.gsub('-','_')
423
+ __send__("#{k}=", v)
424
+ end
425
+ if dat['type']
426
+ self.type = dat['type']
427
+ end
428
+ if dat['installdirs']
429
+ self.installdirs = dat['installdirs']
430
+ end
431
+ end
432
+ end
433
+ def base_bindir
434
+ @base_bindir ||= subprefix('bindir')
435
+ end
436
+ def base_libdir
437
+ @base_libdir ||= subprefix('libdir')
438
+ end
439
+ def base_datadir
440
+ @base_datadir ||= subprefix('datadir')
441
+ end
442
+ def base_mandir
443
+ @base_mandir ||= subprefix('mandir')
444
+ end
445
+ def base_docdir
446
+ @base_docdir || File.dirname(subprefix('docdir'))
447
+ end
448
+ def base_rubylibdir
449
+ @rubylibdir ||= subprefix('rubylibdir')
450
+ end
451
+ def base_rubyarchdir
452
+ @base_rubyarchdir ||= subprefix('archdir')
453
+ end
454
+ def base_sysconfdir
455
+ @base_sysconfdir ||= subprefix('sysconfdir')
456
+ end
457
+ def base_localstatedir
458
+ @base_localstatedir ||= subprefix('localstatedir')
459
+ end
460
+ def type
461
+ @type ||= 'site'
462
+ end
463
+ def type=(val)
464
+ @type = val
465
+ case val.to_s
466
+ when 'std', 'ruby'
467
+ @rbdir = librubyver #'$librubyver'
468
+ @sodir = librubyverarch #'$librubyverarch'
469
+ when 'site'
470
+ @rbdir = siterubyver #'$siterubyver'
471
+ @sodir = siterubyverarch #'$siterubyverarch'
472
+ when 'home'
473
+ self.prefix = File.join(home, '.local') # TODO: Use XDG
474
+ @rbdir = nil #'$libdir/ruby'
475
+ @sodir = nil #'$libdir/ruby'
476
+ else
477
+ raise Error, "bad config: use type=(std|site|home) [#{val}]"
478
+ end
479
+ end
480
+ alias_method :installdirs, :type
481
+ alias_method :installdirs=, :type=
482
+ alias_method :install_prefix, :root
483
+ alias_method :install_prefix=, :root=
484
+ def prefix
485
+ @prefix ||= RBCONFIG['prefix']
486
+ end
487
+ def prefix=(path)
488
+ @prefix = pathname(path)
489
+ end
490
+ def libruby
491
+ @libruby ||= RBCONFIG['prefix'] + "/lib/ruby"
492
+ end
493
+ def libruby=(path)
494
+ path = pathname(path)
495
+ @librubyver = librubyver.sub(libruby, path)
496
+ @librubyverarch = librubyverarch.sub(libruby, path)
497
+ @libruby = path
498
+ end
499
+ def librubyver
500
+ @librubyver ||= RBCONFIG['rubylibdir']
501
+ end
502
+ def librubyver=(path)
503
+ @librubyver = pathname(path)
504
+ end
505
+ def librubyverarch
506
+ @librubyverarch ||= RBCONFIG['archdir']
507
+ end
508
+ def librubyverarch=(path)
509
+ @librubyverarch = pathname(path)
510
+ end
511
+ def siteruby
512
+ @siteruby ||= RBCONFIG['sitedir']
513
+ end
514
+ def siteruby=(path)
515
+ path = pathname(path)
516
+ @siterubyver = siterubyver.sub(siteruby, path)
517
+ @siterubyverarch = siterubyverarch.sub(siteruby, path)
518
+ @siteruby = path
519
+ end
520
+ def siterubyver
521
+ @siterubyver ||= RBCONFIG['sitelibdir']
522
+ end
523
+ def siterubyver=(path)
524
+ @siterubyver = pathname(path)
525
+ end
526
+ def siterubyverarch
527
+ @siterubyverarch ||= RBCONFIG['sitearchdir']
528
+ end
529
+ def siterubyverarch=(path)
530
+ @siterubyverarch = pathname(path)
531
+ end
532
+ def bindir
533
+ @bindir || File.join(prefix, base_bindir)
534
+ end
535
+ def bindir=(path)
536
+ @bindir = pathname(path)
537
+ end
538
+ def libdir
539
+ @libdir || File.join(prefix, base_libdir)
540
+ end
541
+ def libdir=(path)
542
+ @libdir = pathname(path)
543
+ end
544
+ def datadir
545
+ @datadir || File.join(prefix, base_datadir)
546
+ end
547
+ def datadir=(path)
548
+ @datadir = pathname(path)
549
+ end
550
+ def mandir
551
+ @mandir || File.join(prefix, base_mandir)
552
+ end
553
+ def mandir=(path)
554
+ @mandir = pathname(path)
555
+ end
556
+ def docdir
557
+ @docdir || File.join(prefix, base_docdir)
558
+ end
559
+ def docdir=(path)
560
+ @docdir = pathname(path)
561
+ end
562
+ def rbdir
563
+ @rbdir || File.join(prefix, base_rubylibdir)
564
+ end
565
+ def sodir
566
+ @sodir || File.join(prefix, base_rubyarchdir)
567
+ end
568
+ def sysconfdir
569
+ @sysconfdir ||= base_sysconfdir
570
+ end
571
+ def sysconfdir=(path)
572
+ @sysconfdir = pathname(path)
573
+ end
574
+ def localstatedir
575
+ @localstatedir ||= base_localstatedir
576
+ end
577
+ def localstatedir=(path)
578
+ @localstatedir = pathname(path)
579
+ end
580
+ def rubypath
581
+ @rubypath ||= File.join(RBCONFIG['bindir'], RBCONFIG['ruby_install_name'] + RBCONFIG['EXEEXT'])
582
+ end
583
+ def rubypath=(path)
584
+ @rubypath = pathname(path)
585
+ end
586
+ def rubyprog
587
+ @rubyprog || rubypath
588
+ end
589
+ def rubyprog=(command)
590
+ @rubyprog = command
591
+ end
592
+ def makeprog
593
+ @makeprog ||= (
594
+ if arg = RBCONFIG['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg }
595
+ arg.sub(/'/, '').split(/=/, 2)[1]
596
+ else
597
+ 'make'
598
+ end
599
+ )
600
+ end
601
+ def makeprog=(command)
602
+ @makeprog = command
603
+ end
604
+ def extconfopt
605
+ @extconfopt ||= ''
606
+ end
607
+ def extconfopt=(string)
608
+ @extconfopt = string
609
+ end
610
+ def shebang
611
+ @shebang ||= 'ruby'
612
+ end
613
+ def shebang=(val)
614
+ if %w(all ruby never).include?(val)
615
+ @shebang = val
616
+ else
617
+ raise Error, "bad config: use SHEBANG=(all|ruby|never) [#{val}]"
618
+ end
619
+ end
620
+ def no_ext
621
+ @no_ext
622
+ end
623
+ def no_ext=(val)
624
+ @no_ext = boolean(val)
625
+ end
626
+ def no_test
627
+ @no_test
628
+ end
629
+ def no_test=(val)
630
+ @no_test = boolean(val)
631
+ end
632
+ def no_doc
633
+ @no_doc
634
+ end
635
+ def no_doc=(val)
636
+ @no_doc = boolean(val)
637
+ end
638
+ def no_ri
639
+ @no_ri
640
+ end
641
+ def no_ri=(val)
642
+ @no_ri = boolean(val)
643
+ end
644
+ def compile?
645
+ !no_ext
646
+ end
647
+ def test?
648
+ !no_test
649
+ end
650
+ def ri?
651
+ !no_ri
652
+ end
653
+ def doc?
654
+ !no_doc
655
+ end
656
+ def to_h
657
+ h = {}
658
+ options.each do |name, *args|
659
+ h[name.to_s] = __send__(name)
660
+ end
661
+ h
662
+ end
663
+ def to_s
664
+ to_yaml.sub(/\A---\s*\n/,'')
665
+ end
666
+ def to_yaml(*args)
667
+ to_h.to_yaml(*args)
668
+ end
669
+ def save_config
670
+ out = to_yaml
671
+ if not File.exist?(File.dirname(CONFIG_FILE))
672
+ FileUtils.mkdir_p(File.dirname(CONFIG_FILE))
673
+ end
674
+ if File.exist?(CONFIG_FILE)
675
+ txt = File.read(CONFIG_FILE)
676
+ return nil if txt == out
677
+ end
678
+ File.open(CONFIG_FILE, 'w'){ |f| f << out }
679
+ true
680
+ end
681
+ def exist?
682
+ File.exist?(CONFIG_FILE)
683
+ end
684
+ private
685
+ def pathname(path)
686
+ path.gsub(%r<\\$([^/]+)>){ self[$1] }
687
+ end
688
+ def boolean(val, name=nil)
689
+ case val
690
+ when true, false, nil
691
+ val
692
+ else
693
+ case val.to_s.downcase
694
+ when 'y', 'yes', 't', 'true'
695
+ true
696
+ when 'n', 'no', 'f', 'false'
697
+ false
698
+ else
699
+ raise Error, "bad config: use --#{name}=(yes|no) [\#{val}]"
700
+ end
701
+ end
702
+ end
703
+ def subprefix(path, with='')
704
+ val = RBCONFIG[path]
705
+ raise "Unknown path -- #{path}" if val.nil?
706
+ prefix = Regexp.quote(RBCONFIG['prefix'])
707
+ val.sub(/\A#{prefix}/, with)
708
+ end
709
+ def home
710
+ ENV['HOME'] || raise(Error, 'HOME is not set.')
711
+ end
712
+ end #class ConfigTable
713
+ end #module Setup
714
+ =begin
715
+ def inintialize_metaconfig
716
+ path = Dir.glob(METACONFIG_FILE).first
717
+ if path && File.file?(path)
718
+ MetaConfigEnvironment.new(self).instance_eval(File.read(path), path)
719
+ end
720
+ end
721
+ class MetaConfigEnvironment
722
+ def initialize(config) #, installer)
723
+ @config = config
724
+ end
725
+ def config_names
726
+ @config.descriptions.collect{ |n, t, d| n.to_s }
727
+ end
728
+ def config?(name)
729
+ @config.descriptions.find do |sym, type, desc|
730
+ sym.to_s == name.to_s
731
+ end
732
+ end
733
+ def bool_config?(name)
734
+ @config.descriptions.find do |sym, type, desc|
735
+ sym.to_s == name.to_s && type == :bool
736
+ end
737
+ end
738
+ def path_config?(name)
739
+ @config.descriptions.find do |sym, type, desc|
740
+ sym.to_s == name.to_s && type == :path
741
+ end
742
+ end
743
+ def value_config?(name)
744
+ @config.descriptions.find do |sym, type, desc|
745
+ sym.to_s == name.to_s && type != :prog
746
+ end
747
+ end
748
+ def add_config(name, default, desc)
749
+ @config.descriptions << [name.to_sym, nil, desc]
750
+ end
751
+ def add_bool_config(name, default, desc)
752
+ @config.descriptions << [name.to_sym, :bool, desc]
753
+ end
754
+ def add_path_config(name, default, desc)
755
+ @config.descriptions << [name.to_sym, :path, desc]
756
+ end
757
+ def set_config_default(name, default)
758
+ @config[name] = default
759
+ end
760
+ def remove_config(name)
761
+ item = @config.descriptions.find do |sym, type, desc|
762
+ sym.to_s == name.to_s
763
+ end
764
+ index = @config.descriptions.index(item)
765
+ @config.descriptions.delete(index)
766
+ end
767
+ end
768
+ =end
769
+ module Setup
770
+ class Documentor < Base
771
+ def document
772
+ return if config.no_doc
773
+ exec_ri
774
+ end
775
+ def exec_ri
776
+ case config.type #installdirs
777
+ when 'std', 'ruby'
778
+ output = "--ri-site"
779
+ when 'site'
780
+ output = "--ri-site"
781
+ when 'home'
782
+ output = "--ri"
783
+ else
784
+ abort "bad config: should not be possible -- type=#{config.type}"
785
+ end
786
+ if File.exist?('.document')
787
+ files = File.read('.document').split("\n")
788
+ files.reject!{ |l| l =~ /^\s*[#]/ || l !~ /\S/ }
789
+ files.collect!{ |f| f.strip }
790
+ else
791
+ files = []
792
+ files << 'lib' if File.directory?('lib')
793
+ files << 'ext' if File.directory?('ext')
794
+ end
795
+ opt = []
796
+ opt << "-U"
797
+ opt << "-q" #if quiet?
798
+ opt << output
799
+ opt << files
800
+ opt = opt.flatten
801
+ cmd = "rdoc " + opt.join(' ')
802
+ if trial?
803
+ puts cmd
804
+ else
805
+ begin
806
+ success = system(cmd)
807
+ raise unless success
808
+ io.puts "Ok ri." #unless quiet?
809
+ rescue Exception
810
+ $stderr.puts "ri generation failed"
811
+ $stderr.puts "command was: '#{cmd}'"
812
+ end
813
+ end
814
+ end
815
+ def exec_rdoc
816
+ main = Dir.glob("README{,.*}", File::FNM_CASEFOLD).first
817
+ if File.exist?('.document')
818
+ files = File.read('.document').split("\n")
819
+ files.reject!{ |l| l =~ /^\s*[#]/ || l !~ /\S/ }
820
+ files.collect!{ |f| f.strip }
821
+ else
822
+ files = []
823
+ files << main if main
824
+ files << 'lib' if File.directory?('lib')
825
+ files << 'ext' if File.directory?('ext')
826
+ end
827
+ checkfiles = (files + files.map{ |f| Dir[File.join(f,'*','**')] }).flatten.uniq
828
+ if FileUtils.uptodate?('doc/rdoc', checkfiles)
829
+ puts "RDocs look current."
830
+ return
831
+ end
832
+ output = 'doc/rdoc'
833
+ title = (PACKAGE.capitalize + " API").strip if PACKAGE
834
+ template = config.doctemplate || 'html'
835
+ opt = []
836
+ opt << "-U"
837
+ opt << "-q" #if quiet?
838
+ opt << "--op=#{output}"
839
+ opt << "--title=#{title}"
840
+ opt << "--main=#{main}" if main
841
+ opt << files
842
+ opt = opt.flatten
843
+ cmd = "rdoc " + opt.join(' ')
844
+ if trial?
845
+ puts cmd
846
+ else
847
+ begin
848
+ system(cmd)
849
+ puts "Ok rdoc." unless quiet?
850
+ rescue Exception
851
+ puts "Fail rdoc."
852
+ puts "Command was: '#{cmd}'"
853
+ puts "Proceeding with install anyway."
854
+ end
855
+ end
856
+ end
857
+ end
858
+ end
859
+ module Setup
860
+ class Installer < Base
861
+ def install_prefix
862
+ config.install_prefix
863
+ end
864
+ def install
865
+ Dir.chdir(rootdir) do
866
+ install_bin
867
+ install_ext
868
+ install_lib
869
+ install_data
870
+ install_man
871
+ install_doc
872
+ install_etc
873
+ prune_install_record
874
+ end
875
+ end
876
+ def install_bin
877
+ return unless directory?('bin')
878
+ report_transfer('bin', config.bindir)
879
+ files = files('bin')
880
+ install_files('bin', files, config.bindir, 0755)
881
+ end
882
+ def install_ext
883
+ return unless directory?('ext')
884
+ report_transfer('ext', config.sodir)
885
+ files = files('ext')
886
+ files = select_dllext(files)
887
+ files.each do |file|
888
+ name = File.join(File.dirname(File.dirname(file)), File.basename(file))
889
+ dest = destination(config.sodir, name)
890
+ install_file('ext', file, dest, 0555, install_prefix)
891
+ end
892
+ end
893
+ def install_lib
894
+ return unless directory?('lib')
895
+ report_transfer('lib', config.rbdir)
896
+ files = files('lib')
897
+ install_files('lib', files, config.rbdir, 0644)
898
+ end
899
+ def install_data
900
+ return unless directory?('data')
901
+ report_transfer('data', config.datadir)
902
+ files = files('data')
903
+ install_files('data', files, config.datadir, 0644)
904
+ end
905
+ def install_etc
906
+ return unless directory?('etc')
907
+ report_transfer('etc', config.sysconfdir)
908
+ files = files('etc')
909
+ install_files('etc', files, config.sysconfdir, 0644)
910
+ end
911
+ def install_man
912
+ return unless directory?('man')
913
+ report_transfer('man', config.mandir)
914
+ files = files('man')
915
+ install_files('man', files, config.mandir, 0644)
916
+ end
917
+ def install_doc
918
+ return unless config.doc?
919
+ return unless directory?('doc')
920
+ return unless project.name
921
+ dir = File.join(config.docdir, "ruby-{project.name}")
922
+ report_transfer('doc', dir)
923
+ files = files('doc')
924
+ install_files('doc', files, dir, 0644)
925
+ end
926
+ private
927
+ def report_transfer(source, directory)
928
+ unless quiet?
929
+ if install_prefix
930
+ out = File.join(install_prefix, directory)
931
+ else
932
+ out = directory
933
+ end
934
+ io.puts "* #{source} -> #{out}"
935
+ end
936
+ end
937
+ def directory?(path)
938
+ File.directory?(path)
939
+ end
940
+ def files(dir)
941
+ files = Dir["#{dir}/**/*"]
942
+ files = files.select{ |f| File.file?(f) }
943
+ files = files.map{ |f| f.sub("#{dir}/", '') }
944
+ files
945
+ end
946
+ def select_dllext(files)
947
+ ents = files.select do |file|
948
+ File.extname(file) == ".#{dllext}"
949
+ end
950
+ if ents.empty? && !files.empty?
951
+ raise Error, "ruby extention not compiled: 'setup.rb setup' first"
952
+ end
953
+ ents
954
+ end
955
+ def dllext
956
+ config.dlext
957
+ end
958
+ def install_files(dir, list, dest, mode)
959
+ list.each do |fname|
960
+ rdest = destination(dest, fname)
961
+ install_file(dir, fname, rdest, mode, install_prefix)
962
+ end
963
+ end
964
+ def install_file(dir, from, dest, mode, prefix=nil)
965
+ mkdir_p(File.dirname(dest))
966
+ if trace? or trial?
967
+ io.puts "install #{dir}/#{from} #{dest}"
968
+ end
969
+ return if trial?
970
+ str = binread(File.join(dir, from))
971
+ if diff?(str, dest)
972
+ trace_off {
973
+ rm_f(dest) if File.exist?(dest)
974
+ }
975
+ File.open(dest, 'wb'){ |f| f.write(str) }
976
+ File.chmod(mode, dest)
977
+ end
978
+ record_installation(dest) # record file as installed
979
+ end
980
+ def mkdir_p(dirname) #, prefix=nil)
981
+ return if File.directory?(dirname)
982
+ io.puts "mkdir -p #{dirname}" if trace? or trial?
983
+ return if trial?
984
+ dirs = File.expand_path(dirname).split(%r<(?=/)>)
985
+ if /\A[a-z]:\z/i =~ dirs[0]
986
+ disk = dirs.shift
987
+ dirs[0] = disk + dirs[0]
988
+ end
989
+ dirs.each_index do |idx|
990
+ path = dirs[0..idx].join('')
991
+ unless File.dir?(path)
992
+ Dir.mkdir(path)
993
+ end
994
+ record_installation(path) # record directories made
995
+ end
996
+ end
997
+ def record_installation(path)
998
+ File.open(install_record, 'a') do |f|
999
+ f.puts(path)
1000
+ end
1001
+ end
1002
+ def prune_install_record
1003
+ entries = File.read(install_record).split("\n")
1004
+ entries.uniq!
1005
+ File.open(install_record, 'w') do |f|
1006
+ f << entries.join("\n")
1007
+ f << "\n"
1008
+ end
1009
+ end
1010
+ def install_record
1011
+ @install_record ||= (
1012
+ file = INSTALL_RECORD
1013
+ dir = File.dirname(file)
1014
+ unless File.directory?(dir)
1015
+ FileUtils.mkdir_p(dir)
1016
+ end
1017
+ file
1018
+ )
1019
+ end
1020
+ def destination(dir, file)
1021
+ dest = install_prefix ? File.join(install_prefix, File.expand_path(dir)) : dir
1022
+ dest = File.join(dest, file) #if File.dir?(dest)
1023
+ dest = File.expand_path(dest)
1024
+ dest
1025
+ end
1026
+ def diff?(new_content, path)
1027
+ return true unless File.exist?(path)
1028
+ new_content != binread(path)
1029
+ end
1030
+ def binread(fname)
1031
+ File.open(fname, 'rb') do |f|
1032
+ return f.read
1033
+ end
1034
+ end
1035
+ def install_shebang(files, dir)
1036
+ files.each do |file|
1037
+ path = File.join(dir, File.basename(file))
1038
+ update_shebang_line(path)
1039
+ end
1040
+ end
1041
+ def update_shebang_line(path)
1042
+ return if trial?
1043
+ return if config.shebang == 'never'
1044
+ old = Shebang.load(path)
1045
+ if old
1046
+ if old.args.size > 1
1047
+ $stderr.puts "warning: #{path}"
1048
+ $stderr.puts "Shebang line has too many args."
1049
+ $stderr.puts "It is not portable and your program may not work."
1050
+ end
1051
+ new = new_shebang(old)
1052
+ return if new.to_s == old.to_s
1053
+ else
1054
+ return unless config.shebang == 'all'
1055
+ new = Shebang.new(config.rubypath)
1056
+ end
1057
+ $stderr.puts "updating shebang: #{File.basename(path)}" if trace?
1058
+ open_atomic_writer(path) do |output|
1059
+ File.open(path, 'rb') do |f|
1060
+ f.gets if old # discard
1061
+ output.puts new.to_s
1062
+ output.print f.read
1063
+ end
1064
+ end
1065
+ end
1066
+ def new_shebang(old)
1067
+ if /\Aruby/ =~ File.basename(old.cmd)
1068
+ Shebang.new(config.rubypath, old.args)
1069
+ elsif File.basename(old.cmd) == 'env' and old.args.first == 'ruby'
1070
+ Shebang.new(config.rubypath, old.args[1..-1])
1071
+ else
1072
+ return old unless config.shebang == 'all'
1073
+ Shebang.new(config.rubypath)
1074
+ end
1075
+ end
1076
+ def open_atomic_writer(path, &block)
1077
+ tmpfile = File.basename(path) + '.tmp'
1078
+ begin
1079
+ File.open(tmpfile, 'wb', &block)
1080
+ File.rename tmpfile, File.basename(path)
1081
+ ensure
1082
+ File.unlink tmpfile if File.exist?(tmpfile)
1083
+ end
1084
+ end
1085
+ class Shebang
1086
+ def Shebang.load(path)
1087
+ line = nil
1088
+ File.open(path) {|f|
1089
+ line = f.gets
1090
+ }
1091
+ return nil unless /\A#!/ =~ line
1092
+ parse(line)
1093
+ end
1094
+ def Shebang.parse(line)
1095
+ cmd, *args = *line.strip.sub(/\A\#!/, '').split(' ')
1096
+ new(cmd, args)
1097
+ end
1098
+ def initialize(cmd, args = [])
1099
+ @cmd = cmd
1100
+ @args = args
1101
+ end
1102
+ attr_reader :cmd
1103
+ attr_reader :args
1104
+ def to_s
1105
+ "#! #{@cmd}" + (@args.empty? ? '' : " #{@args.join(' ')}")
1106
+ end
1107
+ end
1108
+ end
1109
+ end
1110
+ module Setup
1111
+ class Tester < Base
1112
+ RUBYSCRIPT = META_EXTENSION_DIR + '/testrc.rb'
1113
+ SHELLSCRIPT = 'script/test'
1114
+ def testable?
1115
+ return false if config.no_test
1116
+ return true if File.exist?(RUBYSCRIPT)
1117
+ return true if File.exist?(SHELLSCRIPT)
1118
+ false
1119
+ end
1120
+ def test
1121
+ return true if !testable?
1122
+ if File.exist?(RUBYSCRIPT)
1123
+ test_rubyscript
1124
+ elsif File.exist?(SHELLSCRIPT)
1125
+ test_shellscript
1126
+ end
1127
+ end
1128
+ def test_shellscript
1129
+ bash(SHELLSCRIPT)
1130
+ end
1131
+ def test_rubyscript
1132
+ ruby(RUBYSCRIPT)
1133
+ end
1134
+ end
1135
+ end
1136
+ module Setup
1137
+ class Uninstaller < Base
1138
+ def uninstall
1139
+ return unless File.exist?(INSTALL_RECORD)
1140
+ files = []
1141
+ dirs = []
1142
+ paths.each do |path|
1143
+ dirs << path if File.dir?(path)
1144
+ files << path if File.file?(path)
1145
+ end
1146
+ if dirs.empty? && files.empty?
1147
+ io.outs "Nothing to remove."
1148
+ return
1149
+ end
1150
+ files.sort!{ |a,b| b.size <=> a.size }
1151
+ dirs.sort!{ |a,b| b.size <=> a.size }
1152
+ if !force? && !trial?
1153
+ puts (files + dirs).collect{ |f| "#{f}" }.join("\n")
1154
+ puts
1155
+ puts "Must use --force option to remove these files and directories that become empty."
1156
+ return
1157
+ end
1158
+ files.each do |file|
1159
+ rm_f(file)
1160
+ end
1161
+ dirs.each do |dir|
1162
+ entries = Dir.entries(dir)
1163
+ entries.delete('.')
1164
+ entries.delete('..')
1165
+ rmdir(dir) if entries.empty?
1166
+ end
1167
+ rm_f(INSTALL_RECORD)
1168
+ end
1169
+ private
1170
+ def paths
1171
+ @paths ||= (
1172
+ lines = File.read(INSTALL_RECORD).split(/\s*\n/)
1173
+ lines = lines.map{ |line| line.strip }
1174
+ lines = lines.uniq
1175
+ lines = lines.reject{ |line| line.empty? } # skip blank lines
1176
+ lines = lines.reject{ |line| line[0,1] == '#' } # skip blank lines
1177
+ lines
1178
+ )
1179
+ end
1180
+ end
1181
+ end
1182
+ require 'optparse'
1183
+ module Setup
1184
+ class Command
1185
+ def self.run(*argv)
1186
+ new.run(*argv)
1187
+ end
1188
+ def self.tasks
1189
+ @tasks ||= {}
1190
+ end
1191
+ def self.order
1192
+ @order ||= []
1193
+ end
1194
+ def self.task(name, description)
1195
+ tasks[name] = description
1196
+ order << name
1197
+ end
1198
+ task 'all' , "config, setup, test, install"
1199
+ task 'config' , "saves your configuration"
1200
+ task 'show' , "show current configuration"
1201
+ task 'make' , "compile ruby extentions"
1202
+ task 'test' , "run test suite"
1203
+ task 'doc' , "generate ri documentation"
1204
+ task 'install' , "install project files"
1205
+ task 'uninstall', "uninstall previously installed files"
1206
+ task 'clean' , "does `make clean' for each extention"
1207
+ task 'distclean', "does `make distclean' for each extention"
1208
+ def run(*argv)
1209
+ ARGV.replace(argv) unless argv.empty?
1210
+ task = ARGV.find{ |a| a !~ /^[-]/ }
1211
+ task = 'all' unless task
1212
+ unless task_names.include?(task)
1213
+ $stderr.puts "Not a valid task -- #{task}"
1214
+ exit 1
1215
+ end
1216
+ parser = OptionParser.new
1217
+ options = {}
1218
+ parser.banner = "Usage: #{File.basename($0)} [TASK] [OPTIONS]"
1219
+ optparse_header(parser, options)
1220
+ case task
1221
+ when 'all'
1222
+ optparse_all(parser, options)
1223
+ when 'config'
1224
+ optparse_config(parser, options)
1225
+ when 'install'
1226
+ optparse_install(parser, options)
1227
+ end
1228
+ optparse_common(parser, options)
1229
+ begin
1230
+ parser.parse!(ARGV)
1231
+ rescue OptionParser::InvalidOption
1232
+ $stderr.puts $!.to_s.capitalize
1233
+ exit 1
1234
+ end
1235
+ rootdir = session.project.rootdir
1236
+ print_header
1237
+ begin
1238
+ session.__send__(task)
1239
+ rescue Error
1240
+ raise if $DEBUG
1241
+ $stderr.puts $!.message
1242
+ $stderr.puts "Try 'setup.rb --help' for detailed usage."
1243
+ exit 1
1244
+ end
1245
+ puts unless session.quiet?
1246
+ end
1247
+ def session
1248
+ @session ||= Session.new(:io=>$stdout)
1249
+ end
1250
+ def configuration
1251
+ @configuration ||= session.configuration
1252
+ end
1253
+ def optparse_header(parser, options)
1254
+ parser.banner = "USAGE: #{File.basename($0)} [command] [options]"
1255
+ end
1256
+ def optparse_all(parser, options)
1257
+ optparse_config(parser, options)
1258
+ end
1259
+ def optparse_config(parser, options)
1260
+ parser.separator ""
1261
+ parser.separator "Configuration options:"
1262
+ configuration.options.each do |args|
1263
+ args = args.dup
1264
+ desc = args.pop
1265
+ type = args.pop
1266
+ name, shortcut = *args
1267
+ optname = name.to_s.gsub('_', '-')
1268
+ case type
1269
+ when :bool
1270
+ if optname.index('no-') == 0
1271
+ optname = "[no-]" + optname.sub(/^no-/, '')
1272
+ opts = shortcut ? ["-#{shortcut}", "--#{optname}", desc] : ["--#{optname}", desc]
1273
+ parser.on(*opts) do |val|
1274
+ configuration.__send__("#{name}=", !val)
1275
+ end
1276
+ else
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
+ end
1283
+ else
1284
+ opts = shortcut ? ["-#{shortcut}", "--#{optname} #{type.to_s.upcase}", desc] : ["--#{optname} #{type.to_s.upcase}", desc]
1285
+ parser.on(*opts) do |val|
1286
+ configuration.__send__("#{name}=", val)
1287
+ end
1288
+ end
1289
+ end
1290
+ end
1291
+ def optparse_install(parser, options)
1292
+ parser.separator ""
1293
+ parser.separator "Install options:"
1294
+ parser.on("--prefix PATH", "Installation prefix") do |val|
1295
+ configuration.install_prefix = val
1296
+ end
1297
+ end
1298
+ def optparse_common(parser, options)
1299
+ parser.separator ""
1300
+ parser.separator "General options:"
1301
+ parser.on("-q", "--quiet", "Suppress output") do
1302
+ session.quiet = true
1303
+ end
1304
+ parser.on("-f", "--force", "Force operation") do
1305
+ session.force = true
1306
+ end
1307
+ parser.on("--trace", "--verbose", "Watch execution") do |val|
1308
+ session.trace = true
1309
+ end
1310
+ parser.on("--trial", "--no-harm", "Do not write to disk") do |val|
1311
+ session.trial = true
1312
+ end
1313
+ parser.on("--debug", "Turn on debug mode") do |val|
1314
+ $DEBUG = true
1315
+ end
1316
+ parser.separator ""
1317
+ parser.separator "Inform options:"
1318
+ parser.on_tail("-h", "--help", "display this help information") do
1319
+ puts parser
1320
+ exit
1321
+ end
1322
+ parser.on_tail("--version", "-v", "Show version") do
1323
+ puts File.basename($0) + ' v' + Setup::VERSION #Version.join('.')
1324
+ exit
1325
+ end
1326
+ parser.on_tail("--copyright", "Show copyright") do
1327
+ puts Setup::COPYRIGHT #opyright
1328
+ exit
1329
+ end
1330
+ end
1331
+ def task_names
1332
+ self.class.tasks.keys
1333
+ end
1334
+ def print_header
1335
+ end
1336
+ end
1337
+ end
1338
+ Setup::Command.run