Changeset 57440 in webkit
- Timestamp:
- Apr 10, 2010 10:46:17 PM (14 years ago)
- Location:
- trunk/WebKitTools
- Files:
-
- 3 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebKitTools/ChangeLog
r57439 r57440 1 2010-04-10 Daniel Bates <dbates@rim.com> 2 3 Reviewed by Eric Seidel. 4 5 https://bugs.webkit.org/show_bug.cgi?id=27204 6 7 Implement support for changing the executable bit of a file. 8 The executable bit is among the most changed file properties. 9 Future support can include other property changes. 10 11 Currently, if a patch changes the executable bit of a file 12 it is not respected by svn-apply or svn-unapply. Since the 13 commit-queue bot uses these tools as part of its workflow, 14 such patches cannot be committed by it. That is, such patches 15 need to be committed by hand. Instead, we should add support 16 for the executable bit so that such patches can be committed 17 by the commit-queue bot. 18 19 * Scripts/VCSUtils.pm: Also change reference to Apple Computer, Inc. 20 in copyright to Apple, Inc. 21 * Scripts/svn-apply: 22 * Scripts/svn-unapply: 23 * Scripts/webkitperl/VCSUtils_unittest/appendSVNExecutableBitChangeToPatch.pl: Added. 24 * Scripts/webkitperl/VCSUtils_unittest/parseGitFileMode.pl: Added. 25 * Scripts/webkitperl/VCSUtils_unittest/parseStartOfPatchOrPropertyChangeAndEndOfPropertyChange.pl: Added. 26 1 27 2010-04-10 Eric Seidel <eric@webkit.org> 2 28 -
trunk/WebKitTools/Scripts/VCSUtils.pm
r56472 r57440 1 1 # Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. 2 2 # Copyright (C) 2009, 2010 Chris Jerdonek (chris.jerdonek@gmail.com) 3 # Copyright (C) Research in Motion Limited 2010. All rights reserved. 3 4 # 4 5 # Redistribution and use in source and binary forms, with or without … … 11 12 # notice, this list of conditions and the following disclaimer in the 12 13 # documentation and/or other materials provided with the distribution. 13 # 3. Neither the name of Apple Computer,Inc. ("Apple") nor the names of14 # 3. Neither the name of Apple Inc. ("Apple") nor the names of 14 15 # its contributors may be used to endorse or promote products derived 15 16 # from this software without specific prior written permission. … … 44 45 @ISA = qw(Exporter); 45 46 @EXPORT = qw( 47 &appendSVNExecutableBitChangeToPatch 46 48 &canonicalizePath 47 49 &changeLogEmailAddress … … 55 57 &gitBranch 56 58 &gitdiff2svndiff 59 &isEndOfPropertyChange 57 60 &isGit 58 61 &isGitBranchBuild … … 60 63 &isSVN 61 64 &isSVNDirectory 65 &isSVNProperty 62 66 &isSVNVersion16OrNewer 63 67 &makeFilePathRelative 64 68 &mergeChangeLogs 65 69 &normalizePath 70 &parseGitFileMode 66 71 &parsePatch 72 &parsePropertyChange 73 &parseStartOfPatch 67 74 &pathRelativeToSVNRepositoryRootForPath 68 75 &runPatchCommand 76 &scmAddExecutableProperty 77 &scmRemoveExecutableProperty 69 78 &svnRevisionForDirectory 70 79 &svnStatus 80 &togglePropertyChange 71 81 ); 72 82 %EXPORT_TAGS = ( ); … … 109 119 $isGit = isGitDirectory("."); 110 120 return $isGit; 121 } 122 123 sub parseGitFileMode($) 124 { 125 my ($patch) = @_; 126 return ($patch =~ /^new (file )?mode ([0-9]{6})$/) ? $2 : 0; 127 } 128 129 sub isSVNProperty($) 130 { 131 my ($patch) = @_; 132 # FIXME: We should make this more generic and support additional SVN properties. 133 return $patch =~ /\n(Added|Deleted): svn:executable\n/; 134 } 135 136 sub parseStartOfPatch($) 137 { 138 my ($patch) = @_; 139 return $1 if ($patch =~ /^Index: ([^\r\n]+)/); 140 return 0; 141 } 142 143 sub parsePropertyChange($) 144 { 145 my ($patch) = @_; 146 return $1 if ($patch =~ /^Property changes on: ([^\r\n]+)/); 147 return 0; 148 } 149 150 sub isEndOfPropertyChange($$) 151 { 152 my ($patch, $propertyChangePath) = @_; 153 return ($propertyChangePath && $patch =~ /^ (\+|-) \*$/); 154 } 155 156 sub togglePropertyChange 157 { 158 my ($patch, $fullPath, $shouldUnapply) = @_; 159 # Change executable bit. 160 if ($patch =~ /Added: svn:executable\n/) { 161 if (!defined($shouldUnapply)) { 162 scmAddExecutableProperty($fullPath); 163 } else { 164 scmRemoveExecutableProperty($fullPath); 165 } 166 } elsif ($patch =~ /Deleted: svn:executable\n/) { 167 if (!defined($shouldUnapply)) { 168 scmRemoveExecutableProperty($fullPath); 169 } else { 170 scmAddExecutableProperty($fullPath); 171 } 172 } 173 } 174 175 sub appendSVNExecutableBitChangeToPatch($$$) 176 { 177 my ($indexPath, $fileMode, $patchRef) = @_; 178 # Note, we don't need to include either the divider line or the " + *" line, 179 # but these are left in so as to produce a proper SVN property change entry. 180 $$patchRef .= "Property changes on: $indexPath\n"; 181 $$patchRef .= "___________________________________________________________________\n"; 182 # FIXME: These file modes are fragile and based on observation. 183 $$patchRef .= "Added: svn:executable\n" if $fileMode eq "100755"; 184 $$patchRef .= "Deleted: svn:executable\n" if $fileMode eq "100644"; 185 $$patchRef .= " + *\n"; 186 } 187 188 sub scmAddExecutableProperty($) 189 { 190 my ($path) = @_; 191 if (isSVN()) { 192 system("svn", "propset", "svn:executable", "on", $path) == 0 or die "Failed to run 'svn propset svn:executable on $path'."; 193 } elsif (isGit()) { 194 chmod(0755, $path); 195 } 196 } 197 198 sub scmRemoveExecutableProperty($) 199 { 200 my ($path) = @_; 201 if (isSVN()) { 202 system("svn", "propdel", "svn:executable", $path) == 0 or die "Failed to run 'svn propdel svn:executable $path'."; 203 } elsif (isGit()) { 204 chmod(0664, $path); 205 } 111 206 } 112 207 -
trunk/WebKitTools/Scripts/svn-apply
r52739 r57440 51 51 # Missing features: 52 52 # 53 # Handle property changes .53 # Handle property changes other than the executable bit. 54 54 # Handle copied and moved directories (would require patches made by svn-create-patch). 55 55 # When doing a removal, check that old file matches what's being removed. … … 131 131 my $indexPath; 132 132 my $patch; 133 my $propertyChangePath; 134 my $isGitFormattedPatch = 0; 133 135 while (<>) { 134 136 s/([\n\r]+)$//mg; … … 136 138 if (!defined($indexPath) && m#^diff --git \w/#) { 137 139 $filter = \&gitdiff2svndiff; 140 $isGitFormattedPatch = 1; 138 141 } 139 142 $_ = &$filter($_) if $filter; 140 if (/^Index: (.+)/) { 141 $indexPath = $1; 142 if ($patch) { 143 if (!$copiedFromPath) { 144 push @patches, $patch; 145 } 146 $copiedFromPath = ""; 147 $patch = ""; 148 } 143 my $indexPath = parseStartOfPatch($_); 144 my $propertyChangePath = parsePropertyChange($_); 145 if (($indexPath || $propertyChangePath) && $patch) { 146 if (!$copiedFromPath) { 147 push @patches, $patch; 148 } 149 $copiedFromPath = ""; 150 $patch = ""; 149 151 } 150 152 if ($indexPath) { … … 152 154 s/\S+$/$indexPath/ if /^diff/; 153 155 s/^--- \S+/--- $indexPath/; 156 157 if ($isGitFormattedPatch && (my $fileMode = parseGitFileMode($_))) { 158 # The gitdiff2svndiff filter only operates on a single, but the equivalent 159 # property change entry in SVN spans multiple lines which we need to parse. 160 appendSVNExecutableBitChangeToPatch($indexPath, $fileMode, \$patch); 161 next; 162 } 163 154 164 if (/^--- .+\(from (\S+):(\d+)\)$/) { 155 165 $copiedFromPath = $1; … … 164 174 } 165 175 } 176 $propertyChangePath = "" if isEndOfPropertyChange($_, $propertyChangePath); 166 177 $patch .= $_; 167 178 $patch .= $eol; … … 331 342 return if !$patch; 332 343 333 unless ($patch =~ m|^Index: ([^\r\n]+)| ) {344 unless ($patch =~ m|^Index: ([^\r\n]+)| || $patch =~ m|^Property changes on: ([^\r\n]+)|) { 334 345 my $separator = '-' x 67; 335 warn "Failed to find 'Index:' in:\n$separator\n$patch\n$separator\n";346 warn "Failed to find 'Index:' or 'Property changes on:' in:\n$separator\n$patch\n$separator\n"; 336 347 die unless $force; 337 348 return; … … 343 354 my $isBinary = 0; 344 355 my $isGitBinary = 0; 356 my $isSVNPropertyChange = 0; 345 357 346 358 $addition = 1 if ($patch =~ /\n--- .+\(revision 0\)\r?\n/ || $patch =~ /\n@@ -0,0 .* @@/) && !exists($copiedFiles{$fullPath}); … … 348 360 $isBinary = 1 if $patch =~ /\nCannot display: file marked as a binary type\./; 349 361 $isGitBinary = 1 if $patch =~ /\nGIT binary patch\n/; 350 351 if (!$addition && !$deletion && !$isBinary && !$isGitBinary) { 362 $isSVNPropertyChange = isSVNProperty($patch); 363 364 if (!$addition && !$deletion && !$isBinary && !$isGitBinary && !$isSVNPropertyChange) { 352 365 # Standard patch, patch tool can handle this. 353 366 if (basename($fullPath) eq "ChangeLog") { … … 373 386 applyPatch($patch, $fullPath, ["--force"]); 374 387 scmRemove($fullPath); 388 } elsif ($isSVNPropertyChange) { 389 # Change executable bit. 390 togglePropertyChange($patch, $fullPath); 375 391 } else { 376 392 # Addition -
trunk/WebKitTools/Scripts/svn-unapply
r52739 r57440 48 48 # Missing features: 49 49 # 50 # Handle property changes .50 # Handle property changes other than the executable bit. 51 51 # Handle copied and moved directories (would require patches made by svn-create-patch). 52 52 # Use version numbers in the patch file and do a 3-way merge. … … 102 102 my $indexPath; 103 103 my $patch; 104 my $propertyChangePath; 105 my $isGitFormattedPatch = 0; 104 106 while (<>) { 105 107 s/([\n\r]+)$//mg; … … 109 111 } 110 112 $_ = &$filter($_) if $filter; 111 if (/^Index: (.+)/) { 112 $indexPath = $1; 113 if ($patch) { 114 if ($copiedFromPath) { 115 push @copiedFiles, $patch; 116 } else { 117 patch($patch); 118 } 119 $copiedFromPath = ""; 120 $patch = ""; 121 } 113 my $indexPath = parseStartOfPatch($_); 114 my $propertyChangePath = parsePropertyChange($_); 115 if (($indexPath || $propertyChangePath) && $patch) { 116 if ($copiedFromPath) { 117 push @copiedFiles, $patch; 118 } else { 119 patch($patch); 120 } 121 $copiedFromPath = ""; 122 $patch = ""; 122 123 } 123 124 if ($indexPath) { 124 125 # Fix paths on diff, ---, and +++ lines to match preceding Index: line. 125 126 s/^--- \S+/--- $indexPath/; 127 128 if ($isGitFormattedPatch && (my $fileMode = parseGitFileMode($_))) { 129 # The gitdiff2svndiff filter only operates on a single, but the equivalent 130 # property change entry in SVN spans multiple lines which we need to parse. 131 appendSVNExecutableBitChangeToPatch($indexPath, $fileMode, \$patch); 132 next; 133 } 134 126 135 if (/^--- .+\(from (\S+):\d+\)$/) { 127 136 $copiedFromPath = $1; … … 131 140 } 132 141 } 142 $propertyChangePath = "" if isEndOfPropertyChange($_, $propertyChangePath); 133 143 $patch .= $_; 134 144 $patch .= $eol; … … 169 179 return if !$patch; 170 180 171 unless ($patch =~ m|^Index: ([^\r\n]+)|) { 181 my $fullPath; 182 unless ($fullPath = parseStartOfPatch($patch) || parsePropertyChange($patch)) { 172 183 my $separator = '-' x 67; 173 warn "Failed to find 'Index:' in:\n$separator\n$patch\n$separator\n";184 warn "Failed to find 'Index:' or 'Property changes on:' in:\n$separator\n$patch\n$separator\n"; 174 185 return; 175 186 } 176 my $fullPath = $1;177 187 $directoriesToCheck{dirname($fullPath)} = 1; 178 188 … … 180 190 my $addition = 0; 181 191 my $isBinary = 0; 192 my $isSVNPropertyChange = 0; 182 193 183 194 $addition = 1 if ($patch =~ /\n--- .+\(revision 0\)\n/ || $patch =~ /\n@@ -0,0 .* @@/); 184 195 $deletion = 1 if $patch =~ /\n@@ .* \+0,0 @@/; 185 196 $isBinary = 1 if $patch =~ /\nCannot display: file marked as a binary type\./; 186 187 if (!$addition && !$deletion && !$isBinary) { 197 $isSVNPropertyChange = isSVNProperty($patch); 198 199 if (!$addition && !$deletion && !$isBinary && !$isSVNPropertyChange) { 188 200 # Standard patch, patch tool can handle this. 189 201 if (basename($fullPath) eq "ChangeLog") { … … 227 239 # Show status if the file is modifed 228 240 system "svn", "stat", $fullPath; 241 } elsif ($isSVNPropertyChange) { 242 # Reverse change of executable bit. 243 togglePropertyChange($patch, $fullPath, 1); 229 244 } else { 230 245 # Reverse addition
Note: See TracChangeset
for help on using the changeset viewer.