wordnet 0.0.5

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