merb 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/README +22 -4
  2. data/Rakefile +15 -3
  3. data/TODO +2 -3
  4. data/bin/merb +61 -36
  5. data/examples/sample_app/dist/app/controllers/files.rb +31 -0
  6. data/examples/sample_app/dist/app/controllers/posts.rb +26 -2
  7. data/examples/sample_app/dist/app/controllers/test.rb +7 -1
  8. data/examples/sample_app/dist/app/views/files/progress.jerb +3 -0
  9. data/examples/sample_app/dist/app/views/files/start.herb +62 -0
  10. data/examples/sample_app/dist/app/views/files/upload.herb +6 -0
  11. data/examples/sample_app/dist/app/views/layout/{application.rhtml → application.herb} +2 -3
  12. data/examples/sample_app/dist/app/views/layout/{foo.rhtml → foo.herb} +0 -0
  13. data/examples/sample_app/dist/app/views/posts/{_comments.rhtml → _comments.herb} +0 -0
  14. data/examples/sample_app/dist/app/views/posts/comment.jerb +1 -0
  15. data/examples/sample_app/dist/app/views/posts/{list.rhtml → list.herb} +0 -0
  16. data/examples/sample_app/dist/app/views/posts/{new.rhtml → new.herb} +0 -0
  17. data/examples/sample_app/dist/app/views/posts/{show.rhtml → show.herb} +0 -0
  18. data/examples/sample_app/dist/app/views/posts/xml_test.xerb +3 -0
  19. data/examples/sample_app/dist/app/views/test/{foo.rhtml → foo.herb} +0 -0
  20. data/examples/sample_app/dist/app/views/test/{hello.rhtml → hello.herb} +0 -0
  21. data/examples/sample_app/dist/app/views/test/json.jerb +1 -0
  22. data/examples/sample_app/dist/conf/merb.yml +11 -0
  23. data/examples/sample_app/dist/conf/merb_init.rb +1 -1
  24. data/examples/sample_app/dist/conf/mup.conf +11 -0
  25. data/examples/sample_app/dist/public/javascripts/mup.js +113 -0
  26. data/examples/sample_app/script/merb_stop +7 -3
  27. data/examples/sample_app/script/startdrb +8 -0
  28. data/lib/merb.rb +37 -2
  29. data/lib/merb/merb_class_extensions.rb +21 -22
  30. data/lib/merb/merb_controller.rb +101 -33
  31. data/lib/merb/merb_handler.rb +26 -25
  32. data/lib/merb/merb_router.rb +1 -1
  33. data/lib/merb/merb_utils.rb +35 -37
  34. data/lib/merb/mixins/basic_authentication_mixin.rb +39 -0
  35. data/lib/merb/mixins/controller_mixin.rb +119 -115
  36. data/lib/merb/mixins/javascript_mixin.rb +63 -0
  37. data/lib/merb/mixins/render_mixin.rb +85 -69
  38. data/lib/merb/mixins/responder_mixin.rb +38 -0
  39. data/lib/merb/session/merb_drb_server.rb +107 -0
  40. data/lib/merb/session/merb_drb_session.rb +71 -0
  41. data/lib/merb/session/merb_session.rb +1 -0
  42. data/lib/merb/vendor/paginator/README.txt +84 -0
  43. data/lib/merb/vendor/paginator/paginator.rb +121 -0
  44. data/lib/mutex_hotfix.rb +34 -0
  45. metadata +41 -63
  46. data/doc/rdoc/classes/ControllerMixin.html +0 -676
  47. data/doc/rdoc/classes/Hash.html +0 -148
  48. data/doc/rdoc/classes/Merb.html +0 -140
  49. data/doc/rdoc/classes/Merb/Controller.html +0 -338
  50. data/doc/rdoc/classes/Merb/RouteMatcher.html +0 -388
  51. data/doc/rdoc/classes/Merb/Server.html +0 -148
  52. data/doc/rdoc/classes/Merb/Session.html +0 -201
  53. data/doc/rdoc/classes/Merb/SessionMixin.html +0 -199
  54. data/doc/rdoc/classes/MerbControllerError.html +0 -111
  55. data/doc/rdoc/classes/MerbHandler.html +0 -430
  56. data/doc/rdoc/classes/MerbHash.html +0 -469
  57. data/doc/rdoc/classes/MerbHash/Mutex.html +0 -198
  58. data/doc/rdoc/classes/Noroutefound.html +0 -153
  59. data/doc/rdoc/classes/Object.html +0 -149
  60. data/doc/rdoc/classes/RenderMixin.html +0 -362
  61. data/doc/rdoc/classes/String.html +0 -212
  62. data/doc/rdoc/classes/Symbol.html +0 -179
  63. data/doc/rdoc/created.rid +0 -1
  64. data/doc/rdoc/files/LICENSE.html +0 -129
  65. data/doc/rdoc/files/README.html +0 -417
  66. data/doc/rdoc/files/TODO.html +0 -151
  67. data/doc/rdoc/files/lib/merb/merb_class_extensions_rb.html +0 -101
  68. data/doc/rdoc/files/lib/merb/merb_controller_rb.html +0 -101
  69. data/doc/rdoc/files/lib/merb/merb_handler_rb.html +0 -101
  70. data/doc/rdoc/files/lib/merb/merb_router_rb.html +0 -101
  71. data/doc/rdoc/files/lib/merb/merb_utils_rb.html +0 -108
  72. data/doc/rdoc/files/lib/merb/mixins/controller_mixin_rb.html +0 -101
  73. data/doc/rdoc/files/lib/merb/mixins/render_mixin_rb.html +0 -101
  74. data/doc/rdoc/files/lib/merb/session/merb_session_rb.html +0 -101
  75. data/doc/rdoc/files/lib/merb_rb.html +0 -140
  76. data/doc/rdoc/files/lib/merb_tasks_rb.html +0 -101
  77. data/doc/rdoc/fr_class_index.html +0 -43
  78. data/doc/rdoc/fr_file_index.html +0 -40
  79. data/doc/rdoc/fr_method_index.html +0 -104
  80. data/doc/rdoc/index.html +0 -24
  81. data/doc/rdoc/rdoc-style.css +0 -208
  82. data/examples/sample_app/dist/app/controllers/upload.rb +0 -29
  83. data/examples/sample_app/dist/app/views/posts/comment.merbjs +0 -1
  84. data/examples/sample_app/dist/app/views/upload/start.rhtml +0 -15
  85. data/examples/sample_app/dist/app/views/upload/upload.rhtml +0 -4
  86. data/examples/sample_app/dist/public/files/README +0 -35
  87. data/examples/sample_app/dist/public/files/setup.rb +0 -1346
  88. data/examples/sample_app/log/merb.log +0 -778
