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