darkfish-rdoc 1.1.1
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/ChangeLog +194 -0
- data/LICENSE +27 -0
- data/README +100 -0
- data/Rakefile +238 -0
- data/Rakefile.local +4 -0
- data/lib/darkfish-rdoc.rb +26 -0
- data/lib/rdoc/generator/darkfish.rb +456 -0
- data/rake/dependencies.rb +62 -0
- data/rake/helpers.rb +350 -0
- data/rake/manual.rb +384 -0
- data/rake/packaging.rb +112 -0
- data/rake/publishing.rb +301 -0
- data/rake/rdoc.rb +30 -0
- data/rake/style.rb +62 -0
- data/rake/svn.rb +441 -0
- data/rake/testing.rb +191 -0
- data/rake/verifytask.rb +64 -0
- metadata +86 -0
data/rake/svn.rb
ADDED
@@ -0,0 +1,441 @@
|
|
1
|
+
#
|
2
|
+
# Subversion Rake Tasks
|
3
|
+
# $Id: svn.rb 22 2008-08-08 01:30:06Z deveiant $
|
4
|
+
#
|
5
|
+
# Authors:
|
6
|
+
# * Michael Granger <ged@FaerieMUD.org>
|
7
|
+
#
|
8
|
+
|
9
|
+
|
10
|
+
require 'pp'
|
11
|
+
require 'yaml'
|
12
|
+
require 'date'
|
13
|
+
|
14
|
+
# Strftime format for tags/releases
|
15
|
+
TAG_TIMESTAMP_FORMAT = '%Y%m%d-%H%M%S'
|
16
|
+
TAG_TIMESTAMP_PATTERN = /\d{4}\d{2}\d{2}-\d{6}/
|
17
|
+
|
18
|
+
RELEASE_VERSION_PATTERN = /\d+\.\d+\.\d+/
|
19
|
+
|
20
|
+
DEFAULT_EDITOR = 'vi'
|
21
|
+
DEFAULT_KEYWORDS = %w[Date Rev Author URL Id]
|
22
|
+
KEYWORDED_FILEDIRS = %w[applets bin etc lib misc]
|
23
|
+
KEYWORDED_FILEPATTERN = /^(?:Rakefile|.*\.(?:rb|js|html|template))$/i
|
24
|
+
|
25
|
+
COMMIT_MSG_FILE = 'commit-msg.txt'
|
26
|
+
|
27
|
+
SVN_TRUNK_DIR = 'trunk' unless defined?( SVN_TRUNK_DIR )
|
28
|
+
SVN_RELEASES_DIR = 'branches' unless defined?( SVN_RELEASES_DIR )
|
29
|
+
SVN_BRANCHES_DIR = 'branches' unless defined?( SVN_BRANCHES_DIR )
|
30
|
+
SVN_TAGS_DIR = 'tags' unless defined?( SVN_TAGS_DIR )
|
31
|
+
|
32
|
+
FILE_INDENT = " " * 12
|
33
|
+
LOG_INDENT = " " * 3
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
###
|
38
|
+
### Subversion-specific Helpers
|
39
|
+
###
|
40
|
+
|
41
|
+
### Return a new tag for the given time
|
42
|
+
def make_new_tag( time=Time.now )
|
43
|
+
return time.strftime( TAG_TIMESTAMP_FORMAT )
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
### Get the subversion information for the current working directory as
|
48
|
+
### a hash.
|
49
|
+
def get_svn_info( dir='.' )
|
50
|
+
return {} unless File.directory?( File.join(dir, '.svn') )
|
51
|
+
info = IO.read( '|-' ) or exec 'svn', 'info', dir
|
52
|
+
return YAML.load( info ) # 'svn info' outputs valid YAML! Yay!
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
### Get a list of the objects registered with subversion under the specified directory and
|
57
|
+
### return them as an Array of Pathame objects.
|
58
|
+
def get_svn_filelist( dir='.' )
|
59
|
+
list = IO.read( '|-' ) or exec 'svn', 'st', '-v', '--ignore-externals', dir
|
60
|
+
|
61
|
+
# Split into lines, filter out the unknowns, and grab the filenames as Pathnames
|
62
|
+
# :FIXME: This will break if we ever put in a file with spaces in its name. This
|
63
|
+
# will likely be the least of our worries if we do so, however, so it's not worth
|
64
|
+
# the additional complexity to make it handle that case. If we do need that, there's
|
65
|
+
# always the --xml output for 'svn st'...
|
66
|
+
return list.split( $/ ).
|
67
|
+
reject {|line| line =~ /^\?/ }.
|
68
|
+
collect {|fn| Pathname(fn[/\S+$/]) }
|
69
|
+
end
|
70
|
+
|
71
|
+
### Return the URL to the repository root for the specified +dir+.
|
72
|
+
def get_svn_repo_root( dir='.' )
|
73
|
+
info = get_svn_info( dir )
|
74
|
+
return info['Repository Root']
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
### Return the Subversion URL to the given +dir+.
|
79
|
+
def get_svn_url( dir='.' )
|
80
|
+
info = get_svn_info( dir )
|
81
|
+
return info['URL']
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
### Return the path of the specified +dir+ under the svn root of the
|
86
|
+
### checkout.
|
87
|
+
def get_svn_path( dir='.' )
|
88
|
+
root = get_svn_repo_root( dir )
|
89
|
+
url = get_svn_url( dir )
|
90
|
+
|
91
|
+
return url.sub( root + '/', '' )
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
### Return the keywords for the specified array of +files+ as a Hash keyed by filename.
|
96
|
+
def get_svn_keyword_map( files )
|
97
|
+
cmd = ['svn', 'pg', 'svn:keywords', *files]
|
98
|
+
|
99
|
+
# trace "Executing: svn pg svn:keywords " + files.join(' ')
|
100
|
+
output = IO.read( '|-' ) or exec( 'svn', 'pg', 'svn:keywords', *files )
|
101
|
+
|
102
|
+
kwmap = {}
|
103
|
+
output.split( "\n" ).each do |line|
|
104
|
+
next if line !~ /\s+-\s+/
|
105
|
+
path, keywords = line.split( /\s+-\s+/, 2 )
|
106
|
+
kwmap[ path ] = keywords.split
|
107
|
+
end
|
108
|
+
|
109
|
+
return kwmap
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
### Return the latest revision number of the specified +dir+ as an Integer.
|
114
|
+
def get_svn_rev( dir='.' )
|
115
|
+
info = get_svn_info( dir )
|
116
|
+
return info['Revision']
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
### Return the latest revision number of the specified +dir+ as an Integer.
|
121
|
+
def get_last_changed_rev( dir='.' )
|
122
|
+
info = get_svn_info( dir )
|
123
|
+
return info['Last Changed Rev']
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
### Return a list of the entries at the specified Subversion url. If
|
128
|
+
### no +url+ is specified, it will default to the list in the URL
|
129
|
+
### corresponding to the current working directory.
|
130
|
+
def svn_ls( url=nil )
|
131
|
+
url ||= get_svn_url()
|
132
|
+
list = IO.read( '|-' ) or exec 'svn', 'ls', url
|
133
|
+
|
134
|
+
trace 'svn ls of %s: %p' % [url, list] if $trace
|
135
|
+
|
136
|
+
return [] if list.nil? || list.empty?
|
137
|
+
return list.split( $INPUT_RECORD_SEPARATOR )
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
### Return the URL of the latest timestamp in the tags directory.
|
142
|
+
def get_latest_svn_timestamp_tag
|
143
|
+
rooturl = get_svn_repo_root()
|
144
|
+
tagsurl = rooturl + "/#{SVN_TAGS_DIR}"
|
145
|
+
|
146
|
+
tags = svn_ls( tagsurl ).grep( TAG_TIMESTAMP_PATTERN ).sort
|
147
|
+
return nil if tags.nil? || tags.empty?
|
148
|
+
return tagsurl + '/' + tags.last
|
149
|
+
end
|
150
|
+
|
151
|
+
|
152
|
+
### Get a subversion diff of the specified targets and return it. If no targets are
|
153
|
+
### specified, the current directory will be diffed instead.
|
154
|
+
def get_svn_diff( *targets )
|
155
|
+
targets << BASEDIR if targets.empty?
|
156
|
+
trace "Getting svn diff for targets: %p" % [targets]
|
157
|
+
log = IO.read( '|-' ) or exec 'svn', 'diff', *(targets.flatten)
|
158
|
+
|
159
|
+
return log
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
### Return the URL of the latest timestamp in the tags directory.
|
164
|
+
def get_latest_release_tag
|
165
|
+
rooturl = get_svn_repo_root()
|
166
|
+
releaseurl = rooturl + "/#{SVN_RELEASES_DIR}"
|
167
|
+
|
168
|
+
tags = svn_ls( releaseurl ).grep( RELEASE_VERSION_PATTERN ).sort_by do |tag|
|
169
|
+
tag[RELEASE_VERSION_PATTERN].split('.').collect {|i| Integer(i) }
|
170
|
+
end
|
171
|
+
return nil if tags.empty?
|
172
|
+
|
173
|
+
return releaseurl + '/' + tags.last
|
174
|
+
end
|
175
|
+
|
176
|
+
|
177
|
+
### Extract a diff from the specified subversion working +dir+ and return it.
|
178
|
+
def make_svn_commit_log( dir='.' )
|
179
|
+
diff = IO.read( '|-' ) or exec 'svn', 'diff'
|
180
|
+
fail "No differences." if diff.empty?
|
181
|
+
|
182
|
+
return diff
|
183
|
+
end
|
184
|
+
|
185
|
+
|
186
|
+
### Extract the svn log from the specified subversion working +dir+,
|
187
|
+
### starting from rev +start+ and ending with rev +finish+, and return it.
|
188
|
+
def make_svn_log( dir='.', start='PREV', finish='HEAD' )
|
189
|
+
trace "svn log -r#{start}:#{finish} #{dir}"
|
190
|
+
log = IO.read( '|-' ) or exec 'svn', 'log', "-r#{start}:#{finish}", dir
|
191
|
+
fail "No log between #{start} and #{finish}." if log.empty?
|
192
|
+
|
193
|
+
return log
|
194
|
+
end
|
195
|
+
|
196
|
+
|
197
|
+
### Extract the verbose XML svn log from the specified subversion working +dir+,
|
198
|
+
### starting from rev +start+ and ending with rev +finish+, and return it.
|
199
|
+
def make_xml_svn_log( dir='.', start='PREV', finish='HEAD' )
|
200
|
+
trace "svn log --xml --verbose -r#{start}:#{finish} #{dir}"
|
201
|
+
log = IO.read( '|-' ) or exec 'svn', 'log', '--verbose', '--xml', "-r#{start}:#{finish}", dir
|
202
|
+
fail "No log between #{start} and #{finish}." if log.empty?
|
203
|
+
|
204
|
+
return log
|
205
|
+
end
|
206
|
+
|
207
|
+
|
208
|
+
### Create a changelog from the subversion log of the specified +dir+ and return it.
|
209
|
+
def make_svn_changelog( dir='.' )
|
210
|
+
require 'xml/libxml'
|
211
|
+
|
212
|
+
changelog = ''
|
213
|
+
path_prefix = '/' + get_svn_path( dir ) + '/'
|
214
|
+
|
215
|
+
xmllog = make_xml_svn_log( dir, 0 )
|
216
|
+
|
217
|
+
parser = XML::Parser.string( xmllog )
|
218
|
+
root = parser.parse.root
|
219
|
+
root.find( '//log/logentry' ).to_a.reverse.each do |entry|
|
220
|
+
trace "Making a changelog entry for r%s" % [ entry['revision'] ]
|
221
|
+
|
222
|
+
added = []
|
223
|
+
deleted = []
|
224
|
+
changed = []
|
225
|
+
|
226
|
+
entry.find( 'paths/path').each do |path|
|
227
|
+
pathname = path.content
|
228
|
+
pathname.sub!( path_prefix , '' ) if pathname.count('/') > 1
|
229
|
+
|
230
|
+
case path['action']
|
231
|
+
when 'A', 'R'
|
232
|
+
if path['copyfrom-path']
|
233
|
+
verb = path['action'] == 'A' ? 'renamed' : 'copied'
|
234
|
+
added << "%s\n#{FILE_INDENT}-> #{verb} from %s@r%s" % [
|
235
|
+
pathname,
|
236
|
+
path['copyfrom-path'],
|
237
|
+
path['copyfrom-rev'],
|
238
|
+
]
|
239
|
+
else
|
240
|
+
added << "%s (new)" % [ pathname ]
|
241
|
+
end
|
242
|
+
|
243
|
+
when 'M'
|
244
|
+
changed << pathname
|
245
|
+
|
246
|
+
when 'D'
|
247
|
+
deleted << pathname
|
248
|
+
|
249
|
+
else
|
250
|
+
log "Unknown action %p in rev %d" % [ path['action'], entry['revision'] ]
|
251
|
+
end
|
252
|
+
|
253
|
+
end
|
254
|
+
|
255
|
+
date = Time.parse( entry.find_first('date').content )
|
256
|
+
author = entry.find_first( 'author' ).content
|
257
|
+
msg = entry.find_first( 'msg' ).content
|
258
|
+
rev = entry['revision']
|
259
|
+
|
260
|
+
changelog << "-- #{date.rfc2822} by #{author} (r#{rev}) -----\n"
|
261
|
+
changelog << " Added: " << humanize_file_list(added) << "\n" unless added.empty?
|
262
|
+
changelog << " Changed: " << humanize_file_list(changed) << "\n" unless changed.empty?
|
263
|
+
changelog << " Deleted: " << humanize_file_list(deleted) << "\n" unless deleted.empty?
|
264
|
+
changelog << "\n"
|
265
|
+
|
266
|
+
indent = msg[/^(\s*)/] + LOG_INDENT
|
267
|
+
|
268
|
+
changelog << indent << msg.strip.gsub(/\n\s*/m, "\n#{indent}")
|
269
|
+
changelog << "\n\n\n"
|
270
|
+
end
|
271
|
+
|
272
|
+
return changelog
|
273
|
+
end
|
274
|
+
|
275
|
+
|
276
|
+
### Returns a human-scannable file list by joining and truncating the list if it's too long.
|
277
|
+
def humanize_file_list( list )
|
278
|
+
listtext = list[0..5].join( "\n#{FILE_INDENT}" )
|
279
|
+
if list.length > 5
|
280
|
+
listtext << " (and %d other/s)" % [ list.length - 5 ]
|
281
|
+
end
|
282
|
+
|
283
|
+
return listtext
|
284
|
+
end
|
285
|
+
|
286
|
+
|
287
|
+
|
288
|
+
###
|
289
|
+
### Tasks
|
290
|
+
###
|
291
|
+
|
292
|
+
desc "Subversion tasks"
|
293
|
+
namespace :svn do
|
294
|
+
|
295
|
+
desc "Copy the HEAD revision of the current #{SVN_TRUNK_DIR}/ to #{SVN_TAGS_DIR}/ with a " +
|
296
|
+
"current timestamp."
|
297
|
+
task :tag do
|
298
|
+
svninfo = get_svn_info()
|
299
|
+
tag = make_new_tag()
|
300
|
+
svntrunk = svninfo['Repository Root'] + "/#{SVN_TRUNK_DIR}"
|
301
|
+
svntagdir = svninfo['Repository Root'] + "/#{SVN_TAGS_DIR}"
|
302
|
+
svntag = svntagdir + '/' + tag
|
303
|
+
|
304
|
+
desc = "Tagging trunk as #{svntag}"
|
305
|
+
ask_for_confirmation( desc ) do
|
306
|
+
msg = prompt_with_default( "Commit log: ", "Tagging for code push" )
|
307
|
+
run 'svn', 'cp', '-m', msg, svntrunk, svntag
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
|
312
|
+
desc "Copy the most recent tag to #{SVN_RELEASES_DIR}/#{PKG_VERSION}"
|
313
|
+
task :release do
|
314
|
+
last_tag = get_latest_svn_timestamp_tag()
|
315
|
+
svninfo = get_svn_info()
|
316
|
+
svntrunk = svninfo['Repository Root'] + "/#{SVN_TRUNK_DIR}"
|
317
|
+
svnrel = svninfo['Repository Root'] + "/#{SVN_RELEASES_DIR}"
|
318
|
+
release = PKG_VERSION
|
319
|
+
svnrelease = svnrel + '/' + release
|
320
|
+
|
321
|
+
releases = svn_ls( svnrel ).collect {|name| name.sub(%r{/$}, '') }
|
322
|
+
trace "Releases: %p" % [releases]
|
323
|
+
if releases.include?( release )
|
324
|
+
error "Version #{release} already has a branch (#{svnrelease}). Did you mean " +
|
325
|
+
"to increment the version in #{VERSION_FILE}?"
|
326
|
+
fail
|
327
|
+
else
|
328
|
+
trace "No #{release} version currently exists"
|
329
|
+
end
|
330
|
+
|
331
|
+
desc = "Tagging trunk as #{svnrelease}..."
|
332
|
+
ask_for_confirmation( desc ) do
|
333
|
+
msg = prompt_with_default( "Commit log: ", "Branching for release" )
|
334
|
+
run 'svn', 'cp', '-m', msg, svntrunk, svnrelease
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
### Task for debugging the #get_target_args helper
|
339
|
+
task :show_targets do
|
340
|
+
$stdout.puts "Targets from ARGV (%p): %p" % [ARGV, get_target_args()]
|
341
|
+
end
|
342
|
+
|
343
|
+
|
344
|
+
desc "Generate a commit log"
|
345
|
+
task :commitlog => [COMMIT_MSG_FILE]
|
346
|
+
|
347
|
+
desc "Show the (pre-edited) commit log for the current directory"
|
348
|
+
task :show_commitlog do
|
349
|
+
puts make_svn_commit_log()
|
350
|
+
end
|
351
|
+
|
352
|
+
|
353
|
+
file COMMIT_MSG_FILE do
|
354
|
+
diff = make_svn_commit_log()
|
355
|
+
|
356
|
+
File.open( COMMIT_MSG_FILE, File::WRONLY|File::EXCL|File::CREAT ) do |fh|
|
357
|
+
fh.print( diff )
|
358
|
+
end
|
359
|
+
|
360
|
+
editor = ENV['EDITOR'] || ENV['VISUAL'] || DEFAULT_EDITOR
|
361
|
+
system editor, COMMIT_MSG_FILE
|
362
|
+
unless $?.success?
|
363
|
+
fail "Editor exited uncleanly."
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
|
368
|
+
desc "Update from Subversion"
|
369
|
+
task :update do
|
370
|
+
run 'svn', 'up', '--ignore-externals'
|
371
|
+
end
|
372
|
+
|
373
|
+
|
374
|
+
desc "Check in all the changes in your current working copy"
|
375
|
+
task :checkin => ['svn:update', 'coverage:verify', 'svn:fix_keywords', COMMIT_MSG_FILE] do
|
376
|
+
targets = get_target_args()
|
377
|
+
$deferr.puts '---', File.read( COMMIT_MSG_FILE ), '---'
|
378
|
+
ask_for_confirmation( "Continue with checkin?" ) do
|
379
|
+
run 'svn', 'ci', '-F', COMMIT_MSG_FILE, targets
|
380
|
+
rm_f COMMIT_MSG_FILE
|
381
|
+
end
|
382
|
+
end
|
383
|
+
task :commit => :checkin
|
384
|
+
task :ci => :checkin
|
385
|
+
|
386
|
+
|
387
|
+
task :clean do
|
388
|
+
rm_f COMMIT_MSG_FILE
|
389
|
+
end
|
390
|
+
|
391
|
+
|
392
|
+
desc "Check and fix any missing keywords for any files in the project which need them"
|
393
|
+
task :fix_keywords do
|
394
|
+
log "Checking subversion keywords..."
|
395
|
+
paths = get_svn_filelist( BASEDIR ).
|
396
|
+
select {|path| path.file? && path.to_s =~ KEYWORDED_FILEPATTERN }
|
397
|
+
|
398
|
+
trace "Looking at %d paths for keywords:\n %p" % [paths.length, paths]
|
399
|
+
kwmap = get_svn_keyword_map( paths )
|
400
|
+
|
401
|
+
buf = ''
|
402
|
+
PP.pp( kwmap, buf, 132 )
|
403
|
+
trace "keyword map is: %s" % [buf]
|
404
|
+
|
405
|
+
files_needing_fixups = paths.find_all do |path|
|
406
|
+
(kwmap[path.to_s] & DEFAULT_KEYWORDS) != DEFAULT_KEYWORDS
|
407
|
+
end
|
408
|
+
|
409
|
+
unless files_needing_fixups.empty?
|
410
|
+
$deferr.puts "Files needing keyword fixes: ",
|
411
|
+
files_needing_fixups.collect {|f|
|
412
|
+
" %s: %s" % [f, kwmap[f] ? kwmap[f].join(' ') : "(no keywords)"]
|
413
|
+
}
|
414
|
+
ask_for_confirmation( "Will add default keywords to these files." ) do
|
415
|
+
run 'svn', 'ps', 'svn:keywords', DEFAULT_KEYWORDS.join(' '), *files_needing_fixups
|
416
|
+
end
|
417
|
+
else
|
418
|
+
log "Keywords are all up to date."
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
|
423
|
+
task :debug_helpers do
|
424
|
+
methods = [
|
425
|
+
:make_new_tag,
|
426
|
+
:get_svn_info,
|
427
|
+
:get_svn_repo_root,
|
428
|
+
:get_svn_url,
|
429
|
+
:get_svn_path,
|
430
|
+
:svn_ls,
|
431
|
+
:get_latest_svn_timestamp_tag,
|
432
|
+
]
|
433
|
+
maxlen = methods.collect {|sym| sym.to_s.length }.max
|
434
|
+
|
435
|
+
methods.each do |meth|
|
436
|
+
res = send( meth )
|
437
|
+
puts "%*s => %p" % [ maxlen, colorize(meth.to_s, :cyan), res ]
|
438
|
+
end
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
data/rake/testing.rb
ADDED
@@ -0,0 +1,191 @@
|
|
1
|
+
#
|
2
|
+
# Rake tasklib for testing tasks
|
3
|
+
# $Id: testing.rb 14 2008-07-23 23:16:30Z deveiant $
|
4
|
+
#
|
5
|
+
# Authors:
|
6
|
+
# * Michael Granger <ged@FaerieMUD.org>
|
7
|
+
#
|
8
|
+
|
9
|
+
COVERAGE_MINIMUM = 85.0 unless defined?( COVERAGE_MINIMUM )
|
10
|
+
SPEC_FILES = [] unless defined?( SPEC_FILES )
|
11
|
+
TEST_FILES = [] unless defined?( TEST_FILES )
|
12
|
+
|
13
|
+
COMMON_SPEC_OPTS = ['-c', '-f', 's'] unless defined?( COMMON_SPEC_OPTS )
|
14
|
+
|
15
|
+
COVERAGE_TARGETDIR = BASEDIR + 'coverage' unless defined?( COVERAGE_TARGETDIR )
|
16
|
+
RCOV_EXCLUDES = 'spec,tests,/Library/Ruby,/var/lib,/usr/local/lib' unless
|
17
|
+
defined?( RCOV_EXCLUDES )
|
18
|
+
|
19
|
+
|
20
|
+
desc "Run all defined tests"
|
21
|
+
task :test do
|
22
|
+
unless SPEC_FILES.empty?
|
23
|
+
log "Running specs"
|
24
|
+
Rake::Task['spec:quiet'].invoke
|
25
|
+
end
|
26
|
+
|
27
|
+
unless TEST_FILES.empty?
|
28
|
+
log "Running unit tests"
|
29
|
+
Rake::Task[:unittests].invoke
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
### RSpec specifications
|
35
|
+
begin
|
36
|
+
gem 'rspec', '>= 1.1.3'
|
37
|
+
require 'spec/rake/spectask'
|
38
|
+
|
39
|
+
### Task: spec
|
40
|
+
Spec::Rake::SpecTask.new( :spec ) do |task|
|
41
|
+
task.spec_files = SPEC_FILES
|
42
|
+
task.libs += [LIBDIR]
|
43
|
+
task.spec_opts = COMMON_SPEC_OPTS
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
namespace :spec do
|
48
|
+
desc "Run rspec every time there's a change to one of the files"
|
49
|
+
task :autotest do
|
50
|
+
require 'autotest/rspec'
|
51
|
+
|
52
|
+
autotester = Autotest::Rspec.new
|
53
|
+
autotester.exceptions = %r{\.svn|\.skel}
|
54
|
+
autotester.run
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
desc "Generate quiet output"
|
59
|
+
Spec::Rake::SpecTask.new( :quiet ) do |task|
|
60
|
+
task.spec_files = SPEC_FILES
|
61
|
+
task.spec_opts = ['-f', 'p', '-D']
|
62
|
+
end
|
63
|
+
|
64
|
+
desc "Generate HTML output for a spec run"
|
65
|
+
Spec::Rake::SpecTask.new( :html ) do |task|
|
66
|
+
task.spec_files = SPEC_FILES
|
67
|
+
task.spec_opts = ['-f','h', '-D']
|
68
|
+
end
|
69
|
+
|
70
|
+
desc "Generate plain-text output for a CruiseControl.rb build"
|
71
|
+
Spec::Rake::SpecTask.new( :text ) do |task|
|
72
|
+
task.spec_files = SPEC_FILES
|
73
|
+
task.spec_opts = ['-f','p']
|
74
|
+
end
|
75
|
+
end
|
76
|
+
rescue LoadError => err
|
77
|
+
task :no_rspec do
|
78
|
+
$stderr.puts "Specification tasks not defined: %s" % [ err.message ]
|
79
|
+
end
|
80
|
+
|
81
|
+
task :spec => :no_rspec
|
82
|
+
namespace :spec do
|
83
|
+
task :autotest => :no_rspec
|
84
|
+
task :quiet => :no_rspec
|
85
|
+
task :html => :no_rspec
|
86
|
+
task :text => :no_rspec
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
### Test::Unit tests
|
92
|
+
begin
|
93
|
+
require 'rake/testtask'
|
94
|
+
|
95
|
+
Rake::TestTask.new( :unittests ) do |task|
|
96
|
+
task.libs += [LIBDIR]
|
97
|
+
task.test_files = TEST_FILES
|
98
|
+
task.verbose = true
|
99
|
+
end
|
100
|
+
|
101
|
+
rescue LoadError => err
|
102
|
+
task :no_test do
|
103
|
+
$stderr.puts "Test tasks not defined: %s" % [ err.message ]
|
104
|
+
end
|
105
|
+
|
106
|
+
task :unittests => :no_rspec
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
### RCov (via RSpec) tasks
|
111
|
+
begin
|
112
|
+
gem 'rcov'
|
113
|
+
gem 'rspec', '>= 1.1.3'
|
114
|
+
|
115
|
+
### Task: coverage (via RCov)
|
116
|
+
### Task: rcov
|
117
|
+
desc "Build test coverage reports"
|
118
|
+
unless SPEC_FILES.empty?
|
119
|
+
Spec::Rake::SpecTask.new( :coverage ) do |task|
|
120
|
+
task.spec_files = SPEC_FILES
|
121
|
+
task.libs += [LIBDIR]
|
122
|
+
task.spec_opts = ['-f', 'p', '-b']
|
123
|
+
task.rcov_opts = RCOV_OPTS
|
124
|
+
task.rcov = true
|
125
|
+
end
|
126
|
+
end
|
127
|
+
unless TEST_FILES.empty?
|
128
|
+
require 'rcov/rcovtask'
|
129
|
+
|
130
|
+
Rcov::RcovTask.new do |task|
|
131
|
+
task.libs += [LIBDIR]
|
132
|
+
task.test_files = TEST_FILES
|
133
|
+
task.verbose = true
|
134
|
+
task.rcov_opts = RCOV_OPTS
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
task :rcov => [:coverage] do; end
|
140
|
+
|
141
|
+
### Other coverage tasks
|
142
|
+
namespace :coverage do
|
143
|
+
desc "Generate a detailed text coverage report"
|
144
|
+
Spec::Rake::SpecTask.new( :text ) do |task|
|
145
|
+
task.spec_files = SPEC_FILES
|
146
|
+
task.rcov_opts = RCOV_OPTS + ['--text-report']
|
147
|
+
task.rcov = true
|
148
|
+
end
|
149
|
+
|
150
|
+
desc "Show differences in coverage from last run"
|
151
|
+
Spec::Rake::SpecTask.new( :diff ) do |task|
|
152
|
+
task.spec_files = SPEC_FILES
|
153
|
+
task.rcov_opts = ['--text-coverage-diff']
|
154
|
+
task.rcov = true
|
155
|
+
end
|
156
|
+
|
157
|
+
### Task: verify coverage
|
158
|
+
desc "Build coverage statistics"
|
159
|
+
VerifyTask.new( :verify => :rcov ) do |task|
|
160
|
+
task.threshold = COVERAGE_MINIMUM
|
161
|
+
end
|
162
|
+
|
163
|
+
desc "Run RCov in 'spec-only' mode to check coverage from specs"
|
164
|
+
Spec::Rake::SpecTask.new( :speconly ) do |task|
|
165
|
+
task.spec_files = SPEC_FILES
|
166
|
+
task.rcov_opts = ['--exclude', RCOV_EXCLUDES, '--text-report', '--save']
|
167
|
+
task.rcov = true
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
task :clobber_coverage do
|
172
|
+
rmtree( COVERAGE_TARGETDIR )
|
173
|
+
end
|
174
|
+
|
175
|
+
rescue LoadError => err
|
176
|
+
task :no_rcov do
|
177
|
+
$stderr.puts "Coverage tasks not defined: RSpec+RCov tasklib not available: %s" %
|
178
|
+
[ err.message ]
|
179
|
+
end
|
180
|
+
|
181
|
+
task :coverage => :no_rcov
|
182
|
+
task :clobber_coverage
|
183
|
+
task :rcov => :no_rcov
|
184
|
+
namespace :coverage do
|
185
|
+
task :text => :no_rcov
|
186
|
+
task :diff => :no_rcov
|
187
|
+
end
|
188
|
+
task :verify => :no_rcov
|
189
|
+
end
|
190
|
+
|
191
|
+
|