comp_tree 0.7.6 → 1.0.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/CHANGES.rdoc +6 -0
- data/MANIFEST +14 -15
- data/README.rdoc +13 -14
- data/Rakefile +1 -1
- data/devel/jumpstart.rb +591 -255
- data/install.rb +1 -2
- data/lib/comp_tree/algorithm.rb +44 -44
- data/lib/comp_tree/comp_tree.rb +55 -0
- data/lib/comp_tree/driver.rb +29 -38
- data/lib/comp_tree/error.rb +40 -6
- data/lib/comp_tree/node.rb +32 -27
- data/lib/comp_tree/queue/queue.rb +1 -0
- data/lib/comp_tree/{queue_old.rb → queue/queue_18.rb} +5 -5
- data/lib/comp_tree/{queue_new.rb → queue/queue_19.rb} +3 -1
- data/lib/comp_tree.rb +22 -75
- data/test/{test_basic.rb → basic_test.rb} +5 -3
- data/test/{test_circular.rb → circular_test.rb} +1 -1
- data/test/{common.rb → comp_tree_test_base.rb} +17 -4
- data/test/{test_drain.rb → drain_test.rb} +5 -6
- data/test/exception_test.rb +117 -0
- data/test/{test_flood.rb → flood_test.rb} +1 -1
- data/test/{test_grind.rb → grind_test.rb} +11 -12
- data/test/readme_test.rb +5 -0
- data/test/{test_sequential.rb → sequential_test.rb} +1 -1
- data/test/{test_throw.rb → throw_test.rb} +1 -1
- metadata +42 -43
- data/devel/jumpstart/lazy_attribute.rb +0 -38
- data/devel/jumpstart/ruby.rb +0 -44
- data/devel/jumpstart/simple_installer.rb +0 -85
- data/lib/comp_tree/queue.rb +0 -1
- data/test/test_exception.rb +0 -84
data/devel/jumpstart.rb
CHANGED
@@ -1,281 +1,543 @@
|
|
1
|
-
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
2
|
-
$LOAD_PATH.unshift File.dirname(__FILE__)
|
3
|
-
|
4
|
-
require 'rubygems'
|
5
|
-
require 'ostruct'
|
6
|
-
require 'rbconfig'
|
7
|
-
|
8
|
-
require 'rake/gempackagetask'
|
9
|
-
require 'rake/contrib/sshpublisher'
|
10
|
-
require 'rake/clean'
|
11
|
-
|
12
|
-
require 'rdoc/rdoc'
|
13
|
-
|
14
|
-
require 'jumpstart/ruby'
|
15
|
-
require 'jumpstart/lazy_attribute'
|
16
|
-
require 'jumpstart/simple_installer'
|
17
1
|
|
18
2
|
class Jumpstart
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
3
|
+
class SimpleInstaller
|
4
|
+
def initialize
|
5
|
+
require 'fileutils'
|
6
|
+
require 'rbconfig'
|
7
|
+
require 'find'
|
8
|
+
dest_root = Config::CONFIG["sitelibdir"]
|
9
|
+
sources = []
|
10
|
+
Find.find("./lib") { |source|
|
11
|
+
if install_file?(source)
|
12
|
+
sources << source
|
13
|
+
end
|
14
|
+
}
|
15
|
+
@spec = sources.inject(Array.new) { |acc, source|
|
16
|
+
if source == "./lib"
|
17
|
+
acc
|
18
|
+
else
|
19
|
+
dest = File.join(dest_root, source.sub(%r!\A\./lib!, ""))
|
20
|
+
|
21
|
+
install = lambda {
|
22
|
+
if File.directory?(source)
|
23
|
+
unless File.directory?(dest)
|
24
|
+
puts "mkdir #{dest}"
|
25
|
+
FileUtils.mkdir(dest)
|
26
|
+
end
|
37
27
|
else
|
38
|
-
|
28
|
+
puts "install #{source} --> #{dest}"
|
29
|
+
FileUtils.install(source, dest)
|
39
30
|
end
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
31
|
+
}
|
32
|
+
|
33
|
+
uninstall = lambda {
|
34
|
+
if File.directory?(source)
|
35
|
+
if File.directory?(dest)
|
36
|
+
puts "rmdir #{dest}"
|
37
|
+
FileUtils.rmdir(dest)
|
38
|
+
end
|
39
|
+
else
|
40
|
+
if File.file?(dest)
|
41
|
+
puts "rm #{dest}"
|
42
|
+
FileUtils.rm(dest)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
}
|
46
|
+
|
47
|
+
acc << {
|
48
|
+
:source => source,
|
49
|
+
:dest => dest,
|
50
|
+
:install => install,
|
51
|
+
:uninstall => uninstall,
|
52
|
+
}
|
44
53
|
end
|
45
|
-
|
46
|
-
"0.0.0"
|
47
|
-
end
|
54
|
+
}
|
48
55
|
end
|
49
|
-
|
50
|
-
|
51
|
-
|
56
|
+
|
57
|
+
def install_file?(source)
|
58
|
+
File.directory?(source) or
|
59
|
+
(File.file?(source) and File.extname(source) == ".rb")
|
52
60
|
end
|
53
61
|
|
54
|
-
|
55
|
-
|
62
|
+
def install
|
63
|
+
@spec.each { |entry|
|
64
|
+
entry[:install].call
|
65
|
+
}
|
56
66
|
end
|
57
|
-
|
58
|
-
|
59
|
-
|
67
|
+
|
68
|
+
def uninstall
|
69
|
+
@spec.reverse.each { |entry|
|
70
|
+
entry[:uninstall].call
|
71
|
+
}
|
60
72
|
end
|
61
73
|
|
62
|
-
|
63
|
-
|
74
|
+
def run(args = ARGV)
|
75
|
+
if args.empty?
|
76
|
+
install
|
77
|
+
elsif args.size == 1 and args.first == "--uninstall"
|
78
|
+
uninstall
|
79
|
+
else
|
80
|
+
raise "unrecognized arguments: #{args.inspect}"
|
81
|
+
end
|
64
82
|
end
|
83
|
+
end
|
65
84
|
|
66
|
-
|
67
|
-
|
85
|
+
module AttrLazy
|
86
|
+
def attr_lazy(name, &block)
|
87
|
+
AttrLazy.define_reader(class << self ; self ; end, name, &block)
|
68
88
|
end
|
69
89
|
|
70
|
-
|
71
|
-
|
90
|
+
def attr_lazy_accessor(name, &block)
|
91
|
+
attr_lazy(name, &block)
|
92
|
+
AttrLazy.define_writer(class << self ; self ; end, name, &block)
|
72
93
|
end
|
73
94
|
|
74
|
-
|
75
|
-
|
76
|
-
|
95
|
+
class << self
|
96
|
+
def included(mod)
|
97
|
+
(class << mod ; self ; end).class_eval do
|
98
|
+
def attr_lazy(name, &block)
|
99
|
+
AttrLazy.define_reader(self, name, &block)
|
100
|
+
end
|
77
101
|
|
78
|
-
|
79
|
-
|
80
|
-
|
102
|
+
def attr_lazy_accessor(name, &block)
|
103
|
+
attr_lazy(name, &block)
|
104
|
+
AttrLazy.define_writer(self, name, &block)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
81
108
|
|
82
|
-
|
83
|
-
|
84
|
-
|
109
|
+
def define_evaluated_reader(instance, name, value)
|
110
|
+
(class << instance ; self ; end).class_eval do
|
111
|
+
remove_method name rescue nil
|
112
|
+
define_method name do
|
113
|
+
value
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
85
117
|
|
86
|
-
|
87
|
-
|
88
|
-
|
118
|
+
def define_reader(klass, name, &block)
|
119
|
+
klass.class_eval do
|
120
|
+
remove_method name rescue nil
|
121
|
+
define_method name do
|
122
|
+
value = instance_eval(&block)
|
123
|
+
AttrLazy.define_evaluated_reader(self, name, value)
|
124
|
+
value
|
125
|
+
end
|
126
|
+
end
|
89
127
|
end
|
90
|
-
}
|
91
128
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
129
|
+
def define_writer(klass, name, &block)
|
130
|
+
klass.class_eval do
|
131
|
+
writer = "#{name}="
|
132
|
+
remove_method writer rescue nil
|
133
|
+
define_method writer do |value|
|
134
|
+
AttrLazy.define_evaluated_reader(self, name, value)
|
135
|
+
value
|
136
|
+
end
|
99
137
|
end
|
100
|
-
|
138
|
+
end
|
101
139
|
end
|
140
|
+
end
|
102
141
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
"MANIFEST"
|
109
|
-
end
|
142
|
+
module Ruby
|
143
|
+
module_function
|
144
|
+
|
145
|
+
def executable
|
146
|
+
require 'rbconfig'
|
110
147
|
|
111
|
-
|
112
|
-
|
113
|
-
|
148
|
+
name = File.join(
|
149
|
+
Config::CONFIG["bindir"],
|
150
|
+
Config::CONFIG["RUBY_INSTALL_NAME"]
|
151
|
+
)
|
152
|
+
|
153
|
+
if Config::CONFIG["host"] =~ %r!(mswin|cygwin|mingw)! and
|
154
|
+
File.basename(name) !~ %r!\.(exe|com|bat|cmd)\Z!i
|
155
|
+
name + Config::CONFIG["EXEEXT"]
|
114
156
|
else
|
115
|
-
|
157
|
+
name
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def run(*args)
|
162
|
+
cmd = [executable, *args]
|
163
|
+
unless system(*cmd)
|
164
|
+
cmd_str = cmd.map { |t| "'#{t}'" }.join(", ")
|
165
|
+
raise "system(#{cmd_str}) failed with status #{$?.exitstatus}"
|
116
166
|
end
|
117
167
|
end
|
118
168
|
|
119
|
-
|
120
|
-
|
169
|
+
def run_code_and_capture(code)
|
170
|
+
IO.popen(%{"#{executable}"}, "r+") { |pipe|
|
171
|
+
pipe.print(code)
|
172
|
+
pipe.flush
|
173
|
+
pipe.close_write
|
174
|
+
pipe.read
|
175
|
+
}
|
121
176
|
end
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
else
|
127
|
-
[]
|
177
|
+
|
178
|
+
def run_file_and_capture(file)
|
179
|
+
unless File.file? file
|
180
|
+
raise "file does not exist: `#{file}'"
|
128
181
|
end
|
182
|
+
IO.popen(%{"#{executable}" "#{file}"}, "r") { |pipe|
|
183
|
+
pipe.read
|
184
|
+
}
|
129
185
|
end
|
186
|
+
|
187
|
+
def with_warnings(value = true)
|
188
|
+
previous = $VERBOSE
|
189
|
+
$VERBOSE = value
|
190
|
+
begin
|
191
|
+
yield
|
192
|
+
ensure
|
193
|
+
$VERBOSE = previous
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def no_warnings(&block)
|
198
|
+
with_warnings(nil, &block)
|
199
|
+
end
|
200
|
+
end
|
130
201
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
"--title", "#{name}: #{summary}",
|
138
|
-
] + (files - rdoc_files).inject(Array.new) { |acc, file|
|
139
|
-
acc + ["--exclude", file]
|
202
|
+
module Util
|
203
|
+
module_function
|
204
|
+
|
205
|
+
def run_ruby_on_each(*files)
|
206
|
+
files.each { |file|
|
207
|
+
Ruby.run("-w", file)
|
140
208
|
}
|
141
209
|
end
|
142
210
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
Gem::Specification.new { |g|
|
162
|
-
g.has_rdoc = true
|
163
|
-
%w[
|
164
|
-
name
|
165
|
-
authors
|
166
|
-
email
|
167
|
-
summary
|
168
|
-
version
|
169
|
-
description
|
170
|
-
files
|
171
|
-
extra_rdoc_files
|
172
|
-
rdoc_options
|
173
|
-
].each { |param|
|
174
|
-
value = send(param) and (
|
175
|
-
g.send("#{param}=", value)
|
176
|
-
)
|
211
|
+
def to_camel_case(str)
|
212
|
+
str.split('_').map { |t| t.capitalize }.join
|
213
|
+
end
|
214
|
+
|
215
|
+
def write_file(file)
|
216
|
+
contents = yield
|
217
|
+
File.open(file, "wb") { |out|
|
218
|
+
out.print(contents)
|
219
|
+
}
|
220
|
+
contents
|
221
|
+
end
|
222
|
+
|
223
|
+
def replace_file(file)
|
224
|
+
old_contents = File.read(file)
|
225
|
+
new_contents = yield(old_contents)
|
226
|
+
if old_contents != new_contents
|
227
|
+
File.open(file, "wb") { |output|
|
228
|
+
output.print(new_contents)
|
177
229
|
}
|
230
|
+
end
|
231
|
+
new_contents
|
232
|
+
end
|
233
|
+
end
|
178
234
|
|
179
|
-
|
180
|
-
|
181
|
-
end
|
235
|
+
module InstanceEvalWithArgs
|
236
|
+
module_function
|
182
237
|
|
183
|
-
|
184
|
-
|
238
|
+
def with_temp_method(instance, method_name, method_block)
|
239
|
+
(class << instance ; self ; end).class_eval do
|
240
|
+
define_method(method_name, &method_block)
|
241
|
+
begin
|
242
|
+
yield method_name
|
243
|
+
ensure
|
244
|
+
remove_method(method_name)
|
185
245
|
end
|
246
|
+
end
|
247
|
+
end
|
186
248
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
extra_dev_deps.each { |dep|
|
192
|
-
g.add_development_dependency(*dep)
|
193
|
-
}
|
249
|
+
def call_temp_method(instance, method_name, *args, &method_block)
|
250
|
+
with_temp_method(instance, method_name, method_block) {
|
251
|
+
instance.send(method_name, *args)
|
194
252
|
}
|
195
253
|
end
|
196
254
|
|
197
|
-
|
198
|
-
|
255
|
+
def instance_eval_with_args(instance, *args, &block)
|
256
|
+
call_temp_method(instance, :__temp_method, *args, &block)
|
199
257
|
end
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
258
|
+
end
|
259
|
+
|
260
|
+
include AttrLazy
|
261
|
+
include Util
|
262
|
+
|
263
|
+
def initialize(project_name)
|
264
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
265
|
+
$LOAD_PATH.unshift File.dirname(__FILE__)
|
266
|
+
|
267
|
+
require 'rake/gempackagetask'
|
268
|
+
require 'rake/clean'
|
269
|
+
|
270
|
+
@project_name = project_name
|
271
|
+
|
272
|
+
yield self
|
273
|
+
|
274
|
+
self.class.instance_methods(false).select { |t|
|
275
|
+
t.to_s =~ %r!\Adefine_!
|
276
|
+
}.each { |method_name|
|
277
|
+
send(method_name)
|
278
|
+
}
|
279
|
+
end
|
280
|
+
|
281
|
+
class << self
|
282
|
+
alias_method :attribute, :attr_lazy_accessor
|
283
|
+
end
|
284
|
+
|
285
|
+
attribute :name do
|
286
|
+
@project_name
|
287
|
+
end
|
288
|
+
|
289
|
+
attribute :version_constant_name do
|
290
|
+
"VERSION"
|
291
|
+
end
|
292
|
+
|
293
|
+
attribute :version do
|
294
|
+
require name
|
295
|
+
mod_name = to_camel_case(name)
|
296
|
+
begin
|
297
|
+
mod = Kernel.const_get(mod_name)
|
298
|
+
if mod.constants.include?(version_constant_name)
|
299
|
+
mod.const_get(version_constant_name)
|
300
|
+
else
|
301
|
+
raise
|
210
302
|
end
|
303
|
+
rescue
|
304
|
+
"0.0.0"
|
211
305
|
end
|
306
|
+
end
|
307
|
+
|
308
|
+
attribute :rubyforge_name do
|
309
|
+
name.gsub('_', '')
|
310
|
+
end
|
311
|
+
|
312
|
+
attribute :rubyforge_user do
|
313
|
+
email.first[%r!^.*(?=@)!]
|
314
|
+
end
|
315
|
+
|
316
|
+
attribute :readme_file do
|
317
|
+
"README.rdoc"
|
318
|
+
end
|
319
|
+
|
320
|
+
attribute :history_file do
|
321
|
+
"CHANGES.rdoc"
|
322
|
+
end
|
323
|
+
|
324
|
+
attribute :doc_dir do
|
325
|
+
"documentation"
|
326
|
+
end
|
327
|
+
|
328
|
+
attribute :spec_files do
|
329
|
+
Dir["./spec/*_{spec,example}.rb"]
|
330
|
+
end
|
331
|
+
|
332
|
+
attribute :test_files do
|
333
|
+
(Dir["./test/test_*.rb"] + Dir["./test/*_test.rb"]).uniq
|
334
|
+
end
|
335
|
+
|
336
|
+
attribute :rcov_dir do
|
337
|
+
"coverage"
|
338
|
+
end
|
339
|
+
|
340
|
+
attribute :spec_output_dir do
|
341
|
+
"rspec_output"
|
342
|
+
end
|
343
|
+
|
344
|
+
attribute :spec_output_file do
|
345
|
+
"spec.html"
|
346
|
+
end
|
212
347
|
|
213
|
-
|
214
|
-
|
348
|
+
attr_lazy :spec_output do
|
349
|
+
"#{spec_output_dir}/#{spec_output_file}"
|
350
|
+
end
|
351
|
+
|
352
|
+
[:gem, :tgz].each { |ext|
|
353
|
+
attribute ext do
|
354
|
+
"pkg/#{name}-#{version}.#{ext}"
|
215
355
|
end
|
356
|
+
}
|
357
|
+
|
358
|
+
attribute :rcov_options do
|
359
|
+
# workaround for the default rspec task
|
360
|
+
Dir["*"].select { |f| File.directory? f }.inject(Array.new) { |acc, dir|
|
361
|
+
if dir == "lib"
|
362
|
+
acc
|
363
|
+
else
|
364
|
+
acc + ["--exclude", dir + "/"]
|
365
|
+
end
|
366
|
+
} + ["--text-report"]
|
367
|
+
end
|
368
|
+
|
369
|
+
attribute :readme_file do
|
370
|
+
"README.rdoc"
|
371
|
+
end
|
372
|
+
|
373
|
+
attribute :manifest_file do
|
374
|
+
"MANIFEST"
|
375
|
+
end
|
376
|
+
|
377
|
+
attribute :generated_files do
|
378
|
+
[]
|
379
|
+
end
|
216
380
|
|
217
|
-
|
218
|
-
|
381
|
+
attribute :files do
|
382
|
+
if File.exist?(manifest_file)
|
383
|
+
File.read(manifest_file).split("\n")
|
384
|
+
else
|
385
|
+
`git ls-files`.split("\n") + [manifest_file] + generated_files
|
219
386
|
end
|
387
|
+
end
|
220
388
|
|
221
|
-
|
222
|
-
|
389
|
+
attribute :rdoc_files do
|
390
|
+
Dir["lib/**/*.rb"]
|
391
|
+
end
|
392
|
+
|
393
|
+
attribute :extra_rdoc_files do
|
394
|
+
if File.exist?(readme_file)
|
395
|
+
[readme_file]
|
396
|
+
else
|
397
|
+
[]
|
223
398
|
end
|
399
|
+
end
|
224
400
|
|
225
|
-
|
226
|
-
|
401
|
+
attribute :rdoc_options do
|
402
|
+
if File.exist?(readme_file)
|
403
|
+
["--main", readme_file]
|
404
|
+
else
|
405
|
+
[]
|
406
|
+
end + [
|
407
|
+
"--title", "#{name}: #{summary}",
|
408
|
+
] + (files - rdoc_files).inject(Array.new) { |acc, file|
|
409
|
+
acc + ["--exclude", file]
|
410
|
+
}
|
411
|
+
end
|
412
|
+
|
413
|
+
attribute :browser do
|
414
|
+
require 'rbconfig'
|
415
|
+
if Config::CONFIG["host"] =~ %r!darwin!
|
416
|
+
app = %w[Firefox Safari].map { |t|
|
417
|
+
"/Applications/#{t}.app"
|
418
|
+
}.select { |t|
|
419
|
+
File.exist? t
|
420
|
+
}.first
|
421
|
+
if app
|
422
|
+
["open", app]
|
423
|
+
else
|
424
|
+
raise "need to set `browser'"
|
425
|
+
end
|
426
|
+
else
|
427
|
+
"firefox"
|
227
428
|
end
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
429
|
+
end
|
430
|
+
|
431
|
+
attribute :gemspec do
|
432
|
+
Gem::Specification.new { |g|
|
433
|
+
g.has_rdoc = true
|
434
|
+
%w[
|
435
|
+
name
|
436
|
+
authors
|
437
|
+
email
|
438
|
+
summary
|
439
|
+
version
|
440
|
+
description
|
441
|
+
files
|
442
|
+
extra_rdoc_files
|
443
|
+
rdoc_options
|
444
|
+
].each { |param|
|
445
|
+
value = send(param) and (
|
446
|
+
g.send("#{param}=", value)
|
447
|
+
)
|
448
|
+
}
|
449
|
+
|
450
|
+
if rubyforge_name
|
451
|
+
g.rubyforge_project = rubyforge_name
|
452
|
+
end
|
453
|
+
|
454
|
+
if url
|
455
|
+
g.homepage = url
|
240
456
|
end
|
457
|
+
|
458
|
+
extra_deps.each { |dep|
|
459
|
+
g.add_dependency(*dep)
|
460
|
+
}
|
461
|
+
|
462
|
+
extra_dev_deps.each { |dep|
|
463
|
+
g.add_development_dependency(*dep)
|
464
|
+
}
|
241
465
|
}
|
466
|
+
end
|
467
|
+
|
468
|
+
attribute :readme_contents do
|
469
|
+
File.read(readme_file) rescue "FIXME: readme_file"
|
470
|
+
end
|
471
|
+
|
472
|
+
attribute :sections do
|
473
|
+
begin
|
474
|
+
pairs = Hash[*readme_contents.split(%r!^== (\w+).*?$!)[1..-1]].map {
|
475
|
+
|section, contents|
|
476
|
+
[section.downcase, contents.strip]
|
477
|
+
}
|
478
|
+
Hash[*pairs.flatten]
|
479
|
+
rescue
|
480
|
+
nil
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
attribute :description_section do
|
485
|
+
"description"
|
486
|
+
end
|
487
|
+
|
488
|
+
attribute :summary_section do
|
489
|
+
"summary"
|
490
|
+
end
|
242
491
|
|
243
|
-
|
492
|
+
attribute :description_sentences do
|
493
|
+
1
|
494
|
+
end
|
495
|
+
|
496
|
+
attribute :summary_sentences do
|
497
|
+
1
|
498
|
+
end
|
499
|
+
|
500
|
+
[:summary, :description].each { |section|
|
501
|
+
attribute section do
|
244
502
|
begin
|
245
|
-
|
503
|
+
sections[send("#{section}_section")].
|
504
|
+
gsub("\n", " ").
|
505
|
+
split(%r!\.\s*!m).
|
506
|
+
first(send("#{section}_sentences")).
|
507
|
+
join(". ") << "."
|
246
508
|
rescue
|
247
|
-
"
|
509
|
+
"FIXME: #{section}"
|
248
510
|
end
|
249
511
|
end
|
512
|
+
}
|
250
513
|
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
[]
|
514
|
+
attribute :url do
|
515
|
+
begin
|
516
|
+
readme_contents.match(%r!^\*.*?(http://\S+)!)[1]
|
517
|
+
rescue
|
518
|
+
"http://#{rubyforge_name}.rubyforge.org"
|
257
519
|
end
|
520
|
+
end
|
258
521
|
|
259
|
-
|
522
|
+
attribute :extra_deps do
|
523
|
+
[]
|
524
|
+
end
|
260
525
|
|
261
|
-
|
262
|
-
|
263
|
-
}.each { |method_name|
|
264
|
-
send(method_name)
|
265
|
-
}
|
526
|
+
attribute :extra_dev_deps do
|
527
|
+
[]
|
266
528
|
end
|
267
529
|
|
268
|
-
|
269
|
-
|
270
|
-
self.email << email
|
530
|
+
attribute :authors do
|
531
|
+
Array.new
|
271
532
|
end
|
272
533
|
|
273
|
-
|
274
|
-
|
534
|
+
attribute :email do
|
535
|
+
Array.new
|
275
536
|
end
|
276
537
|
|
277
|
-
def email
|
278
|
-
|
538
|
+
def developer(name, email)
|
539
|
+
authors << name
|
540
|
+
self.email << email
|
279
541
|
end
|
280
542
|
|
281
543
|
def dependency(name, version)
|
@@ -335,7 +597,7 @@ class Jumpstart
|
|
335
597
|
task :prerelease => [:spec, :spec_deps]
|
336
598
|
task :default => :spec
|
337
599
|
|
338
|
-
CLEAN.include
|
600
|
+
CLEAN.include spec_output_dir
|
339
601
|
end
|
340
602
|
end
|
341
603
|
|
@@ -377,6 +639,7 @@ class Jumpstart
|
|
377
639
|
def define_doc
|
378
640
|
desc "run rdoc"
|
379
641
|
task :doc => :clean_doc do
|
642
|
+
require 'rdoc/rdoc'
|
380
643
|
args = (
|
381
644
|
gemspec.rdoc_options +
|
382
645
|
gemspec.require_paths.clone +
|
@@ -403,6 +666,7 @@ class Jumpstart
|
|
403
666
|
def define_publish
|
404
667
|
desc "upload docs"
|
405
668
|
task :publish => [:clean_doc, :doc] do
|
669
|
+
require 'rake/contrib/sshpublisher'
|
406
670
|
Rake::SshDirPublisher.new(
|
407
671
|
"#{rubyforge_user}@rubyforge.org",
|
408
672
|
"/var/www/gforge-projects/#{rubyforge_name}",
|
@@ -445,9 +709,10 @@ class Jumpstart
|
|
445
709
|
end
|
446
710
|
|
447
711
|
def debug_info(enable)
|
712
|
+
require 'find'
|
448
713
|
Find.find("lib", "test") { |path|
|
449
714
|
if path =~ %r!\.rb\Z!
|
450
|
-
|
715
|
+
replace_file(path) { |contents|
|
451
716
|
result = comment_regions(!enable, contents, "debug")
|
452
717
|
comment_lines(!enable, result, "trace")
|
453
718
|
}
|
@@ -485,13 +750,13 @@ class Jumpstart
|
|
485
750
|
task :comments do
|
486
751
|
file = "comments.txt"
|
487
752
|
write_file(file) {
|
488
|
-
Array.new
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
}
|
753
|
+
result = Array.new
|
754
|
+
(["Rakefile"] + Dir["**/*.{rb,rake}"]).each { |f|
|
755
|
+
File.read(f).scan(%r!\#[^\{].*$!) { |match|
|
756
|
+
result << match
|
493
757
|
}
|
494
|
-
}
|
758
|
+
}
|
759
|
+
result.join("\n")
|
495
760
|
}
|
496
761
|
CLEAN.include file
|
497
762
|
end
|
@@ -507,6 +772,7 @@ class Jumpstart
|
|
507
772
|
|
508
773
|
def define_ping
|
509
774
|
task :ping do
|
775
|
+
require 'rbconfig'
|
510
776
|
%w[github.com rubyforge.org].each { |server|
|
511
777
|
cmd = "ping " + (
|
512
778
|
if Config::CONFIG["host"] =~ %r!darwin!
|
@@ -548,28 +814,29 @@ class Jumpstart
|
|
548
814
|
}
|
549
815
|
end
|
550
816
|
|
551
|
-
def rubyforge(
|
552
|
-
|
553
|
-
"rubyforge",
|
554
|
-
command,
|
817
|
+
def rubyforge(mode, file, *options)
|
818
|
+
command = ["rubyforge", mode] + options + [
|
555
819
|
rubyforge_name,
|
556
820
|
rubyforge_name,
|
557
821
|
version.to_s,
|
558
|
-
file
|
559
|
-
|
822
|
+
file,
|
823
|
+
]
|
824
|
+
sh(*command)
|
560
825
|
end
|
561
826
|
|
562
827
|
def define_release
|
563
|
-
task :prerelease => [:clean, :check_directory, :ping]
|
828
|
+
task :prerelease => [:clean, :check_directory, :ping, history_file]
|
564
829
|
|
565
830
|
task :finish_release do
|
566
831
|
gem_md5, tgz_md5 = [gem, tgz].map { |file|
|
567
|
-
"#{file}.md5"
|
568
|
-
|
569
|
-
|
832
|
+
md5 = "#{file}.md5"
|
833
|
+
sh("md5sum #{file} > #{md5}")
|
834
|
+
md5
|
570
835
|
}
|
571
836
|
|
572
|
-
rubyforge(
|
837
|
+
rubyforge(
|
838
|
+
"add_release", gem, "--release_changes", history_file, "--preformatted"
|
839
|
+
)
|
573
840
|
[gem_md5, tgz, tgz_md5].each { |file|
|
574
841
|
rubyforge("add_file", file)
|
575
842
|
}
|
@@ -591,44 +858,113 @@ class Jumpstart
|
|
591
858
|
sh(*([browser].flatten + files))
|
592
859
|
end
|
593
860
|
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
out.print(contents)
|
598
|
-
}
|
599
|
-
}
|
600
|
-
end
|
861
|
+
class << self
|
862
|
+
include Util
|
863
|
+
include InstanceEvalWithArgs
|
601
864
|
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
}
|
606
|
-
end
|
865
|
+
# From minitest, part of the Ruby source; by Ryan Davis.
|
866
|
+
def capture_io
|
867
|
+
require 'stringio'
|
607
868
|
|
608
|
-
|
609
|
-
|
610
|
-
|
869
|
+
orig_stdout, orig_stderr = $stdout, $stderr
|
870
|
+
captured_stdout, captured_stderr = StringIO.new, StringIO.new
|
871
|
+
$stdout, $stderr = captured_stdout, captured_stderr
|
611
872
|
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
873
|
+
yield
|
874
|
+
|
875
|
+
return captured_stdout.string, captured_stderr.string
|
876
|
+
ensure
|
877
|
+
$stdout = orig_stdout
|
878
|
+
$stderr = orig_stderr
|
879
|
+
end
|
880
|
+
|
881
|
+
def run_doc_code(code, expected, index, instance, &block)
|
882
|
+
lib = File.expand_path(File.dirname(__FILE__) + "/../lib")
|
883
|
+
header = %{
|
884
|
+
$LOAD_PATH.unshift "#{lib}"
|
885
|
+
require 'rubygems'
|
886
|
+
begin
|
887
|
+
}
|
888
|
+
footer = %{
|
889
|
+
rescue Exception => __jumpstart_exception
|
890
|
+
puts "raises \#{__jumpstart_exception.class}"
|
620
891
|
end
|
621
892
|
}
|
893
|
+
final_code = header + code + footer
|
894
|
+
|
895
|
+
# Sometimes code is required to be inside a file.
|
896
|
+
actual = nil
|
897
|
+
require 'tempfile'
|
898
|
+
Tempfile.open("run-rdoc-code") { |temp_file|
|
899
|
+
temp_file.print(final_code)
|
900
|
+
temp_file.close
|
901
|
+
actual = Ruby.run_file_and_capture(temp_file.path).chomp
|
902
|
+
}
|
903
|
+
|
904
|
+
instance_eval_with_args(instance, expected, actual, index, &block)
|
905
|
+
end
|
906
|
+
|
907
|
+
def run_doc_section(file, section, instance, &block)
|
908
|
+
contents = File.read(file)
|
909
|
+
if section_contents = contents[%r!^=+[ \t]#{section}.*?\n(.*?)^=!m, 1]
|
910
|
+
index = 0
|
911
|
+
section_contents.scan(%r!^( \S.*?)(?=(^\S|\Z))!m) { |indented, unused|
|
912
|
+
code_sections = indented.split(%r!^ \#\#\#\# output:\s*$!)
|
913
|
+
code, expected = (
|
914
|
+
case code_sections.size
|
915
|
+
when 1
|
916
|
+
[indented, indented.scan(%r!\# => (.*?)\n!).flatten.join("\n")]
|
917
|
+
when 2
|
918
|
+
code_sections
|
919
|
+
else
|
920
|
+
raise "parse error"
|
921
|
+
end
|
922
|
+
)
|
923
|
+
run_doc_code(code, expected, index, instance, &block)
|
924
|
+
index += 1
|
925
|
+
}
|
926
|
+
else
|
927
|
+
raise "couldn't find section `#{section}' of `#{file}'"
|
928
|
+
end
|
929
|
+
end
|
930
|
+
|
931
|
+
def doc_to_spec(file, *sections, &block)
|
932
|
+
jump = self
|
933
|
+
describe file do
|
934
|
+
sections.each { |section|
|
935
|
+
describe "section `#{section}'" do
|
936
|
+
it "should run as claimed" do
|
937
|
+
if block
|
938
|
+
jump.run_doc_section(file, section, self, &block)
|
939
|
+
else
|
940
|
+
jump.run_doc_section(file, section, self) {
|
941
|
+
|expected, actual, index|
|
942
|
+
actual.should == expected
|
943
|
+
}
|
944
|
+
end
|
945
|
+
end
|
946
|
+
end
|
947
|
+
}
|
948
|
+
end
|
622
949
|
end
|
623
|
-
end
|
624
|
-
end
|
625
950
|
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
951
|
+
def doc_to_test(file, *sections, &block)
|
952
|
+
jump = self
|
953
|
+
klass = Class.new Test::Unit::TestCase do
|
954
|
+
sections.each { |section|
|
955
|
+
define_method "test_#{file}_#{section}" do
|
956
|
+
if block
|
957
|
+
jump.run_doc_section(file, section, self, &block)
|
958
|
+
else
|
959
|
+
jump.run_doc_section(file, section, self) {
|
960
|
+
|expected, actual, index|
|
961
|
+
assert_equal expected, actual
|
962
|
+
}
|
963
|
+
end
|
964
|
+
end
|
965
|
+
}
|
966
|
+
end
|
967
|
+
Object.const_set("Test#{file}".gsub(".", ""), klass)
|
631
968
|
end
|
632
969
|
end
|
633
970
|
end
|
634
|
-
|