swiftiply 0.5.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/README +126 -0
- data/bin/mongrel_rails +254 -0
- data/bin/swiftiply +136 -0
- data/bin/swiftiply_mongrel_rails +54 -0
- data/external/package.rb +672 -0
- data/external/test_support.rb +58 -0
- data/setup.rb +40 -0
- data/src/ramaze/adapter/evented_mongrel.rb +2 -0
- data/src/ramaze/adapter/swiftiplied_mongrel.rb +2 -0
- data/src/swiftcore/Swiftiply.rb +444 -0
- data/src/swiftcore/Swiftiply.rb.orig +390 -0
- data/src/swiftcore/evented_mongrel.rb +182 -0
- data/src/swiftcore/swiftiplied_mongrel.rb +212 -0
- data/swiftiply.gemspec +41 -0
- data/test/rails/README +182 -0
- data/test/rails/Rakefile +10 -0
- data/test/rails/app/controllers/application.rb +6 -0
- data/test/rails/app/controllers/tests_controller.rb +15 -0
- data/test/rails/app/helpers/application_helper.rb +3 -0
- data/test/rails/config/boot.rb +45 -0
- data/test/rails/config/database.yml +36 -0
- data/test/rails/config/environment.rb +60 -0
- data/test/rails/config/environments/development.rb +21 -0
- data/test/rails/config/environments/production.rb +18 -0
- data/test/rails/config/environments/production_no_caching.rb +18 -0
- data/test/rails/config/environments/test.rb +19 -0
- data/test/rails/config/routes.rb +23 -0
- data/test/rails/doc/README_FOR_APP +2 -0
- data/test/rails/observe_ram.rb +10 -0
- data/test/rails/public/404.html +30 -0
- data/test/rails/public/500.html +30 -0
- data/test/rails/public/dispatch.cgi +10 -0
- data/test/rails/public/dispatch.fcgi +24 -0
- data/test/rails/public/dispatch.rb +10 -0
- data/test/rails/public/favicon.ico +0 -0
- data/test/rails/public/images/rails.png +0 -0
- data/test/rails/public/index.html +277 -0
- data/test/rails/public/javascripts/application.js +2 -0
- data/test/rails/public/javascripts/controls.js +833 -0
- data/test/rails/public/javascripts/dragdrop.js +942 -0
- data/test/rails/public/javascripts/effects.js +1088 -0
- data/test/rails/public/javascripts/prototype.js +2515 -0
- data/test/rails/public/robots.txt +1 -0
- data/test/rails/script/about +3 -0
- data/test/rails/script/breakpointer +3 -0
- data/test/rails/script/console +3 -0
- data/test/rails/script/destroy +3 -0
- data/test/rails/script/generate +3 -0
- data/test/rails/script/performance/benchmarker +3 -0
- data/test/rails/script/performance/profiler +3 -0
- data/test/rails/script/plugin +3 -0
- data/test/rails/script/process/inspector +3 -0
- data/test/rails/script/process/reaper +3 -0
- data/test/rails/script/process/spawner +3 -0
- data/test/rails/script/runner +3 -0
- data/test/rails/script/server +3 -0
- data/test/rails/test/test_helper.rb +28 -0
- data/test/ramaze/conf/benchmark.yaml +35 -0
- data/test/ramaze/conf/debug.yaml +34 -0
- data/test/ramaze/conf/live.yaml +33 -0
- data/test/ramaze/conf/silent.yaml +31 -0
- data/test/ramaze/conf/stage.yaml +33 -0
- data/test/ramaze/main.rb +18 -0
- data/test/ramaze/public/404.jpg +0 -0
- data/test/ramaze/public/css/coderay.css +105 -0
- data/test/ramaze/public/css/ramaze_error.css +42 -0
- data/test/ramaze/public/error.zmr +77 -0
- data/test/ramaze/public/favicon.ico +0 -0
- data/test/ramaze/public/js/jquery.js +1923 -0
- data/test/ramaze/public/ramaze.png +0 -0
- data/test/ramaze/src/controller/main.rb +8 -0
- data/test/ramaze/src/element/page.rb +17 -0
- data/test/ramaze/src/model.rb +6 -0
- data/test/ramaze/template/index.xhtml +6 -0
- data/test/ramaze/yaml.db +0 -0
- metadata +189 -0
@@ -0,0 +1,54 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
ENV['SWIFT'] = 'true'
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
class MongrelSwiftStart
|
7
|
+
|
8
|
+
def self.parse_options(config = {})
|
9
|
+
defaults={:env => 'production',
|
10
|
+
:pid => (File.expand_path(Dir.pwd)+'/log'),
|
11
|
+
:host => '127.0.0.1',
|
12
|
+
:port => 4000,
|
13
|
+
:num => 1
|
14
|
+
}
|
15
|
+
OptionParser.new do |opts|
|
16
|
+
opts.banner = 'Usage: mongrel_swift [options]'
|
17
|
+
opts.separator ''
|
18
|
+
opts.on('-C','--config CONFFILE',"The mongrel configuration file to read.") do |conf|
|
19
|
+
config[:conf] = conf
|
20
|
+
end
|
21
|
+
opts.on('-h','--host [HOST]','The hostname/IP address that the swiftiply proxy will listen on for backend connections.') do |host|
|
22
|
+
config[:host] = host
|
23
|
+
end
|
24
|
+
opts.on('-p','--port [PORT]','The port that swiftiply proxy is listening on for backend connections. Use the same port for all mongrels!') do |port|
|
25
|
+
config[:port] = port
|
26
|
+
end
|
27
|
+
opts.on('-d','--daemonize','Whether mongrel_rails should put itself into the background.') do |yn|
|
28
|
+
config[:daemonize] = true
|
29
|
+
end
|
30
|
+
opts.on('-n','--num-mongrels [NUM]','The number of mongrels to start.') do |numm|
|
31
|
+
config[:num] = numm.to_i
|
32
|
+
end
|
33
|
+
opts.on('-P','--pidfiles [NUM]','Path to store PID files.') do |numm|
|
34
|
+
config[:num] = numm.to_i
|
35
|
+
end
|
36
|
+
end.parse!
|
37
|
+
@config = defaults.update(config)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.run
|
41
|
+
parse_options
|
42
|
+
@config[:num].times do |i|
|
43
|
+
cmd = "mongrel_rails start -p #{@config[:port]} " <<
|
44
|
+
"-e #{@config[:env]} #{@config[:daemonize] ? '-d' : ''}" <<
|
45
|
+
"-P #{File.join(@config[:pid],'dog' + i.to_s + '.pid')}" <<
|
46
|
+
"#{@config[:conf] ? ' -C '+@config[:conf] : ''}"
|
47
|
+
output = `#{cmd}`
|
48
|
+
puts output
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
MongrelSwiftStart.run
|
data/external/package.rb
ADDED
@@ -0,0 +1,672 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'optparse'
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
class String
|
7
|
+
# This patch for win32 paths contributed by James Britt.
|
8
|
+
def w32
|
9
|
+
if self =~ /^\w:\/\w:/i
|
10
|
+
self.gsub(/^\w:\//i, '')
|
11
|
+
else
|
12
|
+
self
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module Package
|
18
|
+
|
19
|
+
class SpecificationError < StandardError; end
|
20
|
+
class PackageSpecification_1_0; end
|
21
|
+
|
22
|
+
SEMANTICS = { "1.0" => PackageSpecification_1_0 }
|
23
|
+
|
24
|
+
KINDS = [
|
25
|
+
:bin, :lib, :ext, :data, :conf, :doc
|
26
|
+
]
|
27
|
+
|
28
|
+
mapping = { '.' => '\.', '$' => '\$', '#' => '\#', '*' => '.*' }
|
29
|
+
ignore_files = %w[core RCSLOG tags TAGS .make.state .nse_depinfo .hg
|
30
|
+
#* .#* cvslog.* ,* .del-* *.olb *~ *.old *.bak *.BAK *.orig *.rej _$* *$
|
31
|
+
*.org *.in .* ]
|
32
|
+
|
33
|
+
IGNORE_FILES = ignore_files.map do |x|
|
34
|
+
Regexp.new('\A' + x.gsub(/[\.\$\#\*]/){|c| mapping[c]} + '\z')
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.config(name)
|
38
|
+
# XXX use pathname
|
39
|
+
prefix = Regexp.quote(Config::CONFIG["prefix"])
|
40
|
+
exec_prefix = Regexp.quote(Config::CONFIG["exec_prefix"])
|
41
|
+
Config::CONFIG[name].gsub(/\A\/?(#{prefix}|#{exec_prefix})\/?/, '')
|
42
|
+
end
|
43
|
+
|
44
|
+
SITE_DIRS = {
|
45
|
+
:bin => config("bindir"),
|
46
|
+
:lib => config("sitelibdir"),
|
47
|
+
:ext => config("sitearchdir"),
|
48
|
+
:data => config("datadir"),
|
49
|
+
:conf => config("sysconfdir"),
|
50
|
+
:doc => File.join(config("datadir"), "doc"),
|
51
|
+
}
|
52
|
+
|
53
|
+
VENDOR_DIRS = {
|
54
|
+
:bin => config("bindir"),
|
55
|
+
:lib => config("rubylibdir"),
|
56
|
+
:ext => config("archdir"),
|
57
|
+
:data => config("datadir"),
|
58
|
+
:conf => config("sysconfdir"),
|
59
|
+
:doc => File.join(config("datadir"), "doc"),
|
60
|
+
}
|
61
|
+
|
62
|
+
MODES = {
|
63
|
+
:bin => 0755,
|
64
|
+
:lib => 0644,
|
65
|
+
:ext => 0755, # was: 0555,
|
66
|
+
:data => 0644,
|
67
|
+
:conf => 0644,
|
68
|
+
:doc => 0644,
|
69
|
+
}
|
70
|
+
|
71
|
+
|
72
|
+
SETUP_OPTIONS = {:parse_cmdline => true, :load_conf => true, :run_tasks => true}
|
73
|
+
RUBY_BIN = File.join(::Config::CONFIG['bindir'],::Config::CONFIG['ruby_install_name']) << ::Config::CONFIG['EXEEXT']
|
74
|
+
|
75
|
+
def self.setup(version, options = {}, &instructions)
|
76
|
+
prefixes = dirs = nil
|
77
|
+
options = SETUP_OPTIONS.dup.update(options)
|
78
|
+
|
79
|
+
if options[:load_conf] && File.exist?("config.save")
|
80
|
+
config = YAML.load_file "config.save"
|
81
|
+
prefixes = config[:prefixes]
|
82
|
+
dirs = config[:dirs]
|
83
|
+
end
|
84
|
+
|
85
|
+
pkg = package_specification_with_semantics(version).new(prefixes, dirs)
|
86
|
+
pkg.parse_command_line if options[:parse_cmdline]
|
87
|
+
pkg.instance_eval(&instructions)
|
88
|
+
|
89
|
+
pkg.run_tasks if options[:run_tasks]
|
90
|
+
|
91
|
+
# pkg.install
|
92
|
+
pkg
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.package_specification_with_semantics(version)
|
96
|
+
#XXX: implement the full x.y(.z)? semantics
|
97
|
+
r = SEMANTICS[version]
|
98
|
+
raise SpecificationError, "Unknown version #{version}." unless r
|
99
|
+
r
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
module Actions
|
104
|
+
|
105
|
+
class InstallFile
|
106
|
+
|
107
|
+
attr_reader :source, :destination, :mode
|
108
|
+
|
109
|
+
def initialize(source, destination, mode, options)
|
110
|
+
@source = source
|
111
|
+
@destination = destination
|
112
|
+
@mode = mode
|
113
|
+
@options = options
|
114
|
+
end
|
115
|
+
|
116
|
+
def install
|
117
|
+
dirs = [@options.destdir.to_s, @destination].select {|x| x}
|
118
|
+
d = File.expand_path(File.join(dirs)).w32
|
119
|
+
FileUtils.install @source, d,
|
120
|
+
{:verbose => @options.verbose,
|
121
|
+
:noop => @options.noop, :mode => @mode }
|
122
|
+
end
|
123
|
+
|
124
|
+
def hash
|
125
|
+
[@source.hash, @destination.hash].hash
|
126
|
+
end
|
127
|
+
|
128
|
+
def eql?(other)
|
129
|
+
self.class == other.class &&
|
130
|
+
@source == other.source &&
|
131
|
+
@destination == other.destination &&
|
132
|
+
@mode == other.mode
|
133
|
+
end
|
134
|
+
|
135
|
+
def <=>(other)
|
136
|
+
FULL_ORDER[self, other] || self.destination <=> other.destination
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
class MkDir
|
141
|
+
|
142
|
+
attr_reader :directory
|
143
|
+
|
144
|
+
def initialize(directory, options)
|
145
|
+
@directory = directory
|
146
|
+
@options = options
|
147
|
+
end
|
148
|
+
|
149
|
+
def install
|
150
|
+
dirs = [@options.destdir.to_s, @directory].select {|x| x}
|
151
|
+
d = File.expand_path(File.join(dirs)).w32
|
152
|
+
FileUtils.mkdir_p d,
|
153
|
+
{:verbose => @options.verbose,
|
154
|
+
:noop => @options.noop }
|
155
|
+
end
|
156
|
+
|
157
|
+
def <=>(other)
|
158
|
+
FULL_ORDER[self, other] || self.directory <=> other.directory
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
class FixShebang
|
163
|
+
|
164
|
+
attr_reader :destination
|
165
|
+
|
166
|
+
def initialize(destination, options)
|
167
|
+
@options = options
|
168
|
+
@destination = destination
|
169
|
+
end
|
170
|
+
|
171
|
+
def install
|
172
|
+
dirs = [@options.destdir.to_s, @destination].select {|x| x}
|
173
|
+
d = File.expand_path(File.join(dirs)).w32
|
174
|
+
path = d
|
175
|
+
fix_shebang(path)
|
176
|
+
end
|
177
|
+
|
178
|
+
# taken from rpa-base, originally based on setup.rb's
|
179
|
+
# modify: #!/usr/bin/ruby
|
180
|
+
# modify: #! /usr/bin/ruby
|
181
|
+
# modify: #!ruby
|
182
|
+
# not modify: #!/usr/bin/env ruby
|
183
|
+
SHEBANG_RE = /\A\#!\s*\S*ruby\S*/
|
184
|
+
|
185
|
+
#TODO allow the ruby-prog to be placed in the shebang line to be passed as
|
186
|
+
# an option
|
187
|
+
def fix_shebang(path)
|
188
|
+
tmpfile = path + '.tmp'
|
189
|
+
begin
|
190
|
+
#XXX: needed at all?
|
191
|
+
# it seems that FileUtils doesn't expose its default output
|
192
|
+
# @fileutils_output = $stderr
|
193
|
+
# we might want to allow this to be redirected.
|
194
|
+
$stderr.puts "shebang:open #{tmpfile}" if @options.verbose
|
195
|
+
unless @options.noop
|
196
|
+
File.open(path) do |r|
|
197
|
+
File.open(tmpfile, 'w', 0755) do |w|
|
198
|
+
first = r.gets
|
199
|
+
return unless SHEBANG_RE =~ first
|
200
|
+
ruby = File.join(::Config::CONFIG['bindir'],::Config::CONFIG['ruby_install_name'])
|
201
|
+
ruby << ::Config::CONFIG['EXEEXT']
|
202
|
+
#w.print first.sub(SHEBANG_RE, '#!' + Config::CONFIG['ruby-prog'])
|
203
|
+
w.print first.sub(SHEBANG_RE, '#!' + ruby)
|
204
|
+
w.write r.read
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
FileUtils.mv(tmpfile, path, :verbose => @options.verbose,
|
209
|
+
:noop => @options.noop)
|
210
|
+
ensure
|
211
|
+
FileUtils.rm_f(tmpfile, :verbose => @options.verbose,
|
212
|
+
:noop => @options.noop)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def <=>(other)
|
217
|
+
FULL_ORDER[self, other] || self.destination <=> other.destination
|
218
|
+
end
|
219
|
+
|
220
|
+
def hash
|
221
|
+
@destination.hash
|
222
|
+
end
|
223
|
+
|
224
|
+
def eql?(other)
|
225
|
+
self.class == other.class && self.destination == other.destination
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
order = [MkDir, InstallFile, FixShebang]
|
230
|
+
FULL_ORDER = lambda do |me, other|
|
231
|
+
a, b = order.index(me.class), order.index(other.class)
|
232
|
+
if a && b
|
233
|
+
(r = a - b) == 0 ? nil : r
|
234
|
+
else
|
235
|
+
-1
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
class ActionList < Array
|
240
|
+
|
241
|
+
def directories!(options)
|
242
|
+
dirnames = []
|
243
|
+
map! do |d|
|
244
|
+
if d.kind_of?(InstallFile) && !dirnames.include?(File.dirname(d.destination))
|
245
|
+
dirnames << File.dirname(d.destination)
|
246
|
+
[MkDir.new(File.dirname(d.destination), options), d]
|
247
|
+
else
|
248
|
+
d
|
249
|
+
end
|
250
|
+
end
|
251
|
+
flatten!
|
252
|
+
end
|
253
|
+
|
254
|
+
def run(task)
|
255
|
+
each { |action| action.__send__ task }
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
end # module Actions
|
260
|
+
|
261
|
+
Options = Struct.new(:noop, :verbose, :destdir, :nodoc)
|
262
|
+
|
263
|
+
class PackageSpecification_1_0
|
264
|
+
|
265
|
+
TASKS = %w[config setup install test show]
|
266
|
+
# default options for translate(foo => bar)
|
267
|
+
TRANSLATE_DEFAULT_OPTIONS = { :inherit => true }
|
268
|
+
|
269
|
+
def self.declare_file_type(args, &handle_arg)
|
270
|
+
str_arr_p = lambda{|x| Array === x && x.all?{|y| String === y}}
|
271
|
+
|
272
|
+
# strict type checking --- we don't want this to be extended arbitrarily
|
273
|
+
unless args.size == 1 && Hash === args.first &&
|
274
|
+
args.first.all?{|f,r| [Proc, String, NilClass].include?(r.class) &&
|
275
|
+
(String === f || str_arr_p[f])} or
|
276
|
+
args.all?{|x| String === x || str_arr_p[x]}
|
277
|
+
raise SpecificationError,
|
278
|
+
"Unspecified semantics for the given arguments: #{args.inspect}"
|
279
|
+
end
|
280
|
+
|
281
|
+
if args.size == 1 && Hash === args.first
|
282
|
+
args.first.to_a.each do |file, rename_info|
|
283
|
+
if Array === file
|
284
|
+
# ignoring boring files
|
285
|
+
handle_arg.call(file, true, rename_info)
|
286
|
+
else
|
287
|
+
# we do want "boring" files given explicitly
|
288
|
+
handle_arg.call([file], false, rename_info)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
else
|
292
|
+
args.each do |a|
|
293
|
+
if Array === a
|
294
|
+
a.each{|file| handle_arg.call(file, true, nil)}
|
295
|
+
else
|
296
|
+
handle_arg.call(a, false, nil)
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
#{{{ define the file tagging methods
|
303
|
+
KINDS.each do |kind|
|
304
|
+
define_method(kind) do |*args| # if this were 1.9 we could also take a block
|
305
|
+
bin_callback = lambda do |kind_, type, dest, options|
|
306
|
+
next if kind_ != :bin || type == :dir
|
307
|
+
@actions << Actions::FixShebang.new(dest, options)
|
308
|
+
end
|
309
|
+
#TODO: refactor
|
310
|
+
self.class.declare_file_type(args) do |files, ignore_p, opt_rename_info|
|
311
|
+
files.each do |file|
|
312
|
+
next if ignore_p && IGNORE_FILES.any?{|re| re.match(file)}
|
313
|
+
add_file(kind, file, opt_rename_info, &bin_callback)
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
def unit_test(*files)
|
320
|
+
if ARGV.length > 0
|
321
|
+
files.each do |x|
|
322
|
+
@unit_tests.concat([x]) if ARGV.include?(File.basename(x).sub(/\.\w+$/,''))
|
323
|
+
end
|
324
|
+
else
|
325
|
+
@unit_tests.concat files.flatten
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
def ri(*files)
|
330
|
+
@ri_files.concat files.flatten
|
331
|
+
end
|
332
|
+
|
333
|
+
def build_ext(path,opts = {:mkmf => true}, &blk)
|
334
|
+
@ext_targets << [path,opts,blk]
|
335
|
+
end
|
336
|
+
|
337
|
+
attr_accessor :actions, :options
|
338
|
+
|
339
|
+
def self.metadata(name)
|
340
|
+
define_method(name) do |*args|
|
341
|
+
if args.size == 1
|
342
|
+
@metadata[name] = args.first
|
343
|
+
end
|
344
|
+
@metadata[name]
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
metadata :name
|
349
|
+
metadata :version
|
350
|
+
metadata :author
|
351
|
+
|
352
|
+
def translate_dir(kind, dir)
|
353
|
+
replaced_dir_parts = dir.split(%r{/})
|
354
|
+
kept_dir_parts = []
|
355
|
+
loop do
|
356
|
+
replaced_path = replaced_dir_parts.join("/")
|
357
|
+
target, options = @translate[kind][replaced_path]
|
358
|
+
options ||= TRANSLATE_DEFAULT_OPTIONS
|
359
|
+
if target && (replaced_path == dir || options[:inherit])
|
360
|
+
dir = (target != '' ? File.join(target, *kept_dir_parts) :
|
361
|
+
File.join(*kept_dir_parts))
|
362
|
+
break
|
363
|
+
end
|
364
|
+
break if replaced_dir_parts.empty?
|
365
|
+
kept_dir_parts.unshift replaced_dir_parts.pop
|
366
|
+
end
|
367
|
+
dir
|
368
|
+
end
|
369
|
+
|
370
|
+
def add_file(kind, filename, new_filename_info, &callback)
|
371
|
+
#TODO: refactor!!!
|
372
|
+
if File.directory? filename #XXX setup.rb and rpa-base defined File.dir?
|
373
|
+
dir = filename.sub(/\A\.\//, "").sub(/\/\z/, "")
|
374
|
+
dest = File.join(@prefixes[kind], @dirs[kind], translate_dir(kind, dir))
|
375
|
+
@actions << Actions::MkDir.new(dest, @options)
|
376
|
+
callback.call(kind, :dir, dest, @options) if block_given?
|
377
|
+
else
|
378
|
+
if new_filename_info
|
379
|
+
case new_filename_info
|
380
|
+
when Proc
|
381
|
+
dest_name = new_filename_info.call(filename.dup)
|
382
|
+
else
|
383
|
+
dest_name = new_filename_info.dup
|
384
|
+
end
|
385
|
+
else
|
386
|
+
dest_name = filename.dup
|
387
|
+
end
|
388
|
+
|
389
|
+
dirname = File.dirname(dest_name)
|
390
|
+
dirname = "" if dirname == "."
|
391
|
+
dest_name = File.join(translate_dir(kind, dirname), File.basename(dest_name))
|
392
|
+
|
393
|
+
dest = File.join(@prefixes[kind], @dirs[kind], dest_name)
|
394
|
+
@actions << Actions::InstallFile.new(filename, dest, MODES[kind], @options)
|
395
|
+
callback.call(kind, :file, dest, @options) if block_given?
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
399
|
+
def initialize(prefixes = nil, dirs = nil)
|
400
|
+
@prefix = Config::CONFIG["prefix"].gsub(/\A\//, '')
|
401
|
+
@translate = {}
|
402
|
+
@prefixes = (prefixes || {}).dup
|
403
|
+
KINDS.each do |kind|
|
404
|
+
@prefixes[kind] = @prefix unless prefixes
|
405
|
+
@translate[kind] = {}
|
406
|
+
end
|
407
|
+
|
408
|
+
@dirs = (dirs || {}).dup
|
409
|
+
@dirs.update SITE_DIRS unless dirs
|
410
|
+
|
411
|
+
@actions = Actions::ActionList.new
|
412
|
+
|
413
|
+
@metadata = {}
|
414
|
+
@unit_tests = []
|
415
|
+
@ri_files = []
|
416
|
+
@ext_targets = []
|
417
|
+
|
418
|
+
@options = Options.new
|
419
|
+
@options.verbose = true
|
420
|
+
@options.noop = false # XXX for testing
|
421
|
+
@options.destdir = ''
|
422
|
+
|
423
|
+
@tasks = []
|
424
|
+
end
|
425
|
+
|
426
|
+
def aoki
|
427
|
+
(KINDS - [:ext]).each do |kind|
|
428
|
+
translate(kind, kind.to_s => "", :inherit => true)
|
429
|
+
__send__ kind, Dir["#{kind}/**/*"]
|
430
|
+
end
|
431
|
+
translate(:ext, "ext/*" => "", :inherit => true)
|
432
|
+
ext Dir["ext/**/*.#{Config::CONFIG['DLEXT']}"]
|
433
|
+
end
|
434
|
+
|
435
|
+
# Builds any needed extensions.
|
436
|
+
|
437
|
+
def setup
|
438
|
+
@ext_targets.each do |et|
|
439
|
+
path, options, block = et
|
440
|
+
path = expand_ext_path(path)
|
441
|
+
case
|
442
|
+
when options[:mkmf]
|
443
|
+
setup_mkmf(path, options, block)
|
444
|
+
end
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
def expand_ext_path(path)
|
449
|
+
if path =~ /#{File::SEPARATOR}/
|
450
|
+
extpath = File.expand_path(path)
|
451
|
+
else
|
452
|
+
extpath = File.expand_path(File.join('ext',path,'extconf.rb'))
|
453
|
+
end
|
454
|
+
unless extpath =~ /\.rb$/
|
455
|
+
extpath = File.join(extpath,'extconf.rb')
|
456
|
+
end
|
457
|
+
extpath
|
458
|
+
end
|
459
|
+
|
460
|
+
def setup_mkmf(execpath, options, block)
|
461
|
+
$stderr.puts "Building extension in #{File.dirname(execpath)} with #{options.inspect}."
|
462
|
+
cwd = Dir.pwd
|
463
|
+
begin
|
464
|
+
if block
|
465
|
+
block.call(options)
|
466
|
+
else
|
467
|
+
Dir.chdir(File.dirname(execpath))
|
468
|
+
system('make','clean') if FileTest.exist? "Makefile"
|
469
|
+
system(RUBY_BIN,execpath)
|
470
|
+
system('make')
|
471
|
+
end
|
472
|
+
ensure
|
473
|
+
Dir.chdir(cwd)
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
def install
|
478
|
+
$stderr.puts "Installing #{name || "unknown package"} #{version}..." if options.verbose
|
479
|
+
|
480
|
+
actions.uniq!
|
481
|
+
actions.sort!
|
482
|
+
actions.directories!(options)
|
483
|
+
|
484
|
+
actions.run :install
|
485
|
+
|
486
|
+
unless @ri_files.empty? or @options.nodoc
|
487
|
+
$stderr.puts "Generating ri documentation from #{@ri_files.join(',')}"
|
488
|
+
require 'rdoc/rdoc'
|
489
|
+
unless options.noop
|
490
|
+
begin
|
491
|
+
RDoc::RDoc.new.document(["--ri-site"].concat(@ri_files.flatten))
|
492
|
+
rescue Exception => e
|
493
|
+
$stderr.write("Installation of ri documentation failed: #{e.to_s} #{e.backtrace.join("\n")}")
|
494
|
+
end
|
495
|
+
end
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
def test
|
500
|
+
unless @unit_tests.empty?
|
501
|
+
puts "Testing #{name || "unknown package"} #{version}..." if options.verbose
|
502
|
+
require 'test/unit'
|
503
|
+
unless options.noop
|
504
|
+
t = Test::Unit::AutoRunner.new(true)
|
505
|
+
t.process_args(@unit_tests)
|
506
|
+
t.run
|
507
|
+
end
|
508
|
+
end
|
509
|
+
end
|
510
|
+
|
511
|
+
def config
|
512
|
+
File.open("config.save", "w") do |f|
|
513
|
+
YAML.dump({:prefixes => @prefixes, :dirs => @dirs}, f)
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
517
|
+
def show
|
518
|
+
KINDS.each do |kind|
|
519
|
+
puts "#{kind}\t#{File.join(options.destdir, @prefixes[kind], @dirs[kind])}"
|
520
|
+
end
|
521
|
+
end
|
522
|
+
|
523
|
+
def translate(kind, additional_translations)
|
524
|
+
default_opts = TRANSLATE_DEFAULT_OPTIONS.dup
|
525
|
+
key_val_pairs = additional_translations.to_a
|
526
|
+
option_pairs = key_val_pairs.select{|(k,v)| Symbol === k}
|
527
|
+
default_opts.update(Hash[*option_pairs.flatten])
|
528
|
+
|
529
|
+
(key_val_pairs - option_pairs).each do |key, val|
|
530
|
+
add_translation(kind, key, val, default_opts)
|
531
|
+
end
|
532
|
+
end
|
533
|
+
|
534
|
+
def add_translation(kind, src, dest, options)
|
535
|
+
if is_glob?(src)
|
536
|
+
dirs = expand_dir_glob(src)
|
537
|
+
else
|
538
|
+
dirs = [src]
|
539
|
+
end
|
540
|
+
dirs.each do |dirname|
|
541
|
+
dirname = dirname.sub(%r{\A\./}, "").sub(%r{/\z}, "")
|
542
|
+
@translate[kind].update({dirname => [dest, options]})
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
546
|
+
def is_glob?(x)
|
547
|
+
/(^|[^\\])[*?{\[]/.match(x)
|
548
|
+
end
|
549
|
+
|
550
|
+
def expand_dir_glob(src)
|
551
|
+
Dir[src].select{|x| File.directory?(x)}
|
552
|
+
end
|
553
|
+
|
554
|
+
def clean_path(path)
|
555
|
+
path.gsub(/\A\//, '').gsub(/\/+\Z/, '').squeeze("/")
|
556
|
+
end
|
557
|
+
|
558
|
+
def parse_command_line
|
559
|
+
opts = OptionParser.new(nil, 24, ' ') do |opts|
|
560
|
+
opts.banner = "Usage: setup.rb [options] [task]"
|
561
|
+
|
562
|
+
opts.separator ""
|
563
|
+
opts.separator "Tasks:"
|
564
|
+
opts.separator " config configures paths"
|
565
|
+
opts.separator " show shows paths"
|
566
|
+
opts.separator " setup compiles ruby extentions and others XXX"
|
567
|
+
opts.separator " install installs files"
|
568
|
+
opts.separator " test runs unit tests"
|
569
|
+
|
570
|
+
|
571
|
+
opts.separator ""
|
572
|
+
opts.separator "Specific options:"
|
573
|
+
|
574
|
+
opts.on "--prefix=PREFIX",
|
575
|
+
"path prefix of target environment [#@prefix]" do |prefix|
|
576
|
+
@prefix.replace clean_path(prefix) # Shared!
|
577
|
+
end
|
578
|
+
|
579
|
+
opts.separator ""
|
580
|
+
|
581
|
+
KINDS.each do |kind|
|
582
|
+
opts.on "--#{kind}prefix=PREFIX",
|
583
|
+
"path prefix for #{kind} files [#{@prefixes[kind]}]" do |prefix|
|
584
|
+
@prefixes[kind] = clean_path(prefix)
|
585
|
+
end
|
586
|
+
end
|
587
|
+
|
588
|
+
opts.separator ""
|
589
|
+
|
590
|
+
KINDS.each do |kind|
|
591
|
+
opts.on "--#{kind}dir=PREFIX",
|
592
|
+
"directory for #{kind} files [#{@dirs[kind]}]" do |prefix|
|
593
|
+
@dirs[kind] = clean_path(prefix)
|
594
|
+
end
|
595
|
+
end
|
596
|
+
|
597
|
+
opts.separator ""
|
598
|
+
|
599
|
+
KINDS.each do |kind|
|
600
|
+
opts.on "--#{kind}=PREFIX",
|
601
|
+
"absolute directory for #{kind} files [#{File.join(@prefixes[kind], @dirs[kind])}]" do |prefix|
|
602
|
+
@prefixes[kind] = clean_path(prefix)
|
603
|
+
end
|
604
|
+
end
|
605
|
+
|
606
|
+
opts.separator ""
|
607
|
+
opts.separator "Predefined path configurations:"
|
608
|
+
opts.on "--site", "install into site-local directories (default)" do
|
609
|
+
@dirs.update SITE_DIRS
|
610
|
+
end
|
611
|
+
|
612
|
+
opts.on "--vendor", "install into distribution directories (for packagers)" do
|
613
|
+
@dirs.update VENDOR_DIRS
|
614
|
+
end
|
615
|
+
|
616
|
+
opts.separator ""
|
617
|
+
opts.separator "General options:"
|
618
|
+
|
619
|
+
opts.on "--destdir=DESTDIR",
|
620
|
+
"install all files relative to DESTDIR (/)" do |destdir|
|
621
|
+
@options.destdir = destdir
|
622
|
+
end
|
623
|
+
|
624
|
+
opts.on "--dry-run", "only display what to do if given [#{@options.noop}]" do
|
625
|
+
@options.noop = true
|
626
|
+
end
|
627
|
+
|
628
|
+
opts.on "--no-harm", "only display what to do if given" do
|
629
|
+
@options.noop = true
|
630
|
+
end
|
631
|
+
|
632
|
+
opts.on "--no-doc","don't generate documentation" do
|
633
|
+
@options.nodoc = true
|
634
|
+
end
|
635
|
+
|
636
|
+
opts.on "--[no-]verbose", "output messages verbosely [#{@options.verbose}]" do |verbose|
|
637
|
+
@options.verbose = verbose
|
638
|
+
end
|
639
|
+
|
640
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
641
|
+
puts opts
|
642
|
+
exit
|
643
|
+
end
|
644
|
+
end
|
645
|
+
|
646
|
+
opts.parse! ARGV
|
647
|
+
|
648
|
+
#if (ARGV - TASKS).empty? # Only existing tasks?
|
649
|
+
@tasks = ARGV.dup.select do |t|
|
650
|
+
if TASKS.include?(t)
|
651
|
+
ARGV.delete(t)
|
652
|
+
true
|
653
|
+
end
|
654
|
+
end
|
655
|
+
|
656
|
+
@tasks = ["setup","install"] if @tasks.empty?
|
657
|
+
#else
|
658
|
+
# abort "Unknown task(s) #{(ARGV-TASKS).join ", "}."
|
659
|
+
#end
|
660
|
+
end
|
661
|
+
|
662
|
+
def run_tasks
|
663
|
+
@tasks.each { |task| __send__ task }
|
664
|
+
end
|
665
|
+
end
|
666
|
+
|
667
|
+
end # module Package
|
668
|
+
|
669
|
+
require 'rbconfig'
|
670
|
+
def config(x)
|
671
|
+
Config::CONFIG[x]
|
672
|
+
end
|