linkparser 1.0.3

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