comp_tree 0.7.1 → 0.7.2

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.
@@ -1,6 +1,11 @@
1
1
 
2
2
  = CompTree ChangeLog
3
3
 
4
+ == Version 0.7.2
5
+
6
+ * check for number of threads < 1
7
+ * new benchmarks indicate previous algorithm was faster after all
8
+
4
9
  == Version 0.7.1
5
10
 
6
11
  * rename README to README.rdoc for github display
data/README.rdoc CHANGED
@@ -1,5 +1,11 @@
1
1
 
2
- = CompTree -- Parallel Computation Tree
2
+ = CompTree
3
+
4
+ * http://comptree.rubyforge.org
5
+
6
+ == Summary
7
+
8
+ Automatic parallelism and lazy evaluation.
3
9
 
4
10
  == Synopsis
5
11
 
@@ -36,15 +42,24 @@
36
42
  # => 63
37
43
  end
38
44
 
39
- == Notes
45
+ == Install
46
+
47
+ % gem install comp_tree
48
+
49
+ Or for the (non-gem) .tgz package,
50
+
51
+ % ruby install.rb [--uninstall]
52
+
53
+ == Description
54
+
55
+ A computation tree for pure functional programming in Ruby.
40
56
 
41
57
  The user should have a basic understanding of <em>functional
