tournament 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,341 @@
1
+ # Represents a NCAA tournament pool. Contains 4 regions
2
+ # of 16 teams each. Champions of Region 1 and Region 2
3
+ # and champions of Region 3 and Region 4 play each
4
+ # other in the final four.
5
+ class Tournament::Pool
6
+ attr_reader :regions # The regions in the pool
7
+ attr_reader :entries # Tournament::Entry objects for participants
8
+
9
+ # Create a new empty pool with no Regions or Entries
10
+ def initialize
11
+ @regions = Array.new(4)
12
+ @entries = []
13
+ end
14
+
15
+ # add regions to the pool. Champ of region with index = 0 plays
16
+ # region with index = 1 and index == 2 plays index == 3.
17
+ def add_region(name, teams, index)
18
+ @regions[index] = {
19
+ :name => name,
20
+ :teams => teams
21
+ }
22
+ end
23
+
24
+ # Add an Tournament::Entry object to the pool
25
+ def add_entry(entry)
26
+ @entries << entry
27
+ end
28
+
29
+ # Add an Tournament::Entry object to the pool after reading the Tournament::Entry
30
+ # from the provided YAML file.
31
+ def add_entry_yaml(yaml)
32
+ @entries << YAML::load_file(yaml)
33
+ end
34
+
35
+ # Creates a bracket for the pool by combining all the
36
+ # regions into one bracket of 64 teams. By default the
37
+ # bracket uses the basic scoring strategy.
38
+ def bracket
39
+ unless @bracket
40
+ if @regions.compact.size != 4
41
+ raise "Not all regions have been set."
42
+ end
43
+ all_teams = @regions.map do |region|
44
+ region[:teams]
45
+ end
46
+ all_teams = all_teams.flatten
47
+ @bracket = Tournament::Bracket.new(all_teams)
48
+ end
49
+ return @bracket
50
+ end
51
+
52
+ # Replaces the pool's bracket (as in after updating the bracket
53
+ # for game results)
54
+ def bracket=(new_bracket)
55
+ @bracket = new_bracket
56
+ end
57
+
58
+ # Creates a Pool object for the 2008 NCAA tournament
59
+ def self.ncaa_2008
60
+ pool = Tournament::Pool.new
61
+ pool.add_region("East",
62
+ [
63
+ Tournament::Team.new('North Carolina', 'UNC', 1),
64
+ Tournament::Team.new('Mt. St. Mary\'s', 'MSM', 16),
65
+ Tournament::Team.new('Indiana', 'Ind', 8),
66
+ Tournament::Team.new('Arkansas', 'Ark', 9),
67
+ Tournament::Team.new('Notre Dame', 'ND', 5),
68
+ Tournament::Team.new('George Mason', 'GM', 12),
69
+ Tournament::Team.new('Washington St.', 'WSt', 4),
70
+ Tournament::Team.new('Winthrop', 'Win', 13),
71
+ Tournament::Team.new('Oklahoma', 'Okl', 6),
72
+ Tournament::Team.new('St. Joseph\'s', 'StJ', 11),
73
+ Tournament::Team.new('Louisville', 'Lou', 3),
74
+ Tournament::Team.new('Boise St.', 'BSt', 14),
75
+ Tournament::Team.new('Butler', 'But', 7),
76
+ Tournament::Team.new('South Alabama', 'SAl', 10),
77
+ Tournament::Team.new('Tennessee', 'Ten', 2),
78
+ Tournament::Team.new('American', 'Am', 15)
79
+ ],
80
+ 0
81
+ )
82
+ pool.add_region("Midwest",
83
+ [
84
+ Tournament::Team.new('Kansas', 'Kan', 1),
85
+ Tournament::Team.new('Portland St.', 'PSt', 16),
86
+ Tournament::Team.new('UNLV', 'ULV', 8),
87
+ Tournament::Team.new('Kent St.', 'KSt', 9),
88
+ Tournament::Team.new('Clemson', 'Clm', 5),
89
+ Tournament::Team.new('Villanova', 'Vil', 12),
90
+ Tournament::Team.new('Vanderbilt', 'Van', 4),
91
+ Tournament::Team.new('Siena', 'Sie', 13),
92
+ Tournament::Team.new('USC', 'USC', 6),
93
+ Tournament::Team.new('Kansas St.', 'KSU', 11),
94
+ Tournament::Team.new('Wisconsin', 'Wis', 3),
95
+ Tournament::Team.new('CSU Fullerton', 'CSF', 14),
96
+ Tournament::Team.new('Gonzaga', 'Gon', 7),
97
+ Tournament::Team.new('Davidson', 'Dav', 10),
98
+ Tournament::Team.new('Georgetown', 'GT', 2),
99
+ Tournament::Team.new('UMBC', 'UBC', 15)
100
+ ],
101
+ 1
102
+ )
103
+ pool.add_region("South",
104
+ [
105
+ Tournament::Team.new('Memphis', 'Mem', 1),
106
+ Tournament::Team.new('TX Arlington', 'TxA', 16),
107
+ Tournament::Team.new('Mississippi St.', 'MiS', 8),
108
+ Tournament::Team.new('Oregon', 'Ore', 9),
109
+ Tournament::Team.new('Michigan St.', 'MSU', 5),
110
+ Tournament::Team.new('Temple', 'Tem', 12),
111
+ Tournament::Team.new('Pittsburgh', 'Pit', 4),
112
+ Tournament::Team.new('Oral Roberts', 'ORo', 13),
113
+ Tournament::Team.new('Marquette', 'Mar', 6),
114
+ Tournament::Team.new('Kentucky', 'Ken', 11),
115
+ Tournament::Team.new('Stanford', 'Sta', 3),
116
+ Tournament::Team.new('Cornell', 'Cor', 14),
117
+ Tournament::Team.new('Miami (FL)', 'Mia', 7),
118
+ Tournament::Team.new('St. Mary\'s', 'StM', 10),
119
+ Tournament::Team.new('Texas', 'Tex', 2),
120
+ Tournament::Team.new('Austin Peay', 'APe', 15)
121
+ ],
122
+ 2
123
+ )
124
+ pool.add_region("West",
125
+ [
126
+ Tournament::Team.new('UCLA', 'ULA', 1),
127
+ Tournament::Team.new('Mis. Valley St', 'MVS', 16),
128
+ Tournament::Team.new('BYU', 'BYU', 8),
129
+ Tournament::Team.new('Texas A&M', 'A&M', 9),
130
+ Tournament::Team.new('Drake', 'Dra', 5),
131
+ Tournament::Team.new('W. Kentucky', 'WKy', 12),
132
+ Tournament::Team.new('Connecticut', 'Con', 4),
133
+ Tournament::Team.new('San Diego', 'SD', 13),
134
+ Tournament::Team.new('Purdue', 'Pur', 6),
135
+ Tournament::Team.new('Baylor', 'Bay', 11),
136
+ Tournament::Team.new('Xavier', 'Xav', 3),
137
+ Tournament::Team.new('Georgia', 'UG', 14),
138
+ Tournament::Team.new('West Virginia', 'WVa', 7),
139
+ Tournament::Team.new('Arizona', 'UA', 10),
140
+ Tournament::Team.new('Duke', 'Duk', 2),
141
+ Tournament::Team.new('Belmont', 'Bel', 15)
142
+ ],
143
+ 3
144
+ )
145
+ return pool
146
+ end
147
+
148
+ def self.test(num_picks = 10)
149
+ pool = ncaa_2008
150
+ b = pool.bracket
151
+ b.scoring_strategy = Tournament::Bracket::UpsetScoringStrategy.new
152
+ picks = (1..num_picks).map {|n| Tournament::Bracket.random_bracket(b.teams)}
153
+ # Play out the bracket
154
+ 32.times { |n| b.set_winner(1,n+1, b.matchup(1, n+1)[rand(2)])}
155
+ 16.times { |n| b.set_winner(2,n+1, b.matchup(2, n+1)[rand(2)])}
156
+ 8.times { |n| b.set_winner(3,n+1, b.matchup(3, n+1)[rand(2)])}
157
+ 4.times { |n| b.set_winner(4,n+1, b.matchup(4, n+1)[rand(2)])}
158
+ 2.times { |n| b.set_winner(5,n+1, b.matchup(5, n+1)[rand(2)])}
159
+ 1.times { |n| b.set_winner(6,n+1, b.matchup(6, n+1)[rand(2)])}
160
+ picks.each_with_index {|p, idx| pool.add_entry Tournament::Entry.new("picker_#{idx}", p) }
161
+ picks.each_with_index do |p, idx|
162
+ puts "Score #{idx+1}: #{p.score_against(b)}"
163
+ end
164
+ #pool.possibility_report
165
+ pool.leader_report
166
+ pool.entry_report
167
+ end
168
+
169
+ def leader_report
170
+ puts "Total games played: #{@bracket.games_played}"
171
+ puts "Number of entries: #{@entries.size}"
172
+ if @entries.size > 0
173
+ puts " Curr| Max | |Champ| Round Scores"
174
+ puts "Score|Score| Name |Live?|" + (1..bracket.rounds).to_a.map{|r| "%3d" % r}.join(" ")
175
+ sep ="-----+-----+---------------+-----+" + ("-" * 4 * bracket.rounds)
176
+ puts sep
177
+ @entries.sort_by {|e| -e.picks.score_against(bracket)}.each do |entry|
178
+ total = entry.picks.score_against(bracket)
179
+ max = entry.picks.maximum_score(bracket)
180
+ champ = entry.picks.champion
181
+ round_scores = []
182
+ 1.upto(bracket.rounds) do |round|
183
+ scores = entry.picks.scores_for_round(round, bracket)
184
+ round_scores << scores.inject(0) {|sum, arr| sum += (arr[0] ? arr[0] : 0)}
185
+ end
186
+ puts "%5d|%5d|%15s|%3s %1s|%s" % [total, max, entry.name,
187
+ champ.short_name,(bracket.still_alive?(champ) ? 'Y' : 'N'), round_scores.map {|s| "%3d" % s}.join(" ")]
188
+ end
189
+ puts sep
190
+ end
191
+ end
192
+
193
+ def score_report
194
+ # Compute scores
195
+ puts "Total games played: #{@bracket.games_played}"
196
+ puts "Number of entries: #{@entries.size}"
197
+ sep = "-----+---------------+----------------------------------------------------------------------------------"
198
+ if @entries.size > 0
199
+ puts "Total| Name | Round Scores"
200
+ puts sep
201
+ fmt1 = "%5d|%15s|%d: %3d %s"
202
+ fmt2 = " | |%d: %3d %s"
203
+ fmt3 = " | | %s"
204
+ @entries.sort_by {|e| -e.picks.score_against(bracket)}.each do |entry|
205
+ total = entry.picks.score_against(bracket)
206
+ 1.upto(bracket.rounds) do |round|
207
+ scores = entry.picks.scores_for_round(round, bracket)
208
+ round_total = scores.inject(0) {|sum, arr| sum += (arr[0] ? arr[0] : 0)}
209
+ scores_str = scores.map{|arr| "#{arr[1].short_name}=#{arr[0] ? arr[0] : '?'}"}.join(" ")
210
+ if [1,2].include?(round)
211
+ scores_str_arr = Tournament::Pool.split_line(scores_str, 70)
212
+ if round == 1
213
+ puts fmt1 % [total, entry.name, round, round_total, scores_str_arr[0]]
214
+ else
215
+ puts fmt2 % [round, round_total, scores_str_arr[0]]
216
+ end
217
+ scores_str_arr[1..-1].each do |scores_str|
218
+ puts fmt3 % scores_str
219
+ end
220
+ else
221
+ puts fmt2 % [round, round_total, scores_str]
222
+ end
223
+ end
224
+ puts sep
225
+ end
226
+ end
227
+ end
228
+
229
+ def self.split_line(str, len)
230
+ new_str = []
231
+ beg_idx = 0
232
+ end_idx = len - 1
233
+ while end_idx < str.length
234
+ end_idx += 1 while end_idx < (str.length - 1) && str[end_idx].chr != ' '
235
+ new_str << str[beg_idx,(end_idx-beg_idx+1)].strip
236
+ beg_idx = end_idx + 1
237
+ end_idx += len
238
+ end
239
+ new_str << str[beg_idx,str.length-1]
240
+ return new_str.reject {|s| s.nil? || s.length == 0}
241
+ end
242
+
243
+ def entry_report
244
+ puts "There are #{@entries.size} entries."
245
+ if @entries.size > 0
246
+ puts "".center(15) + "|" + "First Round".center(128)
247
+ puts "Name".center(15) + "|" + "Sweet 16".center(64) + "|" + "Elite 8".center(32) +
248
+ "|" + "Final 4".center(16) + "|" + "Final 2".center(8) + "|" + "Champion".center(15) +
249
+ "|" + "Tie Break"
250
+ puts ("-" * 15) + "+" + ("-" * 64) + "+" + ("-" * 32) +
251
+ "+" + ("-" * 16) + "+" + ("-" * 8) + "+" + ("-" * 15) +
252
+ "+" + ("-" * 10)
253
+ output = Proc.new do |name, bracket, tie_breaker|
254
+ first_round = bracket.winners[1].map {|t| "%s" % (t.short_name rescue 'Unk')}.join('-')
255
+ sweet_16 = bracket.winners[2].map {|t| "%s" % (t.short_name rescue 'Unk')}.join('-')
256
+ elite_8 = bracket.winners[3].map {|t| "%s" % (t.short_name rescue 'Unk')}.join('-')
257
+ final_4 = bracket.winners[4].map {|t| "%s" % (t.short_name rescue 'Unk')}.join('-')
258
+ final_2 = bracket.winners[5].map {|t| "%s" % (t.short_name rescue 'Unk')}.join('-')
259
+ champ = bracket.champion.name rescue 'Unk'
260
+ puts " |%128s" % first_round
261
+ puts "%15s|%64s|%32s|%16s|%8s|%15s|%s" %
262
+ [name, sweet_16, elite_8, final_4, final_2, champ, tie_breaker.to_s]
263
+ puts ("-" * 15) + "+" + ("-" * 64) + "+" + ("-" * 32) +
264
+ "+" + ("-" * 16) + "+" + ("-" * 8) + "+" + ("-" * 15) +
265
+ "+" + ("-" * 10)
266
+ end
267
+
268
+ output.call('Tournament', bracket, '-')
269
+
270
+ @entries.sort_by{|e| e.name}.each do |entry|
271
+ output.call(entry.name, entry.picks, entry.tie_breaker)
272
+ end
273
+ end
274
+ end
275
+
276
+ def region_report
277
+ puts " Region | Seed | Team "
278
+ current_idx = -1
279
+ @regions.each_with_index do |region, idx|
280
+ region[:teams].each do |team|
281
+ region_name = ''
282
+ if idx != current_idx
283
+ region_name = region[:name]
284
+ current_idx = idx
285
+ puts "--------+------+-------------------------"
286
+ end
287
+ puts "%8s|%6d|%25s" % [region_name, team.seed, "#{team.name} (#{team.short_name})"]
288
+ end
289
+ end
290
+ end
291
+
292
+ def possibility_report
293
+ if @entries.size == 0
294
+ puts "There are no entries in the pool."
295
+ return
296
+ end
297
+ max_possible_score = @entries.map{|p| 0}
298
+ min_ranking = @entries.map{|p| @entries.size + 1}
299
+ times_winner = @entries.map{|p| 0 }
300
+ count = 0
301
+ start = Time.now.to_f
302
+ self.bracket.each_possible_bracket do |poss|
303
+ poss_scores = @entries.map{|p| p.picks.score_against(poss)}
304
+ sort_scores = poss_scores.sort.reverse
305
+ @entries.each_with_index do |entry, i|
306
+ score = poss_scores[i]
307
+ max_possible_score[i] = score if score > max_possible_score[i]
308
+ rank = sort_scores.index(score) + 1
309
+ min_ranking[i] = rank if rank < min_ranking[i]
310
+ times_winner[i] += 1 if rank == 1
311
+ end
312
+ count += 1
313
+ percentage = (count * 100 / self.bracket.number_of_outcomes) * 1000
314
+ if (percentage % 1000) == 0
315
+ percentage /= 1000
316
+ hashes = '#' * percentage + '>'
317
+ elapsed = Time.now.to_f - start
318
+ spp = elapsed / count
319
+ remaining = ((self.bracket.number_of_outcomes - count) * spp).to_i
320
+ print "\rCalculating: %3d%% +#{hashes.ljust(100, '-')}+ %5d seconds remaining" % [percentage, remaining]
321
+
322
+ end
323
+ end
324
+ puts "\n"
325
+ #puts "\n Max Scores: #{max_possible_score.inspect}"
326
+ #puts "Highest Place: #{min_ranking.inspect}"
327
+ #puts " Times Winner: #{times_winner.inspect}"
328
+ sort_array = []
329
+ times_winner.each_with_index { |n, i| sort_array << [n, i, min_ranking[i], max_possible_score[i]] }
330
+ sort_array = sort_array.sort_by {|arr| arr[0] == 0 ? (arr[2] == 0 ? -arr[3] : arr[2]) : -arr[0]}
331
+ #puts "SORT: #{sort_array.inspect}"
332
+ puts " Entry | Win Chance | Highest Place | Max Score | Tie Break "
333
+ puts "--------------------+------------+---------------+-----------+------------"
334
+ sort_array.each do |arr|
335
+ chance = arr[0].to_f * 100.0 / self.bracket.number_of_outcomes
336
+ puts "%19s | %10.2f | %13d | %9d | %d" %
337
+ [@entries[arr[1]].name, chance, min_ranking[arr[1]], max_possible_score[arr[1]], @entries[arr[1]].tie_breaker]
338
+ end
339
+ end
340
+
341
+ end
@@ -0,0 +1,19 @@
1
+ # Represents a team in a tournament Bracket
2
+ class Tournament::Team
3
+ attr_reader :name, :short_name, :seed
4
+
5
+ def initialize(name, short_name, seed)
6
+ @name = name
7
+ @short_name = short_name
8
+ @seed = seed
9
+ end
10
+
11
+ def ==(other)
12
+ return false unless Tournament::Team === other
13
+ @name == other.name && @short_name == other.short_name && @seed == other.seed
14
+ end
15
+
16
+ def eql?(other)
17
+ @name.eql?(other)
18
+ end
19
+ end
data/lib/tournament.rb ADDED
@@ -0,0 +1,56 @@
1
+ # $Id$
2
+
3
+ # Equivalent to a header guard in C/C++
4
+ # Used to prevent the class/module from being loaded more than once
5
+ unless defined? Tournament
6
+
7
+ module Tournament
8
+
9
+ # :stopdoc:
10
+ VERSION = '1.0.0'
11
+ LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
12
+ PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
13
+ # :startdoc:
14
+
15
+ # Returns the version string for the library.
16
+ #
17
+ def self.version
18
+ VERSION
19
+ end
20
+
21
+ # Returns the library path for the module. If any arguments are given,
22
+ # they will be joined to the end of the libray path using
23
+ # <tt>File.join</tt>.
24
+ #
25
+ def self.libpath( *args )
26
+ args.empty? ? LIBPATH : ::File.join(LIBPATH, *args)
27
+ end
28
+
29
+ # Returns the lpath for the module. If any arguments are given,
30
+ # they will be joined to the end of the path using
31
+ # <tt>File.join</tt>.
32
+ #
33
+ def self.path( *args )
34
+ args.empty? ? PATH : ::File.join(PATH, *args)
35
+ end
36
+
37
+ # Utility method used to rquire all files ending in .rb that lie in the
38
+ # directory below this file that has the same name as the filename passed
39
+ # in. Optionally, a specific _directory_ name can be passed in such that
40
+ # the _filename_ does not have to be equivalent to the directory.
41
+ #
42
+ def self.require_all_libs_relative_to( fname, dir = nil )
43
+ dir ||= ::File.basename(fname, '.*')
44
+ search_me = ::File.expand_path(
45
+ ::File.join(::File.dirname(fname), dir, '**', '*.rb'))
46
+
47
+ Dir.glob(search_me).sort.each {|rb| require rb}
48
+ end
49
+
50
+ end # module Tournament
51
+
52
+ Tournament.require_all_libs_relative_to __FILE__
53
+
54
+ end # unless defined?
55
+
56
+ # EOF
@@ -0,0 +1,17 @@
1
+ # $Id$
2
+
3
+ require File.expand_path(
4
+ File.join(File.dirname(__FILE__), %w[.. lib tournament]))
5
+
6
+ Spec::Runner.configure do |config|
7
+ # == Mock Framework
8
+ #
9
+ # RSpec uses it's own mocking framework by default. If you prefer to
10
+ # use mocha, flexmock or RR, uncomment the appropriate line:
11
+ #
12
+ # config.mock_with :mocha
13
+ # config.mock_with :flexmock
14
+ # config.mock_with :rr
15
+ end
16
+
17
+ # EOF
@@ -0,0 +1,8 @@
1
+ # $Id$
2
+
3
+ require File.join(File.dirname(__FILE__), %w[spec_helper])
4
+
5
+ describe Tournament do
6
+ end
7
+
8
+ # EOF
Binary file
data/tasks/ann.rake ADDED
@@ -0,0 +1,76 @@
1
+ # $Id$
2
+
3
+ begin
4
+ require 'bones/smtp_tls'
5
+ rescue LoadError
6
+ require 'net/smtp'
7
+ end
8
+ require 'time'
9
+
10
+ namespace :ann do
11
+
12
+ file PROJ.ann_file do
13
+ puts "Generating #{PROJ.ann_file}"
14
+ File.open(PROJ.ann_file,'w') do |fd|
15
+ fd.puts("#{PROJ.name} version #{PROJ.version}")
16
+ fd.puts(" by #{Array(PROJ.authors).first}") if PROJ.authors
17
+ fd.puts(" #{PROJ.url}") if PROJ.url
18
+ fd.puts(" (the \"#{PROJ.release_name}\" release)") if PROJ.release_name
19
+ fd.puts
20
+ fd.puts("== DESCRIPTION")
21
+ fd.puts
22
+ fd.puts(PROJ.description)
23
+ fd.puts
24
+ fd.puts(PROJ.changes.sub(%r/^.*$/, '== CHANGES'))
25
+ fd.puts
26
+ PROJ.ann_paragraphs.each do |p|
27
+ fd.puts "== #{p.upcase}"
28
+ fd.puts
29
+ fd.puts paragraphs_of(PROJ.readme_file, p).join("\n\n")
30
+ fd.puts
31
+ end
32
+ fd.puts PROJ.ann_text if PROJ.ann_text
33
+ end
34
+ end
35
+
36
+ desc "Create an announcement file"
37
+ task :announcement => PROJ.ann_file
38
+
39
+ desc "Send an email announcement"
40
+ task :email => PROJ.ann_file do
41
+ from = PROJ.ann_email[:from] || PROJ.email
42
+ to = Array(PROJ.ann_email[:to])
43
+
44
+ ### build a mail header for RFC 822
45
+ rfc822msg = "From: #{from}\n"
46
+ rfc822msg << "To: #{to.join(',')}\n"
47
+ rfc822msg << "Subject: [ANN] #{PROJ.name} #{PROJ.version}"
48
+ rfc822msg << " (#{PROJ.release_name})" if PROJ.release_name
49
+ rfc822msg << "\n"
50
+ rfc822msg << "Date: #{Time.new.rfc822}\n"
51
+ rfc822msg << "Message-Id: "
52
+ rfc822msg << "<#{"%.8f" % Time.now.to_f}@#{PROJ.ann_email[:domain]}>\n\n"
53
+ rfc822msg << File.read(PROJ.ann_file)
54
+
55
+ params = [:server, :port, :domain, :acct, :passwd, :authtype].map do |key|
56
+ PROJ.ann_email[key]
57
+ end
58
+
59
+ params[3] = PROJ.email if params[3].nil?
60
+
61
+ if params[4].nil?
62
+ STDOUT.write "Please enter your e-mail password (#{params[3]}): "
63
+ params[4] = STDIN.gets.chomp
64
+ end
65
+
66
+ ### send email
67
+ Net::SMTP.start(*params) {|smtp| smtp.sendmail(rfc822msg, from, to)}
68
+ end
69
+ end # namespace :ann
70
+
71
+ desc 'Alias to ann:announcement'
72
+ task :ann => 'ann:announcement'
73
+
74
+ CLOBBER << PROJ.ann_file
75
+
76
+ # EOF
@@ -0,0 +1,22 @@
1
+ # $Id$
2
+
3
+ if HAVE_BONES
4
+
5
+ desc "Enumerate all annotations"
6
+ task :notes do
7
+ Bones::AnnotationExtractor.enumerate(
8
+ PROJ, PROJ.annotation_tags.join('|'), :tag => true)
9
+ end
10
+
11
+ namespace :notes do
12
+ PROJ.annotation_tags.each do |tag|
13
+ desc "Enumerate all #{tag} annotations"
14
+ task tag.downcase.to_sym do
15
+ Bones::AnnotationExtractor.enumerate(PROJ, tag)
16
+ end
17
+ end
18
+ end
19
+
20
+ end # if HAVE_BONES
21
+
22
+ # EOF
data/tasks/bones.rake ADDED
@@ -0,0 +1,40 @@
1
+ # $Id$
2
+
3
+ require 'pp'
4
+ require 'stringio'
5
+
6
+ namespace :bones do
7
+
8
+ desc 'Show the PROJ open struct'
9
+ task :debug do |t|
10
+ atr = if ARGV.length == 2
11
+ t.application.top_level_tasks.pop
12
+ end
13
+ sio = StringIO.new
14
+ sep = "\n" + ' '*27
15
+ fmt = "%23s => %s"
16
+
17
+ if atr
18
+ PP.pp(PROJ.send(atr.to_sym), sio, 49)
19
+ sio.seek 0
20
+ val = sio.read
21
+ val = val.split("\n").join(sep)
22
+
23
+ puts fmt % [atr, val]
24
+ else
25
+ h = PROJ.instance_variable_get(:@table)
26
+ h.keys.map {|k| k.to_s}.sort.each do |k|
27
+ sio.truncate 0
28
+ PP.pp(h[k.to_sym], sio, 49)
29
+ sio.seek 0
30
+ val = sio.read
31
+ val = val.split("\n").join(sep)
32
+
33
+ puts fmt % [k, val]
34
+ end
35
+ end
36
+ end
37
+
38
+ end # namespace :bones
39
+
40
+ # EOF
data/tasks/doc.rake ADDED
@@ -0,0 +1,48 @@
1
+ # $Id$
2
+
3
+ require 'rake/rdoctask'
4
+
5
+ namespace :doc do
6
+
7
+ desc 'Generate RDoc documentation'
8
+ Rake::RDocTask.new do |rd|
9
+ rd.main = PROJ.rdoc_main
10
+ rd.rdoc_dir = PROJ.rdoc_dir
11
+
12
+ incl = Regexp.new(PROJ.rdoc_include.join('|'))
13
+ excl = Regexp.new(PROJ.rdoc_exclude.join('|'))
14
+ files = PROJ.files.find_all do |fn|
15
+ case fn
16
+ when excl; false
17
+ when incl; true
18
+ else false end
19
+ end
20
+ rd.rdoc_files.push(*files)
21
+
22
+ title = "#{PROJ.name}-#{PROJ.version} Documentation"
23
+ title = "#{PROJ.rubyforge_name}'s " + title if PROJ.rubyforge_name != title
24
+
25
+ rd.options << "-t #{title}"
26
+ rd.options.concat(PROJ.rdoc_opts)
27
+ end
28
+
29
+ desc 'Generate ri locally for testing'
30
+ task :ri => :clobber_ri do
31
+ sh "#{RDOC} --ri -o ri ."
32
+ end
33
+
34
+ task :clobber_ri do
35
+ rm_r 'ri' rescue nil
36
+ end
37
+
38
+ end # namespace :doc
39
+
40
+ desc 'Alias to doc:rdoc'
41
+ task :doc => 'doc:rdoc'
42
+
43
+ desc 'Remove all build products'
44
+ task :clobber => %w(doc:clobber_rdoc doc:clobber_ri)
45
+
46
+ remove_desc_for_task %w(doc:clobber_rdoc)
47
+
48
+ # EOF