Changeset 50547 in webkit
- Timestamp:
- Nov 4, 2009 11:07:00 PM (14 years ago)
- Location:
- trunk/WebKitTools
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebKitTools/ChangeLog
r50525 r50547 1 2009-11-04 Eric Seidel <eric@webkit.org> 2 3 Reviewed by David Kilzer. 4 5 svn-apply's fixChangeLogPatch function seems broken 6 https://bugs.webkit.org/show_bug.cgi?id=30683 7 8 Update fixChangeLogPatch to be able to handle patches which 9 don't start at line 1. 10 Add unit tests for svn-apply to scm_unittest.py. 11 12 * Scripts/VCSUtils.pm: 13 * Scripts/modules/scm_unittest.py: 14 1 15 2009-11-04 Chris Fleizach <cfleizach@apple.com> 2 16 -
trunk/WebKitTools/Scripts/VCSUtils.pm
r50318 r50547 356 356 } 357 357 358 # The diff(1) command is greedy when matching lines, so a new ChangeLog entry will 359 # have lines of context at the top of a patch when the existing entry has the same 360 # date and author as the new entry. Alter the ChangeLog patch so 361 # that the added lines ("+") in the patch always start at the beginning of the 362 # patch and there are no initial lines of context. 358 363 sub fixChangeLogPatch($) 359 364 { 360 my $patch = shift; 361 my $contextLineCount = 3; 362 363 return $patch if $patch !~ /\n@@ -1,(\d+) \+1,(\d+) @@\n( .*\n)+(\+.*\n)+( .*\n){$contextLineCount}$/m; 364 my ($oldLineCount, $newLineCount) = ($1, $2); 365 return $patch if $oldLineCount <= $contextLineCount; 366 367 # The diff(1) command is greedy when matching lines, so a new ChangeLog entry will 368 # have lines of context at the top of a patch when the existing entry has the same 369 # date and author as the new entry. This nifty loop alters a ChangeLog patch so 370 # that the added lines ("+") in the patch always start at the beginning of the 371 # patch and there are no initial lines of context. 372 my $newPatch; 373 my $lineCountInState = 0; 374 my $oldContentLineCountReduction = $oldLineCount - $contextLineCount; 375 my $newContentLineCountWithoutContext = $newLineCount - $oldLineCount - $oldContentLineCountReduction; 376 my ($stateHeader, $statePreContext, $stateNewChanges, $statePostContext) = (1..4); 377 my $state = $stateHeader; 378 foreach my $line (split(/\n/, $patch)) { 379 $lineCountInState++; 380 if ($state == $stateHeader && $line =~ /^@@ -1,$oldLineCount \+1,$newLineCount @\@$/) { 381 $line = "@@ -1,$contextLineCount +1," . ($newLineCount - $oldContentLineCountReduction) . " @@"; 382 $lineCountInState = 0; 383 $state = $statePreContext; 384 } elsif ($state == $statePreContext && substr($line, 0, 1) eq " ") { 385 $line = "+" . substr($line, 1); 386 if ($lineCountInState == $oldContentLineCountReduction) { 387 $lineCountInState = 0; 388 $state = $stateNewChanges; 365 my $patch = shift; # $patch will only contain patch fragments for ChangeLog. 366 367 $patch =~ /(\r?\n)/; 368 my $lineEnding = $1; 369 my @patchLines = split(/$lineEnding/, $patch); 370 371 # e.g. 2009-06-03 Eric Seidel <eric@webkit.org> 372 my $dateLineRegexpString = '^\+(\d{4}-\d{2}-\d{2})' # Consume the leading '+' and the date. 373 . '\s+(.+)\s+' # Consume the name. 374 . '<([^<>]+)>$'; # And finally the email address. 375 376 # Figure out where the patch contents start and stop. 377 my $patchHeaderIndex; 378 my $firstContentIndex; 379 my $trailingContextIndex; 380 my $dateIndex; 381 my $patchEndIndex = scalar(@patchLines); 382 for (my $index = 0; $index < @patchLines; ++$index) { 383 my $line = $patchLines[$index]; 384 if ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@$/) { # e.g. @@ -1,5 +1,18 @@ 385 if ($patchHeaderIndex) { 386 $patchEndIndex = $index; # We only bother to fix up the first patch fragment. 387 last; 389 388 } 390 } elsif ($state == $stateNewChanges && substr($line, 0, 1) eq "+") { 391 # No changes to these lines 392 if ($lineCountInState == $newContentLineCountWithoutContext) { 393 $lineCountInState = 0; 394 $state = $statePostContext; 395 } 396 } elsif ($state == $statePostContext) { 397 if (substr($line, 0, 1) eq "+" && $lineCountInState <= $oldContentLineCountReduction) { 398 $line = " " . substr($line, 1); 399 } elsif ($lineCountInState > $contextLineCount && substr($line, 0, 1) eq " ") { 400 next; # Discard 401 } 389 $patchHeaderIndex = $index; 402 390 } 403 $newPatch .= $line . "\n"; 404 } 405 406 return $newPatch; 407 } 408 391 $firstContentIndex = $index if ($patchHeaderIndex && !$firstContentIndex && $line =~ /^\+[^+]/); # Only match after finding patchHeaderIndex, otherwise we'd match "+++". 392 $dateIndex = $index if ($line =~ /$dateLineRegexpString/); 393 $trailingContextIndex = $index if ($firstContentIndex && !$trailingContextIndex && $line =~ /^ /); 394 } 395 my $contentLineCount = $trailingContextIndex - $firstContentIndex; 396 my $trailingContextLineCount = $patchEndIndex - $trailingContextIndex; 397 398 # If we didn't find a date line in the content then this is not a patch we should try and fix. 399 return $patch if (!$dateIndex); 400 401 # We only need to do anything if the date line is not the first content line. 402 return $patch if ($dateIndex == $firstContentIndex); 403 404 # Write the new patch. 405 my $totalNewContentLines = $contentLineCount + $trailingContextLineCount; 406 $patchLines[$patchHeaderIndex] = "@@ -1,$trailingContextLineCount +1,$totalNewContentLines @@"; # Write a new header. 407 my @repeatedLines = splice(@patchLines, $dateIndex, $trailingContextIndex - $dateIndex); # The date line and all the content after it that diff saw as repeated. 408 splice(@patchLines, $firstContentIndex, 0, @repeatedLines); # Move the repeated content to the top. 409 foreach my $line (@repeatedLines) { 410 $line =~ s/^\+/ /; 411 } 412 splice(@patchLines, $trailingContextIndex, $patchEndIndex, @repeatedLines); # Replace trailing context with the repeated content. 413 splice(@patchLines, $patchHeaderIndex + 1, $firstContentIndex - $patchHeaderIndex - 1); # Remove any leading context. 414 415 return join($lineEnding, @patchLines) . "\n"; # patch(1) expects an extra trailing newline. 416 } 409 417 410 418 1; -
trunk/WebKitTools/Scripts/modules/scm_unittest.py
r49931 r50547 36 36 import unittest 37 37 import urllib 38 39 from datetime import date 38 40 from modules.scm import detect_scm_system, SCM, ScriptError, CheckoutNeedsUpdate, ignore_error, commit_error_handler 39 41 … … 205 207 class SVNTest(SCMTest): 206 208 209 @staticmethod 210 def _set_date_and_reviewer(changelog_entry): 211 # Joe Cool matches the reviewer set in SCMTest._create_patch 212 changelog_entry = changelog_entry.replace('REVIEWER_HERE', 'Joe Cool') 213 # svn-apply will update ChangeLog entries with today's date. 214 return changelog_entry.replace('DATE_HERE', date.today().isoformat()) 215 216 def test_svn_apply(self): 217 first_entry = """2009-10-26 Eric Seidel <eric@webkit.org> 218 219 Reviewed by Foo Bar. 220 221 Most awesome change ever. 222 223 * scm_unittest.py: 224 """ 225 intermediate_entry = """2009-10-27 Eric Seidel <eric@webkit.org> 226 227 Reviewed by Baz Bar. 228 229 A more awesomer change yet! 230 231 * scm_unittest.py: 232 """ 233 one_line_overlap_patch = """Index: ChangeLog 234 =================================================================== 235 --- ChangeLog (revision 5) 236 +++ ChangeLog (working copy) 237 @@ -1,5 +1,13 @@ 238 2009-10-26 Eric Seidel <eric@webkit.org> 239 240 + Reviewed by NOBODY (OOPS!). 241 + 242 + Second most awsome change ever. 243 + 244 + * scm_unittest.py: 245 + 246 +2009-10-26 Eric Seidel <eric@webkit.org> 247 + 248 Reviewed by Foo Bar. 249 250 Most awesome change ever. 251 """ 252 one_line_overlap_entry = """DATE_HERE Eric Seidel <eric@webkit.org> 253 254 Reviewed by REVIEWER_HERE. 255 256 Second most awsome change ever. 257 258 * scm_unittest.py: 259 """ 260 two_line_overlap_patch = """Index: ChangeLog 261 =================================================================== 262 --- ChangeLog (revision 5) 263 +++ ChangeLog (working copy) 264 @@ -2,6 +2,14 @@ 265 266 Reviewed by Foo Bar. 267 268 + Second most awsome change ever. 269 + 270 + * scm_unittest.py: 271 + 272 +2009-10-26 Eric Seidel <eric@webkit.org> 273 + 274 + Reviewed by Foo Bar. 275 + 276 Most awesome change ever. 277 278 * scm_unittest.py: 279 """ 280 two_line_overlap_entry = """DATE_HERE Eric Seidel <eric@webkit.org> 281 282 Reviewed by Foo Bar. 283 284 Second most awsome change ever. 285 286 * scm_unittest.py: 287 """ 288 write_into_file_at_path('ChangeLog', first_entry) 289 run(['svn', 'add', 'ChangeLog']) 290 run(['svn', 'commit', '--quiet', '--message', 'ChangeLog commit']) 291 292 # Patch files were created against just 'first_entry'. 293 # Add a second commit to make svn-apply have to apply the patches with fuzz. 294 changelog_contents = "%s\n%s" % (intermediate_entry, first_entry) 295 write_into_file_at_path('ChangeLog', changelog_contents) 296 run(['svn', 'commit', '--quiet', '--message', 'Intermediate commit']) 297 298 self._setup_webkittools_scripts_symlink(self.scm) 299 self.scm.apply_patch(self._create_patch(one_line_overlap_patch)) 300 expected_changelog_contents = "%s\n%s" % (self._set_date_and_reviewer(one_line_overlap_entry), changelog_contents) 301 self.assertEquals(read_from_path('ChangeLog'), expected_changelog_contents) 302 303 self.scm.revert_files(['ChangeLog']) 304 self.scm.apply_patch(self._create_patch(two_line_overlap_patch)) 305 expected_changelog_contents = "%s\n%s" % (self._set_date_and_reviewer(two_line_overlap_entry), changelog_contents) 306 self.assertEquals(read_from_path('ChangeLog'), expected_changelog_contents) 307 207 308 def setUp(self): 208 309 SVNTestRepository.setup(self)
Note: See TracChangeset
for help on using the changeset viewer.