@@ -1,208 +0,0 @@
1
-
2
- body {
3
- font-family: Verdana,Arial,Helvetica,sans-serif;
4
- font-size: 90%;
5
- margin: 0;
6
- margin-left: 40px;
7
- padding: 0;
8
- background: white;
9
- }
10
-
11
- h1,h2,h3,h4 { margin: 0; color: #efefef; background: transparent; }
12
- h1 { font-size: 150%; }
13
- h2,h3,h4 { margin-top: 1em; }
14
-
15
- a { background: #eef; color: #039; text-decoration: none; }
16
- a:hover { background: #039; color: #eef; }
17
-
18
- /* Override the base stylesheet's Anchor inside a table cell */
19
- td > a {
20
- background: transparent;
21
- color: #039;
22
- text-decoration: none;
23
- }
24
-
25
- /* and inside a section title */
26
- .section-title > a {
27
- background: transparent;
28
- color: #eee;
29
- text-decoration: none;
30
- }
31
-
32
- /* === Structural elements =================================== */
33
-
34
- div#index {
35
- margin: 0;
36
- margin-left: -40px;
37
- padding: 0;
38
- font-size: 90%;
39
- }
40
-
41
-
42
- div#index a {
43
- margin-left: 0.7em;
44
- }
45
-
46
- div#index .section-bar {
47
- margin-left: 0px;
48
- padding-left: 0.7em;
49
- background: #ccc;
50
- font-size: small;
51
- }
52
-
53
-
54
- div#classHeader, div#fileHeader {
55
- width: auto;
56
- color: white;
57
- padding: 0.5em 1.5em 0.5em 1.5em;
58
- margin: 0;
59
- margin-left: -40px;
60
- border-bottom: 3px solid #006;
61
- }
62
-
63
- div#classHeader a, div#fileHeader a {
64
- background: inherit;
65
- color: white;
66
- }
67
-
68
- div#classHeader td, div#fileHeader td {
69
- background: inherit;
70
- color: white;
71
- }
72
-
73
-
74
- div#fileHeader {
75
- background: #057;
76
- }
77
-
78
- div#classHeader {
79
- background: #048;
80
- }
81
-
82
-
83
- .class-name-in-header {
84
- font-size: 180%;
85
- font-weight: bold;
86
- }
87
-
88
-
89
- div#bodyContent {
90
- padding: 0 1.5em 0 1.5em;
91
- }
92
-
93
- div#description {
94
- padding: 0.5em 1.5em;
95
- background: #efefef;
96
- border: 1px dotted #999;
97
- }
98
-
99
- div#description h1,h2,h3,h4,h5,h6 {
100
- color: #125;;
101
- background: transparent;
102
- }
103
-
104
- div#validator-badges {
105
- text-align: center;
106
- }
107
- div#validator-badges img { border: 0; }
108
-
109
- div#copyright {
110
- color: #333;
111
- background: #efefef;
112
- font: 0.75em sans-serif;
113
- margin-top: 5em;
114
- margin-bottom: 0;
115
- padding: 0.5em 2em;
116
- }
117
-
118
-
119
- /* === Classes =================================== */
120
-
121
- table.header-table {
122
- color: white;
123
- font-size: small;
124
- }
125
-
126
- .type-note {
127
- font-size: small;
128
- color: #DEDEDE;
129
- }
130
-
131
- .xxsection-bar {
132
- background: #eee;
133
- color: #333;
134
- padding: 3px;
135
- }
136
-
137
- .section-bar {
138
- color: #333;
139
- border-bottom: 1px solid #999;
140
- margin-left: -20px;
141
- }
142
-
143
-
144
- .section-title {
145
- background: #79a;
146
- color: #eee;
147
- padding: 3px;
148
- margin-top: 2em;
149
- margin-left: -30px;
150
- border: 1px solid #999;
151
- }
152
-
153
- .top-aligned-row { vertical-align: top }
154
- .bottom-aligned-row { vertical-align: bottom }
155
-
156
- /* --- Context section classes ----------------------- */
157
-
158
- .context-row { }
159
- .context-item-name { font-family: monospace; font-weight: bold; color: black; }
160
- .context-item-value { font-size: small; color: #448; }
161
- .context-item-desc { color: #333; padding-left: 2em; }
162
-
163
- /* --- Method classes -------------------------- */
164
- .method-detail {
165
- background: #efefef;
166
- padding: 0;
167
- margin-top: 0.5em;
168
- margin-bottom: 1em;
169
- border: 1px dotted #ccc;
170
- }
171
- .method-heading {
172
- color: black;
173
- background: #ccc;
174
- border-bottom: 1px solid #666;
175
- padding: 0.2em 0.5em 0 0.5em;
176
- }
177
- .method-signature { color: black; background: inherit; }
178
- .method-name { font-weight: bold; }
179
- .method-args { font-style: italic; }
180
- .method-description { padding: 0 0.5em 0 0.5em; }
181
-
182
- /* --- Source code sections -------------------- */
183
-
184
- a.source-toggle { font-size: 90%; }
185
- div.method-source-code {
186
- background: #262626;
187
- color: #ffdead;
188
- margin: 1em;
189
- padding: 0.5em;
190
- border: 1px dashed #999;
191
- overflow: hidden;
192
- }
193
-
194
- div.method-source-code pre { color: #ffdead; overflow: hidden; }
195
-
196
- /* --- Ruby keyword styles --------------------- */
197
-
198
- .standalone-code { background: #221111; color: #ffdead; overflow: hidden; }
199
-
200
- .ruby-constant { color: #7fffd4; background: transparent; }
201
- .ruby-keyword { color: #00ffff; background: transparent; }
202
- .ruby-ivar { color: #eedd82; background: transparent; }
203
- .ruby-operator { color: #00ffee; background: transparent; }
204
- .ruby-identifier { color: #ffdead; background: transparent; }
205
- .ruby-node { color: #ffa07a; background: transparent; }
206
- .ruby-comment { color: #b22222; font-weight: bold; background: transparent; }
207
- .ruby-regexp { color: #ffa07a; background: transparent; }
208
- .ruby-value { color: #7fffd4; background: transparent; }
@@ -1,29 +0,0 @@
1
- class Upload < Merb::Controller
2
-
3
- def start
4
- # Assign the parameter to an instance variable
5
- @args = params
6
- render
7
- end
8
-
9
- def index
10
- @args = params
11
- render 'start'
12
- end
13
-
14
- def upload
15
- puts params[:file].inspect
16
-
17
- FileUtils.mv params[:file][:tempfile].path, ::Merb::Server.config[:dist_root]+"/public/files/#{params[:file][:filename]}"
18
-
19
- render
20
- end
21
-
22
- def file
23
- send_file MERB_ROOT+'/public/files/'+params[:file]
24
- end
25
-
26
- def to_s
27
- "<html><body>Upload controller, no mathing action</body></html>"
28
- end
29
- end
@@ -1 +0,0 @@
1
- $('comments').update('<%= escape_js(partial(:comments)) %>');
@@ -1,15 +0,0 @@
1
-
2
- <h2>Test file uploading.</h2>
3
-
4
- <form action="/upload/upload" enctype="multipart/form-data" method="post">
5
-
6
- <dl>
7
- <dt><label>Select a file</label></dt>
8
- <dd><input name="file" type="file" /></dd>
9
- </dl>
10
-
11
-
12
- <p>
13
- <input name="commit" type="submit" value="Upload Asset" />
14
- </p>
15
- </form>
@@ -1,4 +0,0 @@
1
- <h2>File uploaded successfully</h2>
2
-
3
- <p>params for params[:file].inspect</p>
4
- <%=params[:file].inspect %>
@@ -1,35 +0,0 @@
1
- = Capistrano
2
-
3
- Capistrano is a utility and framework for executing commands in parallel on multiple remote machines, via SSH. It uses a simple DSL (borrowed in part from Rake, http://rake.rubyforge.org/) that allows you to define _tasks_, which may be applied to machines in certain roles. It also supports tunneling connections via some gateway machine to allow operations to be performed behind VPN's and firewalls.
4
-
5
- Capistrano was originally designed to simplify and automate deployment of web applications to distributed environments, and so it comes with many tasks predefined for that ("update_code" and "deploy", for instance).
6
-
7
- == Dependencies
8
-
9
- Capistrano depends upon the Net::SSH library by Jamis Buck (http://net-ssh.rubyforge.org). Net::SSH itself depends on the Needle library (http://needle.rubyforge.org), also by Jamis Buck.
10
-
11
- == Assumptions
12
-
13
- In keeping with Rails' "convention over configuration", Capistrano makes several assumptions about how you will use it (most, if not all, of which may be explicitly overridden):
14
-
15
- * You are writing web applications and want to use Capistrano to deploy them.
16
- * You are using Ruby on Rails (http://www.rubyonrails.com) to build your apps.
17
- * You are using Subversion (http://subversion.tigris.org/) to manage your source code.
18
- * You are running your apps using FastCGI, together with Rails' spinner/reaper utilities.
19
-
20
- As with the rest of Rails, if you can abide by these assumptions, you can use Capistrano "out of the box". If any of these assumptions do not hold, you'll need to make some adjustments to your deployment recipe files.
21
-
22
- == Usage
23
-
24
- More documentation is always pending, but you'll want to see the user manual for detailed usage instructions. (The manual is online at http://manuals.rubyonrails.org/read/book/17).
25
-
26
- In general, you'll use Capistrano as follows:
27
-
28
- * Create a deployment recipe ("deploy.rb") for your application. You can use the sample recipe in examples/sample.rb as a starting point.
29
- * Use the +cap+ script to execute your recipe (see below).
30
-
31
- Use the +cap+ script as follows:
32
-
33
- cap -vvv someaction
34
-
35
- By default, the script will look for a file called one of <tt>config/deploy</tt>, <tt>config/deploy.rb</tt>, <tt>capistrano</tt>, or <tt>capistrano.rb</tt>. You can the <tt>-v</tt> switch multiple times (as shown) to increase the verbosity of the output. The +someaction+ text indicates which action to execute.
@@ -1,1346 +0,0 @@
1
- #
2
- # setup.rb
3
- #
4
- # Copyright (c) 2000-2004 Minero Aoki
5
- #
6
- # This program is free software.
7
- # You can distribute/modify this program under the terms of
8
- # the GNU Lesser General Public License version 2.1.
9
- #
10
-
11
- #
12
- # For backward compatibility
13
- #
14
-
15
- unless Enumerable.method_defined?(:map)
16
- module Enumerable
17
- alias map collect
18
- end
19
- end
20
-
21
- unless Enumerable.method_defined?(:detect)
22
- module Enumerable
23
- alias detect find
24
- end
25
- end
26
-
27
- unless Enumerable.method_defined?(:select)
28
- module Enumerable
29
- alias select find_all
30
- end
31
- end
32
-
33
- unless Enumerable.method_defined?(:reject)
34
- module Enumerable
35
- def reject
36
- result = []
37
- each do |i|
38
- result.push i unless yield(i)
39
- end
40
- result
41
- end
42
- end
43
- end
44
-
45
- unless Enumerable.method_defined?(:inject)
46
- module Enumerable
47
- def inject(result)
48
- each do |i|
49
- result = yield(result, i)
50
- end
51
- result
52
- end
53
- end
54
- end
55
-
56
- unless Enumerable.method_defined?(:any?)
57
- module Enumerable
58
- def any?
59
- each do |i|
60
- return true if yield(i)
61
- end
62
- false
63
- end
64
- end
65
- end
66
-
67
- unless File.respond_to?(:read)
68
- def File.read(fname)
69
- open(fname) {|f|
70
- return f.read
71
- }
72
- end
73
- end
74
-
75
- #
76
- # Application independent utilities
77
- #
78
-
79
- def File.binread(fname)
80
- open(fname, 'rb') {|f|
81
- return f.read
82
- }
83
- end
84
-
85
- # for corrupted windows stat(2)
86
- def File.dir?(path)
87
- File.directory?((path[-1,1] == '/') ? path : path + '/')
88
- end
89
-
90
- #
91
- # Config
92
- #
93
-
94
- if arg = ARGV.detect{|arg| /\A--rbconfig=/ =~ arg }
95
- ARGV.delete(arg)
96
- require arg.split(/=/, 2)[1]
97
- $".push 'rbconfig.rb'
98
- else
99
- require 'rbconfig'
100
- end
101
-
102
- def multipackage_install?
103
- FileTest.directory?(File.dirname($0) + '/packages')
104
- end
105
-
106
-
107
- class ConfigTable
108
-
109
- c = ::Config::CONFIG
110
-
111
- rubypath = c['bindir'] + '/' + c['ruby_install_name']
112
-
113
- major = c['MAJOR'].to_i
114
- minor = c['MINOR'].to_i
115
- teeny = c['TEENY'].to_i
116
- version = "#{major}.#{minor}"
117
-
118
- # ruby ver. >= 1.4.4?
119
- newpath_p = ((major >= 2) or
120
- ((major == 1) and
121
- ((minor >= 5) or
122
- ((minor == 4) and (teeny >= 4)))))
123
-
124
- subprefix = lambda {|path|
125
- path.sub(/\A#{Regexp.quote(c['prefix'])}/o, '$prefix')
126
- }
127
-
128
- if c['rubylibdir']
129
- # V < 1.6.3
130
- stdruby = subprefix.call(c['rubylibdir'])
131
- siteruby = subprefix.call(c['sitedir'])
132
- versite = subprefix.call(c['sitelibdir'])
133
- sodir = subprefix.call(c['sitearchdir'])
134
- elsif newpath_p
135
- # 1.4.4 <= V <= 1.6.3
136
- stdruby = "$prefix/lib/ruby/#{version}"
137
- siteruby = subprefix.call(c['sitedir'])
138
- versite = siteruby + '/' + version
139
- sodir = "$site-ruby/#{c['arch']}"
140
- else
141
- # V < 1.4.4
142
- stdruby = "$prefix/lib/ruby/#{version}"
143
- siteruby = "$prefix/lib/ruby/#{version}/site_ruby"
144
- versite = siteruby
145
- sodir = "$site-ruby/#{c['arch']}"
146
- end
147
-
148
- if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg }
149
- makeprog = arg.sub(/'/, '').split(/=/, 2)[1]
150
- else
151
- makeprog = 'make'
152
- end
153
-
154
- common_descripters = [
155
- [ 'prefix', [ c['prefix'],
156
- 'path',
157
- 'path prefix of target environment' ] ],
158
- [ 'std-ruby', [ stdruby,
159
- 'path',
160
- 'the directory for standard ruby libraries' ] ],
161
- [ 'site-ruby-common', [ siteruby,
162
- 'path',
163
- 'the directory for version-independent non-standard ruby libraries' ] ],
164
- [ 'site-ruby', [ versite,
165
- 'path',
166
- 'the directory for non-standard ruby libraries' ] ],
167
- [ 'bin-dir', [ '$prefix/bin',
168
- 'path',
169
- 'the directory for commands' ] ],
170
- [ 'rb-dir', [ '$site-ruby',
171
- 'path',
172
- 'the directory for ruby scripts' ] ],
173
- [ 'so-dir', [ sodir,
174
- 'path',
175
- 'the directory for ruby extentions' ] ],
176
- [ 'data-dir', [ '$prefix/share',
177
- 'path',
178
- 'the directory for shared data' ] ],
179
- [ 'ruby-path', [ rubypath,
180
- 'path',
181
- 'path to set to #! line' ] ],
182
- [ 'ruby-prog', [ rubypath,
183
- 'name',
184
- 'the ruby program using for installation' ] ],
185
- [ 'make-prog', [ makeprog,
186
- 'name',
187
- 'the make program to compile ruby extentions' ] ],
188
- [ 'without-ext', [ 'no',
189
- 'yes/no',
190
- 'does not compile/install ruby extentions' ] ]
191
- ]
192
- multipackage_descripters = [
193
- [ 'with', [ '',
194
- 'name,name...',
195
- 'package names that you want to install',
196
- 'ALL' ] ],
197
- [ 'without', [ '',
198
- 'name,name...',
199
- 'package names that you do not want to install',
200
- 'NONE' ] ]
201
- ]
202
- if multipackage_install?
203
- DESCRIPTER = common_descripters + multipackage_descripters
204
- else
205
- DESCRIPTER = common_descripters
206
- end
207
-
208
- SAVE_FILE = 'config.save'
209
-
210
- def ConfigTable.each_name(&block)
211
- keys().each(&block)
212
- end
213
-
214
- def ConfigTable.keys
215
- DESCRIPTER.map {|name, *dummy| name }
216
- end
217
-
218
- def ConfigTable.each_definition(&block)
219
- DESCRIPTER.each(&block)
220
- end
221
-
222
- def ConfigTable.get_entry(name)
223
- name, ent = DESCRIPTER.assoc(name)
224
- ent
225
- end
226
-
227
- def ConfigTable.get_entry!(name)
228
- get_entry(name) or raise ArgumentError, "no such config: #{name}"
229
- end
230
-
231
- def ConfigTable.add_entry(name, vals)
232
- ConfigTable::DESCRIPTER.push [name,vals]
233
- end
234
-
235
- def ConfigTable.remove_entry(name)
236
- get_entry(name) or raise ArgumentError, "no such config: #{name}"
237
- DESCRIPTER.delete_if {|n, arr| n == name }
238
- end
239
-
240
- def ConfigTable.config_key?(name)
241
- get_entry(name) ? true : false
242
- end
243
-
244
- def ConfigTable.bool_config?(name)
245
- ent = get_entry(name) or return false
246
- ent[1] == 'yes/no'
247
- end
248
-
249
- def ConfigTable.value_config?(name)
250
- ent = get_entry(name) or return false
251
- ent[1] != 'yes/no'
252
- end
253
-
254
- def ConfigTable.path_config?(name)
255
- ent = get_entry(name) or return false
256
- ent[1] == 'path'
257
- end
258
-
259
-
260
- class << self
261
- alias newobj new
262
- end
263
-
264
- def ConfigTable.new
265
- c = newobj()
266
- c.initialize_from_table
267
- c
268
- end
269
-
270
- def ConfigTable.load
271
- c = newobj()
272
- c.initialize_from_file
273
- c
274
- end
275
-
276
- def initialize_from_table
277
- @table = {}
278
- DESCRIPTER.each do |k, (default, vname, desc, default2)|
279
- @table[k] = default
280
- end
281
- end
282
-
283
- def initialize_from_file
284
- raise InstallError, "#{File.basename $0} config first"\
285
- unless File.file?(SAVE_FILE)
286
- @table = {}
287
- File.foreach(SAVE_FILE) do |line|
288
- k, v = line.split(/=/, 2)
289
- @table[k] = v.strip
290
- end
291
- end
292
-
293
- def save
294
- File.open(SAVE_FILE, 'w') {|f|
295
- @table.each do |k, v|
296
- f.printf "%s=%s\n", k, v if v
297
- end
298
- }
299
- end
300
-
301
- def []=(k, v)
302
- raise InstallError, "unknown config option #{k}"\
303
- unless ConfigTable.config_key?(k)
304
- @table[k] = v
305
- end
306
-
307
- def [](key)
308
- return nil unless @table[key]
309
- @table[key].gsub(%r<\$([^/]+)>) { self[$1] }
310
- end
311
-
312
- def set_raw(key, val)
313
- @table[key] = val
314
- end
315
-
316
- def get_raw(key)
317
- @table[key]
318
- end
319
-
320
- end
321
-
322
-
323
- module MetaConfigAPI
324
-
325
- def eval_file_ifexist(fname)
326
- instance_eval File.read(fname), fname, 1 if File.file?(fname)
327
- end
328
-
329
- def config_names
330
- ConfigTable.keys
331
- end
332
-
333
- def config?(name)
334
- ConfigTable.config_key?(name)
335
- end
336
-
337
- def bool_config?(name)
338
- ConfigTable.bool_config?(name)
339
- end
340
-
341
- def value_config?(name)
342
- ConfigTable.value_config?(name)
343
- end
344
-
345
- def path_config?(name)
346
- ConfigTable.path_config?(name)
347
- end
348
-
349
- def add_config(name, argname, default, desc)
350
- ConfigTable.add_entry name,[default,argname,desc]
351
- end
352
-
353
- def add_path_config(name, default, desc)
354
- add_config name, 'path', default, desc
355
- end
356
-
357
- def add_bool_config(name, default, desc)
358
- add_config name, 'yes/no', default ? 'yes' : 'no', desc
359
- end
360
-
361
- def set_config_default(name, default)
362
- if bool_config?(name)
363
- ConfigTable.get_entry!(name)[0] = (default ? 'yes' : 'no')
364
- else
365
- ConfigTable.get_entry!(name)[0] = default
366
- end
367
- end
368
-
369
- def remove_config(name)
370
- ent = ConfigTable.get_entry(name)
371
- ConfigTable.remove_entry name
372
- ent
373
- end
374
-
375
- end
376
-
377
- #
378
- # File Operations
379
- #
380
-
381
- module FileOperations
382
-
383
- def mkdir_p(dirname, prefix = nil)
384
- dirname = prefix + dirname if prefix
385
- $stderr.puts "mkdir -p #{dirname}" if verbose?
386
- return if no_harm?
387
-
388
- # does not check '/'... it's too abnormal case
389
- dirs = dirname.split(%r<(?=/)>)
390
- if /\A[a-z]:\z/i =~ dirs[0]
391
- disk = dirs.shift
392
- dirs[0] = disk + dirs[0]
393
- end
394
- dirs.each_index do |idx|
395
- path = dirs[0..idx].join('')
396
- Dir.mkdir path unless File.dir?(path)
397
- end
398
- end
399
-
400
- def rm_f(fname)
401
- $stderr.puts "rm -f #{fname}" if verbose?
402
- return if no_harm?
403
-
404
- if File.exist?(fname) or File.symlink?(fname)
405
- File.chmod 0777, fname
406
- File.unlink fname
407
- end
408
- end
409
-
410
- def rm_rf(dn)
411
- $stderr.puts "rm -rf #{dn}" if verbose?
412
- return if no_harm?
413
-
414
- Dir.chdir dn
415
- Dir.foreach('.') do |fn|
416
- next if fn == '.'
417
- next if fn == '..'
418
- if File.dir?(fn)
419
- verbose_off {
420
- rm_rf fn
421
- }
422
- else
423
- verbose_off {
424
- rm_f fn
425
- }
426
- end
427
- end
428
- Dir.chdir '..'
429
- Dir.rmdir dn
430
- end
431
-
432
- def move_file(src, dest)
433
- File.unlink dest if File.exist?(dest)
434
- begin
435
- File.rename src, dest
436
- rescue
437
- File.open(dest, 'wb') {|f| f.write File.binread(src) }
438
- File.chmod File.stat(src).mode, dest
439
- File.unlink src
440
- end
441
- end
442
-
443
- def install(from, dest, mode, prefix = nil)
444
- $stderr.puts "install #{from} #{dest}" if verbose?
445
- return if no_harm?
446
-
447
- realdest = prefix + dest if prefix
448
- realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest)
449
- str = File.binread(from)
450
- if diff?(str, realdest)
451
- verbose_off {
452
- rm_f realdest if File.exist?(realdest)
453
- }
454
- File.open(realdest, 'wb') {|f|
455
- f.write str
456
- }
457
- File.chmod mode, realdest
458
-
459
- File.open("#{objdir_root()}/InstalledFiles", 'a') {|f|
460
- if prefix
461
- f.puts realdest.sub(prefix, '')
462
- else
463
- f.puts realdest
464
- end
465
- }
466
- end
467
- end
468
-
469
- def diff?(new_content, path)
470
- return true unless File.exist?(path)
471
- new_content != File.binread(path)
472
- end
473
-
474
- def command(str)
475
- $stderr.puts str if verbose?
476
- system str or raise RuntimeError, "'system #{str}' failed"
477
- end
478
-
479
- def ruby(str)
480
- command config('ruby-prog') + ' ' + str
481
- end
482
-
483
- def make(task = '')
484
- command config('make-prog') + ' ' + task
485
- end
486
-
487
- def extdir?(dir)
488
- File.exist?(dir + '/MANIFEST')
489
- end
490
-
491
- def all_files_in(dirname)
492
- Dir.open(dirname) {|d|
493
- return d.select {|ent| File.file?("#{dirname}/#{ent}") }
494
- }
495
- end
496
-
497
- REJECT_DIRS = %w(
498
- CVS SCCS RCS CVS.adm .svn
499
- )
500
-
501
- def all_dirs_in(dirname)
502
- Dir.open(dirname) {|d|
503
- return d.select {|n| File.dir?("#{dirname}/#{n}") } - %w(. ..) - REJECT_DIRS
504
- }
505
- end
506
-
507
- end
508
-
509
- #
510
- # Main Installer
511
- #
512
-
513
- class InstallError < StandardError; end
514
-
515
-
516
- module HookUtils
517
-
518
- def run_hook(name)
519
- try_run_hook "#{curr_srcdir()}/#{name}" or
520
- try_run_hook "#{curr_srcdir()}/#{name}.rb"
521
- end
522
-
523
- def try_run_hook(fname)
524
- return false unless File.file?(fname)
525
- begin
526
- instance_eval File.read(fname), fname, 1
527
- rescue
528
- raise InstallError, "hook #{fname} failed:\n" + $!.message
529
- end
530
- true
531
- end
532
-
533
- end
534
-
535
-
536
- module HookScriptAPI
537
-
538
- def get_config(key)
539
- @config[key]
540
- end
541
-
542
- alias config get_config
543
-
544
- def set_config(key, val)
545
- @config[key] = val
546
- end
547
-
548
- #
549
- # srcdir/objdir (works only in the package directory)
550
- #
551
-
552
- #abstract srcdir_root
553
- #abstract objdir_root
554
- #abstract relpath
555
-
556
- def curr_srcdir
557
- "#{srcdir_root()}/#{relpath()}"
558
- end
559
-
560
- def curr_objdir
561
- "#{objdir_root()}/#{relpath()}"
562
- end
563
-
564
- def srcfile(path)
565
- "#{curr_srcdir()}/#{path}"
566
- end
567
-
568
- def srcexist?(path)
569
- File.exist?(srcfile(path))
570
- end
571
-
572
- def srcdirectory?(path)
573
- File.dir?(srcfile(path))
574
- end
575
-
576
- def srcfile?(path)
577
- File.file? srcfile(path)
578
- end
579
-
580
- def srcentries(path = '.')
581
- Dir.open("#{curr_srcdir()}/#{path}") {|d|
582
- return d.to_a - %w(. ..)
583
- }
584
- end
585
-
586
- def srcfiles(path = '.')
587
- srcentries(path).select {|fname|
588
- File.file?(File.join(curr_srcdir(), path, fname))
589
- }
590
- end
591
-
592
- def srcdirectories(path = '.')
593
- srcentries(path).select {|fname|
594
- File.dir?(File.join(curr_srcdir(), path, fname))
595
- }
596
- end
597
-
598
- end
599
-
600
-
601
- class ToplevelInstaller
602
-
603
- Version = '3.2.4'
604
- Copyright = 'Copyright (c) 2000-2004 Minero Aoki'
605
-
606
- TASKS = [
607
- [ 'config', 'saves your configurations' ],
608
- [ 'show', 'shows current configuration' ],
609
- [ 'setup', 'compiles ruby extentions and others' ],
610
- [ 'install', 'installs files' ],
611
- [ 'clean', "does `make clean' for each extention" ],
612
- [ 'distclean',"does `make distclean' for each extention" ]
613
- ]
614
-
615
- def ToplevelInstaller.invoke
616
- instance().invoke
617
- end
618
-
619
- @singleton = nil
620
-
621
- def ToplevelInstaller.instance
622
- @singleton ||= new(File.dirname($0))
623
- @singleton
624
- end
625
-
626
- include MetaConfigAPI
627
-
628
- def initialize(ardir_root)
629
- @config = nil
630
- @options = { 'verbose' => true }
631
- @ardir = File.expand_path(ardir_root)
632
- end
633
-
634
- def inspect
635
- "#<#{self.class} #{__id__()}>"
636
- end
637
-
638
- def invoke
639
- run_metaconfigs
640
- task = parsearg_global()
641
- @config = load_config(task)
642
- __send__ "parsearg_#{task}"
643
- init_installers
644
- __send__ "exec_#{task}"
645
- end
646
-
647
- def run_metaconfigs
648
- eval_file_ifexist "#{@ardir}/metaconfig"
649
- end
650
-
651
- def load_config(task)
652
- case task
653
- when 'config'
654
- ConfigTable.new
655
- when 'clean', 'distclean'
656
- if File.exist?('config.save')
657
- then ConfigTable.load
658
- else ConfigTable.new
659
- end
660
- else
661
- ConfigTable.load
662
- end
663
- end
664
-
665
- def init_installers
666
- @installer = Installer.new(@config, @options, @ardir, File.expand_path('.'))
667
- end
668
-
669
- #
670
- # Hook Script API bases
671
- #
672
-
673
- def srcdir_root
674
- @ardir
675
- end
676
-
677
- def objdir_root
678
- '.'
679
- end
680
-
681
- def relpath
682
- '.'
683
- end
684
-
685
- #
686
- # Option Parsing
687
- #
688
-
689
- def parsearg_global
690
- valid_task = /\A(?:#{TASKS.map {|task,desc| task }.join '|'})\z/
691
-
692
- while arg = ARGV.shift
693
- case arg
694
- when /\A\w+\z/
695
- raise InstallError, "invalid task: #{arg}" unless valid_task =~ arg
696
- return arg
697
-
698
- when '-q', '--quiet'
699
- @options['verbose'] = false
700
-
701
- when '--verbose'
702
- @options['verbose'] = true
703
-
704
- when '-h', '--help'
705
- print_usage $stdout
706
- exit 0
707
-
708
- when '-v', '--version'
709
- puts "#{File.basename($0)} version #{Version}"
710
- exit 0
711
-
712
- when '--copyright'
713
- puts Copyright
714
- exit 0
715
-
716
- else
717
- raise InstallError, "unknown global option '#{arg}'"
718
- end
719
- end
720
-
721
- raise InstallError, <<EOS
722
- No task or global option given.
723
- Typical installation procedure is:
724
- $ ruby #{File.basename($0)} config
725
- $ ruby #{File.basename($0)} setup
726
- # ruby #{File.basename($0)} install (may require root privilege)
727
- EOS
728
- end
729
-
730
-
731
- def parsearg_no_options
732
- raise InstallError, "#{task}: unknown options: #{ARGV.join ' '}"\
733
- unless ARGV.empty?
734
- end
735
-
736
- alias parsearg_show parsearg_no_options
737
- alias parsearg_setup parsearg_no_options
738
- alias parsearg_clean parsearg_no_options
739
- alias parsearg_distclean parsearg_no_options
740
-
741
- def parsearg_config
742
- re = /\A--(#{ConfigTable.keys.join '|'})(?:=(.*))?\z/
743
- @options['config-opt'] = []
744
-
745
- while i = ARGV.shift
746
- if /\A--?\z/ =~ i
747
- @options['config-opt'] = ARGV.dup
748
- break
749
- end
750
- m = re.match(i) or raise InstallError, "config: unknown option #{i}"
751
- name, value = m.to_a[1,2]
752
- if value
753
- if ConfigTable.bool_config?(name)
754
- raise InstallError, "config: --#{name} allows only yes/no for argument"\
755
- unless /\A(y(es)?|n(o)?|t(rue)?|f(alse))\z/i =~ value
756
- value = (/\Ay(es)?|\At(rue)/i =~ value) ? 'yes' : 'no'
757
- end
758
- else
759
- raise InstallError, "config: --#{name} requires argument"\
760
- unless ConfigTable.bool_config?(name)
761
- value = 'yes'
762
- end
763
- @config[name] = value
764
- end
765
- end
766
-
767
- def parsearg_install
768
- @options['no-harm'] = false
769
- @options['install-prefix'] = ''
770
- while a = ARGV.shift
771
- case a
772
- when /\A--no-harm\z/
773
- @options['no-harm'] = true
774
- when /\A--prefix=(.*)\z/
775
- path = $1
776
- path = File.expand_path(path) unless path[0,1] == '/'
777
- @options['install-prefix'] = path
778
- else
779
- raise InstallError, "install: unknown option #{a}"
780
- end
781
- end
782
- end
783
-
784
- def print_usage(out)
785
- out.puts 'Typical Installation Procedure:'
786
- out.puts " $ ruby #{File.basename $0} config"
787
- out.puts " $ ruby #{File.basename $0} setup"
788
- out.puts " # ruby #{File.basename $0} install (may require root privilege)"
789
- out.puts
790
- out.puts 'Detailed Usage:'
791
- out.puts " ruby #{File.basename $0} <global option>"
792
- out.puts " ruby #{File.basename $0} [<global options>] <task> [<task options>]"
793
-
794
- fmt = " %-20s %s\n"
795
- out.puts
796
- out.puts 'Global options:'
797
- out.printf fmt, '-q,--quiet', 'suppress message outputs'
798
- out.printf fmt, ' --verbose', 'output messages verbosely'
799
- out.printf fmt, '-h,--help', 'print this message'
800
- out.printf fmt, '-v,--version', 'print version and quit'
801
- out.printf fmt, ' --copyright', 'print copyright and quit'
802
-
803
- out.puts
804
- out.puts 'Tasks:'
805
- TASKS.each do |name, desc|
806
- out.printf " %-10s %s\n", name, desc
807
- end
808
-
809
- out.puts
810
- out.puts 'Options for config:'
811
- ConfigTable.each_definition do |name, (default, arg, desc, default2)|
812
- out.printf " %-20s %s [%s]\n",
813
- '--'+ name + (ConfigTable.bool_config?(name) ? '' : '='+arg),
814
- desc,
815
- default2 || default
816
- end
817
- out.printf " %-20s %s [%s]\n",
818
- '--rbconfig=path', 'your rbconfig.rb to load', "running ruby's"
819
-
820
- out.puts
821
- out.puts 'Options for install:'
822
- out.printf " %-20s %s [%s]\n",
823
- '--no-harm', 'only display what to do if given', 'off'
824
- out.printf " %-20s %s [%s]\n",
825
- '--prefix', 'install path prefix', '$prefix'
826
-
827
- out.puts
828
- end
829
-
830
- #
831
- # Task Handlers
832
- #
833
-
834
- def exec_config
835
- @installer.exec_config
836
- @config.save # must be final
837
- end
838
-
839
- def exec_setup
840
- @installer.exec_setup
841
- end
842
-
843
- def exec_install
844
- @installer.exec_install
845
- end
846
-
847
- def exec_show
848
- ConfigTable.each_name do |k|
849
- v = @config.get_raw(k)
850
- if not v or v.empty?
851
- v = '(not specified)'
852
- end
853
- printf "%-10s %s\n", k, v
854
- end
855
- end
856
-
857
- def exec_clean
858
- @installer.exec_clean
859
- end
860
-
861
- def exec_distclean
862
- @installer.exec_distclean
863
- end
864
-
865
- end
866
-
867
-
868
- class ToplevelInstallerMulti < ToplevelInstaller
869
-
870
- include HookUtils
871
- include HookScriptAPI
872
- include FileOperations
873
-
874
- def initialize(ardir)
875
- super
876
- @packages = all_dirs_in("#{@ardir}/packages")
877
- raise 'no package exists' if @packages.empty?
878
- end
879
-
880
- def run_metaconfigs
881
- eval_file_ifexist "#{@ardir}/metaconfig"
882
- @packages.each do |name|
883
- eval_file_ifexist "#{@ardir}/packages/#{name}/metaconfig"
884
- end
885
- end
886
-
887
- def init_installers
888
- @installers = {}
889
- @packages.each do |pack|
890
- @installers[pack] = Installer.new(@config, @options,
891
- "#{@ardir}/packages/#{pack}",
892
- "packages/#{pack}")
893
- end
894
-
895
- with = extract_selection(config('with'))
896
- without = extract_selection(config('without'))
897
- @selected = @installers.keys.select {|name|
898
- (with.empty? or with.include?(name)) \
899
- and not without.include?(name)
900
- }
901
- end
902
-
903
- def extract_selection(list)
904
- a = list.split(/,/)
905
- a.each do |name|
906
- raise InstallError, "no such package: #{name}" \
907
- unless @installers.key?(name)
908
- end
909
- a
910
- end
911
-
912
- def print_usage(f)
913
- super
914
- f.puts 'Inluded packages:'
915
- f.puts ' ' + @packages.sort.join(' ')
916
- f.puts
917
- end
918
-
919
- #
920
- # multi-package metaconfig API
921
- #
922
-
923
- attr_reader :packages
924
-
925
- def declare_packages(list)
926
- raise 'package list is empty' if list.empty?
927
- list.each do |name|
928
- raise "directory packages/#{name} does not exist"\
929
- unless File.dir?("#{@ardir}/packages/#{name}")
930
- end
931
- @packages = list
932
- end
933
-
934
- #
935
- # Task Handlers
936
- #
937
-
938
- def exec_config
939
- run_hook 'pre-config'
940
- each_selected_installers {|inst| inst.exec_config }
941
- run_hook 'post-config'
942
- @config.save # must be final
943
- end
944
-
945
- def exec_setup
946
- run_hook 'pre-setup'
947
- each_selected_installers {|inst| inst.exec_setup }
948
- run_hook 'post-setup'
949
- end
950
-
951
- def exec_install
952
- run_hook 'pre-install'
953
- each_selected_installers {|inst| inst.exec_install }
954
- run_hook 'post-install'
955
- end
956
-
957
- def exec_clean
958
- rm_f 'config.save'
959
- run_hook 'pre-clean'
960
- each_selected_installers {|inst| inst.exec_clean }
961
- run_hook 'post-clean'
962
- end
963
-
964
- def exec_distclean
965
- rm_f 'config.save'
966
- run_hook 'pre-distclean'
967
- each_selected_installers {|inst| inst.exec_distclean }
968
- run_hook 'post-distclean'
969
- end
970
-
971
- #
972
- # lib
973
- #
974
-
975
- def each_selected_installers
976
- Dir.mkdir 'packages' unless File.dir?('packages')
977
- @selected.each do |pack|
978
- $stderr.puts "Processing the package `#{pack}' ..." if @options['verbose']
979
- Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}")
980
- Dir.chdir "packages/#{pack}"
981
- yield @installers[pack]
982
- Dir.chdir '../..'
983
- end
984
- end
985
-
986
- def verbose?
987
- @options['verbose']
988
- end
989
-
990
- def no_harm?
991
- @options['no-harm']
992
- end
993
-
994
- end
995
-
996
-
997
- class Installer
998
-
999
- FILETYPES = %w( bin lib ext data )
1000
-
1001
- include HookScriptAPI
1002
- include HookUtils
1003
- include FileOperations
1004
-
1005
- def initialize(config, opt, srcroot, objroot)
1006
- @config = config
1007
- @options = opt
1008
- @srcdir = File.expand_path(srcroot)
1009
- @objdir = File.expand_path(objroot)
1010
- @currdir = '.'
1011
- end
1012
-
1013
- def inspect
1014
- "#<#{self.class} #{File.basename(@srcdir)}>"
1015
- end
1016
-
1017
- #
1018
- # Hook Script API bases
1019
- #
1020
-
1021
- def srcdir_root
1022
- @srcdir
1023
- end
1024
-
1025
- def objdir_root
1026
- @objdir
1027
- end
1028
-
1029
- def relpath
1030
- @currdir
1031
- end
1032
-
1033
- #
1034
- # configs/options
1035
- #
1036
-
1037
- def no_harm?
1038
- @options['no-harm']
1039
- end
1040
-
1041
- def verbose?
1042
- @options['verbose']
1043
- end
1044
-
1045
- def verbose_off
1046
- begin
1047
- save, @options['verbose'] = @options['verbose'], false
1048
- yield
1049
- ensure
1050
- @options['verbose'] = save
1051
- end
1052
- end
1053
-
1054
- #
1055
- # TASK config
1056
- #
1057
-
1058
- def exec_config
1059
- exec_task_traverse 'config'
1060
- end
1061
-
1062
- def config_dir_bin(rel)
1063
- end
1064
-
1065
- def config_dir_lib(rel)
1066
- end
1067
-
1068
- def config_dir_ext(rel)
1069
- extconf if extdir?(curr_srcdir())
1070
- end
1071
-
1072
- def extconf
1073
- opt = @options['config-opt'].join(' ')
1074
- command "#{config('ruby-prog')} #{curr_srcdir()}/extconf.rb #{opt}"
1075
- end
1076
-
1077
- def config_dir_data(rel)
1078
- end
1079
-
1080
- #
1081
- # TASK setup
1082
- #
1083
-
1084
- def exec_setup
1085
- exec_task_traverse 'setup'
1086
- end
1087
-
1088
- def setup_dir_bin(rel)
1089
- all_files_in(curr_srcdir()).each do |fname|
1090
- adjust_shebang "#{curr_srcdir()}/#{fname}"
1091
- end
1092
- end
1093
-
1094
- # modify: #!/usr/bin/ruby
1095
- # modify: #! /usr/bin/ruby
1096
- # modify: #!ruby
1097
- # not modify: #!/usr/bin/env ruby
1098
- SHEBANG_RE = /\A\#!\s*\S*ruby\S*/
1099
-
1100
- def adjust_shebang(path)
1101
- return if no_harm?
1102
-
1103
- tmpfile = File.basename(path) + '.tmp'
1104
- begin
1105
- File.open(path, 'rb') {|r|
1106
- File.open(tmpfile, 'wb') {|w|
1107
- first = r.gets
1108
- return unless SHEBANG_RE =~ first
1109
-
1110
- $stderr.puts "adjusting shebang: #{File.basename path}" if verbose?
1111
- w.print first.sub(SHEBANG_RE, '#!' + config('ruby-path'))
1112
- w.write r.read
1113
- }
1114
- }
1115
- move_file tmpfile, File.basename(path)
1116
- ensure
1117
- File.unlink tmpfile if File.exist?(tmpfile)
1118
- end
1119
- end
1120
-
1121
- def setup_dir_lib(rel)
1122
- end
1123
-
1124
- def setup_dir_ext(rel)
1125
- make if extdir?(curr_srcdir())
1126
- end
1127
-
1128
- def setup_dir_data(rel)
1129
- end
1130
-
1131
- #
1132
- # TASK install
1133
- #
1134
-
1135
- def exec_install
1136
- exec_task_traverse 'install'
1137
- end
1138
-
1139
- def install_dir_bin(rel)
1140
- list = collect_filenames_auto
1141
- install_files list, "#{config('bin-dir')}/#{rel}", 0755
1142
- install_cmd_files list, "#{config('bin-dir')}/#{rel}", 0755
1143
- end
1144
-
1145
- def install_dir_lib(rel)
1146
- install_files ruby_scripts(), "#{config('rb-dir')}/#{rel}", 0644
1147
- end
1148
-
1149
- def install_dir_ext(rel)
1150
- return unless extdir?(curr_srcdir())
1151
- install_files ruby_extentions('.'),
1152
- "#{config('so-dir')}/#{File.dirname(rel)}",
1153
- 0555
1154
- end
1155
-
1156
- def install_dir_data(rel)
1157
- install_files collect_filenames_auto(), "#{config('data-dir')}/#{rel}", 0644
1158
- end
1159
-
1160
- def install_cmd_files(list, dest, mode)
1161
- if Config::CONFIG["arch"] =~ /dos|win32/i
1162
- mkdir_p dest, @options['install-prefix']
1163
- list.each do |fname|
1164
- next if no_harm?
1165
- File.open(File.join(dest, "#{fname}.cmd"), "w") do |file|
1166
- file.puts "@ruby \"#{File.join(dest, fname)}\" %*"
1167
- end
1168
- File.chmod mode, File.join(dest, "#{fname}.cmd")
1169
- end
1170
- end
1171
- end
1172
-
1173
- def install_files(list, dest, mode)
1174
- mkdir_p dest, @options['install-prefix']
1175
- list.each do |fname|
1176
- install fname, dest, mode, @options['install-prefix']
1177
- end
1178
- end
1179
-
1180
- def ruby_scripts
1181
- collect_filenames_auto().select {|n| /\.r(b|html)\z/ =~ n}
1182
- end
1183
-
1184
- # picked up many entries from cvs-1.11.1/src/ignore.c
1185
- reject_patterns = %w(
1186
- core RCSLOG tags TAGS .make.state
1187
- .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb
1188
- *~ *.old *.bak *.BAK *.orig *.rej _$* *$
1189
-
1190
- *.org *.in .*
1191
- )
1192
- mapping = {
1193
- '.' => '\.',
1194
- '$' => '\$',
1195
- '#' => '\#',
1196
- '*' => '.*'
1197
- }
1198
- REJECT_PATTERNS = Regexp.new('\A(?:' +
1199
- reject_patterns.map {|pat|
1200
- pat.gsub(/[\.\$\#\*]/) {|ch| mapping[ch] }
1201
- }.join('|') +
1202
- ')\z')
1203
-
1204
- def collect_filenames_auto
1205
- mapdir((existfiles() - hookfiles()).reject {|fname|
1206
- REJECT_PATTERNS =~ fname
1207
- })
1208
- end
1209
-
1210
- def existfiles
1211
- all_files_in(curr_srcdir()) | all_files_in('.')
1212
- end
1213
-
1214
- def hookfiles
1215
- %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt|
1216
- %w( config setup install clean ).map {|t| sprintf(fmt, t) }
1217
- }.flatten
1218
- end
1219
-
1220
- def mapdir(filelist)
1221
- filelist.map {|fname|
1222
- if File.exist?(fname) # objdir
1223
- fname
1224
- else # srcdir
1225
- File.join(curr_srcdir(), fname)
1226
- end
1227
- }
1228
- end
1229
-
1230
- def ruby_extentions(dir)
1231
- _ruby_extentions(dir) or
1232
- raise InstallError, "no ruby extention exists: 'ruby #{$0} setup' first"
1233
- end
1234
-
1235
- DLEXT = /\.#{ ::Config::CONFIG['DLEXT'] }\z/
1236
-
1237
- def _ruby_extentions(dir)
1238
- Dir.open(dir) {|d|
1239
- return d.select {|fname| DLEXT =~ fname }
1240
- }
1241
- end
1242
-
1243
- #
1244
- # TASK clean
1245
- #
1246
-
1247
- def exec_clean
1248
- exec_task_traverse 'clean'
1249
- rm_f 'config.save'
1250
- rm_f 'InstalledFiles'
1251
- end
1252
-
1253
- def clean_dir_bin(rel)
1254
- end
1255
-
1256
- def clean_dir_lib(rel)
1257
- end
1258
-
1259
- def clean_dir_ext(rel)
1260
- return unless extdir?(curr_srcdir())
1261
- make 'clean' if File.file?('Makefile')
1262
- end
1263
-
1264
- def clean_dir_data(rel)
1265
- end
1266
-
1267
- #
1268
- # TASK distclean
1269
- #
1270
-
1271
- def exec_distclean
1272
- exec_task_traverse 'distclean'
1273
- rm_f 'config.save'
1274
- rm_f 'InstalledFiles'
1275
- end
1276
-
1277
- def distclean_dir_bin(rel)
1278
- end
1279
-
1280
- def distclean_dir_lib(rel)
1281
- end
1282
-
1283
- def distclean_dir_ext(rel)
1284
- return unless extdir?(curr_srcdir())
1285
- make 'distclean' if File.file?('Makefile')
1286
- end
1287
-
1288
- #
1289
- # lib
1290
- #
1291
-
1292
- def exec_task_traverse(task)
1293
- run_hook "pre-#{task}"
1294
- FILETYPES.each do |type|
1295
- if config('without-ext') == 'yes' and type == 'ext'
1296
- $stderr.puts 'skipping ext/* by user option' if verbose?
1297
- next
1298
- end
1299
- traverse task, type, "#{task}_dir_#{type}"
1300
- end
1301
- run_hook "post-#{task}"
1302
- end
1303
-
1304
- def traverse(task, rel, mid)
1305
- dive_into(rel) {
1306
- run_hook "pre-#{task}"
1307
- __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '')
1308
- all_dirs_in(curr_srcdir()).each do |d|
1309
- traverse task, "#{rel}/#{d}", mid
1310
- end
1311
- run_hook "post-#{task}"
1312
- }
1313
- end
1314
-
1315
- def dive_into(rel)
1316
- return unless File.dir?("#{@srcdir}/#{rel}")
1317
-
1318
- dir = File.basename(rel)
1319
- Dir.mkdir dir unless File.dir?(dir)
1320
- prevdir = Dir.pwd
1321
- Dir.chdir dir
1322
- $stderr.puts '---> ' + rel if verbose?
1323
- @currdir = rel
1324
- yield
1325
- Dir.chdir prevdir
1326
- $stderr.puts '<--- ' + rel if verbose?
1327
- @currdir = File.dirname(rel)
1328
- end
1329
-
1330
- end
1331
-
1332
-
1333
- if $0 == __FILE__
1334
- begin
1335
- if multipackage_install?
1336
- ToplevelInstallerMulti.invoke
1337
- else
1338
- ToplevelInstaller.invoke
1339
- end
1340
- rescue
1341
- raise if $DEBUG
1342
- $stderr.puts $!.message
1343
- $stderr.puts "Try 'ruby #{$0} --help' for detailed usage."
1344
- exit 1
1345
- end
1346
- end