42
58
  programming</em> (see for example
43
59
  http://en.wikipedia.org/wiki/Functional_programming) and the meaning
44
60
  of <em>side effects</em>.
45
61
 
46
- CompTree requires the user to adopt a functional style. Every
47
- function you define must explicitly depend on the data it uses.
62
+ Every function you define must explicitly depend on the data it uses.
48
63
 
49
64
  #
50
65
  # BAD example: depending on state -- offset not listed as a parameter
@@ -76,14 +91,6 @@ Note however it is OK affect a state as long as <em>no other function
76
91
  depends on that state</em>. This is the principle under which
77
92
  +comp_tree+ parallelizes Rake tasks (http://drake.rubyforge.org).
78
93
 
79
- == Install
80
-
81
- % gem install comp_tree
82
-
83
- Or for the (non-gem) .tgz package,
84
-
85
- % ruby install.rb [--uninstall]
86
-
87
94
  == Links
88
95
 
89
96
  * Download: http://rubyforge.org/frs/?group_id=6917
data/Rakefile CHANGED
@@ -1,3 +1,8 @@
1
+ $LOAD_PATH.unshift "devel"
1
2
 
2
- # rakelib generates tasks
3
+ require 'jumpstart'
3
4
 
5
+ Jumpstart.new('comp_tree') do |s|
6
+ s.developer('James M. Lawrence', 'quixoticsycophant@gmail.com')
7
+ s.rubyforge_user = "quix"
8
+ end
@@ -0,0 +1,580 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + "/../lib"
2
+
3
+ require 'rubygems'
4
+ require 'ostruct'
5
+ require 'rbconfig'
6
+
7
+ require 'rake/gempackagetask'
8
+ require 'rake/contrib/sshpublisher'
9
+ require 'rake/clean'
10
+
11
+ require 'rdoc/rdoc'
12
+
13
+ require "jumpstart/ruby"
14
+ require "jumpstart/lazy_attribute"
15
+ require "jumpstart/simple_installer"
16
+
17
+ class Jumpstart
18
+ include LazyAttribute
19
+
20
+ def not_provided(param)
21
+ raise "#{self.class}##{param} not provided"
22
+ end
23
+
24
+ def must_define(*params)
25
+ params.each { |param|
26
+ attribute param do
27
+ not_provided(param)
28
+ end
29
+ }
30
+ end
31
+
32
+ def initialize(project_name)
33
+ must_define :authors, :email
34
+
35
+ attribute :name do
36
+ project_name
37
+ end
38
+
39
+ attribute :version do
40
+ str = "VERSION"
41
+ begin
42
+ require name
43
+ if mod = Object.const_get(to_camel_case(name))
44
+ if mod.constants.include? str
45
+ mod.const_get str
46
+ else
47
+ raise
48
+ end
49
+ else
50
+ raise
51
+ end
52
+ rescue Exception
53
+ "0.0.0"
54
+ end
55
+ end
56
+
57
+ attribute :rubyforge_name do
58
+ name.gsub('_', '')
59
+ end
60
+
61
+ attribute :rubyforge_user do
62
+ email.first[%r!^.*(?=@)!]
63
+ end
64
+
65
+ attribute :readme_file do
66
+ "README.rdoc"
67
+ end
68
+
69
+ attribute :history_file do
70
+ "CHANGES.rdoc"
71
+ end
72
+
73
+ attribute :doc_dir do
74
+ "documentation"
75
+ end
76
+
77
+ attribute :spec_files do
78
+ Dir["spec/*_{spec,example}.rb"]
79
+ end
80
+
81
+ attribute :test_files do
82
+ Dir["test/test_*.rb"]
83
+ end
84
+
85
+ attribute :rcov_dir do
86
+ "coverage"
87
+ end
88
+
89
+ attribute :spec_output do
90
+ "spec.html"
91
+ end
92
+
93
+ %w[gem tgz].map { |ext|
94
+ attribute ext.to_sym do
95
+ "pkg/#{name}-#{version}.#{ext}"
96
+ end
97
+ }
98
+
99
+ attribute :rcov_options do
100
+ # workaround for the default rspec task
101
+ Dir["*"].select { |f| File.directory? f }.inject(Array.new) { |acc, dir|
102
+ if dir == "lib"
103
+ acc
104
+ else
105
+ acc + ["--exclude", dir + "/"]
106
+ end
107
+ } + ["--text-report"]
108
+ end
109
+
110
+ attribute :readme_file do
111
+ "README.rdoc"
112
+ end
113
+
114
+ attribute :files do
115
+ `git ls-files`.split("\n")
116
+ end
117
+
118
+ attribute :rdoc_files do
119
+ Dir["lib/**/*.rb"]
120
+ end
121
+
122
+ attribute :extra_rdoc_files do
123
+ [readme_file]
124
+ end
125
+
126
+ attribute :rdoc_options do
127
+ [
128
+ "--main",
129
+ readme_file,
130
+ "--title",
131
+ "#{name}: #{summary}",
132
+ ] + (files - rdoc_files).inject(Array.new) { |acc, file|
133
+ acc + ["--exclude", file]
134
+ }
135
+ end
136
+
137
+ attribute :browser do
138
+ if Config::CONFIG["host"] =~ %r!darwin!
139
+ app = %w[Firefox Safari].map { |t|
140
+ "/Applications/#{t}.app"
141
+ }.select { |t|
142
+ File.exist? t
143
+ }.first
144
+ if app
145
+ ["open", app]
146
+ else
147
+ not_provided(:browser)
148
+ end
149
+ else
150
+ "firefox"
151
+ end
152
+ end
153
+
154
+ attribute :gemspec do
155
+ Gem::Specification.new { |g|
156
+ g.has_rdoc = true
157
+ %w[
158
+ name
159
+ authors
160
+ email
161
+ summary
162
+ version
163
+ description
164
+ files
165
+ extra_rdoc_files
166
+ rdoc_options
167
+ ].each { |param|
168
+ value = send(param) and (
169
+ g.send("#{param}=", value)
170
+ )
171
+ }
172
+
173
+ if rubyforge_name
174
+ g.rubyforge_project = rubyforge_name
175
+ end
176
+
177
+ if url
178
+ g.homepage = url
179
+ end
180
+ }
181
+ end
182
+
183
+ attribute :readme_contents do
184
+ File.read(readme_file)
185
+ end
186
+
187
+ attribute :sections do
188
+ begin
189
+ pairs = Hash[*readme_contents.split(%r!^== (\w+).*?$!)[1..-1]].map {
190
+ |section, contents|
191
+ [section.downcase, contents.strip]
192
+ }
193
+ Hash[*pairs.flatten]
194
+ rescue
195
+ nil
196
+ end
197
+ end
198
+
199
+ attribute :description_section do
200
+ "description"
201
+ end
202
+
203
+ attribute :summary_section do
204
+ "summary"
205
+ end
206
+
207
+ attribute :description_sentences do
208
+ 1
209
+ end
210
+
211
+ attribute :summary_sentences do
212
+ 1
213
+ end
214
+
215
+ [:summary, :description].each { |section|
216
+ attribute section do
217
+ begin
218
+ sections[send("#{section}_section")].
219
+ gsub("\n", " ").
220
+ split(%r!\.\s*!m).
221
+ first(send("#{section}_sentences")).
222
+ join(". ") << "."
223
+ rescue
224
+ if section == :description
225
+ summary
226
+ end
227
+ end
228
+ end
229
+ }
230
+
231
+ attribute :url do
232
+ begin
233
+ readme_contents.match(%r!^\* (\S+)!)[1]
234
+ rescue
235
+ "http://#{rubyforge_name}.rubyforge.org"
236
+ end
237
+ end
238
+
239
+ yield self
240
+
241
+ self.class.instance_methods(false).select { |t|
242
+ t.to_s =~ %r!\Adefine_!
243
+ }.each { |method_name|
244
+ send(method_name)
245
+ }
246
+ end
247
+
248
+ def developer(name, email)
249
+ self.authors rescue self.authors = []
250
+ self.email rescue self.email = []
251
+ self.authors << name
252
+ self.email << email
253
+ end
254
+
255
+ def author=(name)
256
+ self.authors = [name]
257
+ end
258
+
259
+ def define_clean
260
+ task :clean do
261
+ Rake::Task[:clobber].invoke
262
+ end
263
+ end
264
+
265
+ def define_package
266
+ task :package => :clean
267
+ Rake::GemPackageTask.new(gemspec) { |t|
268
+ t.need_tar = true
269
+ }
270
+ end
271
+
272
+ def define_spec
273
+ unless spec_files.empty?
274
+ require 'spec/rake/spectask'
275
+
276
+ desc "run specs"
277
+ Spec::Rake::SpecTask.new('spec') do |t|
278
+ t.spec_files = spec_files
279
+ end
280
+
281
+ desc "run specs with text output"
282
+ Spec::Rake::SpecTask.new('text_spec') do |t|
283
+ t.spec_files = spec_files
284
+ t.spec_opts = ['-fs']
285
+ end
286
+
287
+ desc "run specs with html output"
288
+ Spec::Rake::SpecTask.new('full_spec') do |t|
289
+ t.spec_files = spec_files
290
+ t.rcov = true
291
+ t.rcov_opts = rcov_options
292
+ t.spec_opts = ["-fh:#{spec_output}"]
293
+ end
294
+
295
+ desc "run full_spec then open browser"
296
+ task :show_spec => :full_spec do
297
+ open_browser(spec_output, rcov_dir + "/index.html")
298
+ end
299
+
300
+ desc "run specs individually"
301
+ task :spec_deps do
302
+ run_ruby_on_each(*spec_files)
303
+ end
304
+
305
+ task :prerelease => :spec_deps
306
+ task :default => :spec
307
+
308
+ CLEAN.include spec_output
309
+ end
310
+ end
311
+
312
+ def define_test
313
+ unless test_files.empty?
314
+ desc "run tests"
315
+ task :test do
316
+ test_files.each { |file|
317
+ require file
318
+ }
319
+ end
320
+
321
+ desc "run tests with rcov"
322
+ task :full_test do
323
+ verbose(false) {
324
+ sh("rcov", "-o", rcov_dir, "--text-report",
325
+ *(test_files + rcov_options)
326
+ )
327
+ }
328
+ end
329
+
330
+ desc "run full_test then open browser"
331
+ task :show_test => :full_test do
332
+ open_browser(rcov_dir + "/index.html")
333
+ end
334
+
335
+ desc "run tests individually"
336
+ task :test_deps do
337
+ run_ruby_on_each(*test_files)
338
+ end
339
+
340
+ task :prerelease => :test_deps
341
+ task :default => :test
342
+
343
+ CLEAN.include rcov_dir
344
+ end
345
+ end
346
+
347
+ def define_doc
348
+ desc "run rdoc"
349
+ task :doc => :clean_doc do
350
+ args = (
351
+ gemspec.rdoc_options +
352
+ gemspec.require_paths.clone +
353
+ gemspec.extra_rdoc_files +
354
+ ["-o", doc_dir]
355
+ ).flatten.map { |t| t.to_s }
356
+ RDoc::RDoc.new.document args
357
+ end
358
+
359
+ task :clean_doc do
360
+ # normally rm_rf, but mimic rake/clean output
361
+ rm_r(doc_dir) rescue nil
362
+ end
363
+
364
+ desc "run rdoc then open browser"
365
+ task :show_doc => :doc do
366
+ open_browser(doc_dir + "/index.html")
367
+ end
368
+
369
+ task :rdoc => :doc
370
+ task :clean => :clean_doc
371
+ end
372
+
373
+ def define_publish
374
+ desc "upload docs"
375
+ task :publish => [:clean_doc, :doc] do
376
+ Rake::SshDirPublisher.new(
377
+ "#{rubyforge_user}@rubyforge.org",
378
+ "/var/www/gforge-projects/#{rubyforge_name}",
379
+ doc_dir
380
+ ).upload
381
+ end
382
+ end
383
+
384
+ def define_install
385
+ desc "direct install (no gem)"
386
+ task :install do
387
+ SimpleInstaller.new.run([])
388
+ end
389
+
390
+ desc "direct uninstall (no gem)"
391
+ task :uninstall do
392
+ SimpleInstaller.new.run(["--uninstall"])
393
+ end
394
+ end
395
+
396
+ def define_debug
397
+ runner = Class.new do
398
+ def comment_src_dst(on)
399
+ on ? ["", "#"] : ["#", ""]
400
+ end
401
+
402
+ def comment_regions(on, contents, start)
403
+ src, dst = comment_src_dst(on)
404
+ contents.gsub(%r!^(\s+)#{src}#{start}.*?^\1#{src}(\}|end)!m) { |chunk|
405
+ indent = $1
406
+ chunk.gsub(%r!^#{indent}#{src}!, "#{indent}#{dst}")
407
+ }
408
+ end
409
+
410
+ def comment_lines(on, contents, start)
411
+ src, dst = comment_src_dst(on)
412
+ contents.gsub(%r!^(\s*)#{src}#{start}!) {
413
+ $1 + dst + start
414
+ }
415
+ end
416
+
417
+ def debug_info(enable)
418
+ Find.find("lib", "test") { |path|
419
+ if path =~ %r!\.rb\Z!
420
+ replace_file(path) { |contents|
421
+ result = comment_regions(!enable, contents, "debug")
422
+ comment_lines(!enable, result, "trace")
423
+ }
424
+ end
425
+ }
426
+ end
427
+ end
428
+
429
+ desc "enable debug and trace calls"
430
+ task :debug_on do
431
+ runner.new.debug_info(true)
432
+ end
433
+
434
+ desc "disable debug and trace calls"
435
+ task :debug_off do
436
+ runner.new.debug_info(false)
437
+ end
438
+ end
439
+
440
+ def define_columns
441
+ desc "check for columns > 80"
442
+ task :check_columns do
443
+ Dir["**/*.rb"].each { |file|
444
+ File.read(file).scan(%r!^.{81}!) { |match|
445
+ unless match =~ %r!http://!
446
+ raise "#{file} greater than 80 columns: #{match}"
447
+ end
448
+ }
449
+ }
450
+ end
451
+ task :prerelease => :check_columns
452
+ end
453
+
454
+ def define_comments
455
+ task :comments do
456
+ file = "comments.txt"
457
+ write_file(file) {
458
+ Array.new.tap { |result|
459
+ (["Rakefile"] + Dir["**/*.{rb,rake}"]).each { |file|
460
+ File.read(file).scan(%r!\#[^\{].*$!) { |match|
461
+ result << match
462
+ }
463
+ }
464
+ }.join("\n")
465
+ }
466
+ CLEAN.include file
467
+ end
468
+ end
469
+
470
+ def define_check_directory
471
+ task :check_directory do
472
+ unless `git status` =~ %r!nothing to commit \(working directory clean\)!
473
+ raise "Directory not clean"
474
+ end
475
+ end
476
+ end
477
+
478
+ def define_ping
479
+ task :ping do
480
+ %w[github.com rubyforge.org].each { |server|
481
+ cmd = "ping " + (
482
+ if Config::CONFIG["host"] =~ %r!darwin!
483
+ "-c2 #{server}"
484
+ else
485
+ "#{server} 2 2"
486
+ end
487
+ )
488
+ unless `#{cmd}` =~ %r!0% packet loss!
489
+ raise "No ping for #{server}"
490
+ end
491
+ }
492
+ end
493
+ end
494
+
495
+ def git(*args)
496
+ sh("git", *args)
497
+ end
498
+
499
+ def rubyforge(command, file)
500
+ sh(
501
+ "rubyforge",
502
+ command,
503
+ rubyforge_name,
504
+ rubyforge_name,
505
+ version.to_s,
506
+ file
507
+ )
508
+ end
509
+
510
+ def define_release
511
+ task :prerelease => [:clean, :check_directory, :ping]
512
+
513
+ task :finish_release do
514
+ gem_md5, tgz_md5 = [gem, tgz].map { |file|
515
+ "#{file}.md5".tap { |md5|
516
+ sh("md5sum #{file} > #{md5}")
517
+ }
518
+ }
519
+
520
+ rubyforge("add_release", gem)
521
+ [gem_md5, tgz, tgz_md5].each { |file|
522
+ rubyforge("add_file", file)
523
+ }
524
+
525
+ git("tag", "#{name}-" + version.to_s)
526
+ git(*%w(push --tags origin master))
527
+ end
528
+
529
+ task :release => [:prerelease, :package, :publish, :finish_release]
530
+ end
531
+
532
+ def define_debug_gem
533
+ task :debug_gem do
534
+ puts gemspec.to_ruby
535
+ end
536
+ end
537
+
538
+ def open_browser(*files)
539
+ sh(*([browser].flatten + files))
540
+ end
541
+
542
+ def replace_file(file)
543
+ old_contents = File.read(file)
544
+ yield(old_contents).tap { |new_contents|
545
+ if old_contents != new_contents
546
+ File.open(file, "wb") { |output|
547
+ output.print(new_contents)
548
+ }
549
+ end
550
+ }
551
+ end
552
+
553
+ def write_file(file)
554
+ yield.tap { |contents|
555
+ File.open(file, "wb") { |out|
556
+ out.print(contents)
557
+ }
558
+ }
559
+ end
560
+
561
+ def run_ruby_on_each(*files)
562
+ files.each { |file|
563
+ Ruby.run_or_raise("-w", file)
564
+ }
565
+ end
566
+
567
+ def to_camel_case(str)
568
+ str.split('_').map { |t| t.capitalize }.join
569
+ end
570
+
571
+ unless respond_to? :tap
572
+ class Object
573
+ def tap
574
+ yield self
575
+ self
576
+ end
577
+ end
578
+ end
579
+ end
580
+