Changeset 57440 in webkit


Ignore:
Timestamp:
Apr 10, 2010 10:46:17 PM (14 years ago)
Author:
eric@webkit.org
Message:

2010-04-10 Daniel Bates <dbates@rim.com>

Reviewed by Eric Seidel.

https://bugs.webkit.org/show_bug.cgi?id=27204

Implement support for changing the executable bit of a file.
The executable bit is among the most changed file properties.
Future support can include other property changes.

Currently, if a patch changes the executable bit of a file
it is not respected by svn-apply or svn-unapply. Since the
commit-queue bot uses these tools as part of its workflow,
such patches cannot be committed by it. That is, such patches
need to be committed by hand. Instead, we should add support
for the executable bit so that such patches can be committed
by the commit-queue bot.

  • Scripts/VCSUtils.pm: Also change reference to Apple Computer, Inc. in copyright to Apple, Inc.
  • Scripts/svn-apply:
  • Scripts/svn-unapply:
  • Scripts/webkitperl/VCSUtils_unittest/appendSVNExecutableBitChangeToPatch.pl: Added.
  • Scripts/webkitperl/VCSUtils_unittest/parseGitFileMode.pl: Added.
  • Scripts/webkitperl/VCSUtils_unittest/parseStartOfPatchOrPropertyChangeAndEndOfPropertyChange.pl: Added.
Location:
trunk/WebKitTools
Files:
3 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebKitTools/ChangeLog

    r57439 r57440  
     12010-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
    1272010-04-10  Eric Seidel  <eric@webkit.org>
    228
  • trunk/WebKitTools/Scripts/VCSUtils.pm

    r56472 r57440  
    11# Copyright (C) 2007, 2008, 2009 Apple Inc.  All rights reserved.
    22# Copyright (C) 2009, 2010 Chris Jerdonek (chris.jerdonek@gmail.com)
     3# Copyright (C) Research in Motion Limited 2010. All rights reserved.
    34#
    45# Redistribution and use in source and binary forms, with or without
     
    1112#     notice, this list of conditions and the following disclaimer in the
    1213#     documentation and/or other materials provided with the distribution.
    13 # 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     14# 3.  Neither the name of Apple Inc. ("Apple") nor the names of
    1415#     its contributors may be used to endorse or promote products derived
    1516#     from this software without specific prior written permission.
     
    4445    @ISA         = qw(Exporter);
    4546    @EXPORT      = qw(
     47        &appendSVNExecutableBitChangeToPatch
    4648        &canonicalizePath
    4749        &changeLogEmailAddress
     
    5557        &gitBranch
    5658        &gitdiff2svndiff
     59        &isEndOfPropertyChange
    5760        &isGit
    5861        &isGitBranchBuild
     
    6063        &isSVN
    6164        &isSVNDirectory
     65        &isSVNProperty
    6266        &isSVNVersion16OrNewer
    6367        &makeFilePathRelative
    6468        &mergeChangeLogs
    6569        &normalizePath
     70        &parseGitFileMode
    6671        &parsePatch
     72        &parsePropertyChange
     73        &parseStartOfPatch
    6774        &pathRelativeToSVNRepositoryRootForPath
    6875        &runPatchCommand
     76        &scmAddExecutableProperty
     77        &scmRemoveExecutableProperty
    6978        &svnRevisionForDirectory
    7079        &svnStatus
     80        &togglePropertyChange
    7181    );
    7282    %EXPORT_TAGS = ( );
     
    109119    $isGit = isGitDirectory(".");
    110120    return $isGit;
     121}
     122
     123sub parseGitFileMode($)
     124{
     125    my ($patch) = @_;
     126    return ($patch =~ /^new (file )?mode ([0-9]{6})$/) ? $2 : 0;
     127}
     128
     129sub 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
     136sub parseStartOfPatch($)
     137{
     138    my ($patch) = @_;
     139    return $1 if ($patch =~ /^Index: ([^\r\n]+)/);
     140    return 0;
     141}
     142
     143sub parsePropertyChange($)
     144{
     145    my ($patch) = @_;
     146    return $1 if ($patch =~ /^Property changes on: ([^\r\n]+)/);
     147    return 0;
     148}
     149
     150sub isEndOfPropertyChange($$)
     151{
     152    my ($patch, $propertyChangePath) = @_;
     153    return ($propertyChangePath && $patch =~ /^   (\+|-) \*$/);
     154}
     155
     156sub 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
     175sub 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
     188sub 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
     198sub 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    }
    111206}
    112207
  • trunk/WebKitTools/Scripts/svn-apply

    r52739 r57440  
    5151# Missing features:
    5252#
    53 #   Handle property changes.
     53#   Handle property changes other than the executable bit.
    5454#   Handle copied and moved directories (would require patches made by svn-create-patch).
    5555#   When doing a removal, check that old file matches what's being removed.
     
    131131my $indexPath;
    132132my $patch;
     133my $propertyChangePath;
     134my $isGitFormattedPatch = 0;
    133135while (<>) {
    134136    s/([\n\r]+)$//mg;
     
    136138    if (!defined($indexPath) && m#^diff --git \w/#) {
    137139        $filter = \&gitdiff2svndiff;
     140        $isGitFormattedPatch = 1;
    138141    }
    139142    $_ = &$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 = "";
    149151    }
    150152    if ($indexPath) {
     
    152154        s/\S+$/$indexPath/ if /^diff/;
    153155        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
    154164        if (/^--- .+\(from (\S+):(\d+)\)$/) {
    155165            $copiedFromPath = $1;
     
    164174        }
    165175    }
     176    $propertyChangePath = "" if isEndOfPropertyChange($_, $propertyChangePath);
    166177    $patch .= $_;
    167178    $patch .= $eol;
     
    331342    return if !$patch;
    332343
    333     unless ($patch =~ m|^Index: ([^\r\n]+)|) {
     344    unless ($patch =~ m|^Index: ([^\r\n]+)| || $patch =~ m|^Property changes on: ([^\r\n]+)|) {
    334345        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";
    336347        die unless $force;
    337348        return;
     
    343354    my $isBinary = 0;
    344355    my $isGitBinary = 0;
     356    my $isSVNPropertyChange = 0;
    345357
    346358    $addition = 1 if ($patch =~ /\n--- .+\(revision 0\)\r?\n/ || $patch =~ /\n@@ -0,0 .* @@/) && !exists($copiedFiles{$fullPath});
     
    348360    $isBinary = 1 if $patch =~ /\nCannot display: file marked as a binary type\./;
    349361    $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) {
    352365        # Standard patch, patch tool can handle this.
    353366        if (basename($fullPath) eq "ChangeLog") {
     
    373386            applyPatch($patch, $fullPath, ["--force"]);
    374387            scmRemove($fullPath);
     388        } elsif ($isSVNPropertyChange) {
     389            # Change executable bit.
     390            togglePropertyChange($patch, $fullPath);
    375391        } else {
    376392            # Addition
  • trunk/WebKitTools/Scripts/svn-unapply

    r52739 r57440  
    4848# Missing features:
    4949#
    50 #   Handle property changes.
     50#   Handle property changes other than the executable bit.
    5151#   Handle copied and moved directories (would require patches made by svn-create-patch).
    5252#   Use version numbers in the patch file and do a 3-way merge.
     
    102102my $indexPath;
    103103my $patch;
     104my $propertyChangePath;
     105my $isGitFormattedPatch = 0;
    104106while (<>) {
    105107    s/([\n\r]+)$//mg;
     
    109111    }
    110112    $_ = &$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 = "";
    122123    }
    123124    if ($indexPath) {
    124125        # Fix paths on diff, ---, and +++ lines to match preceding Index: line.
    125126        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
    126135        if (/^--- .+\(from (\S+):\d+\)$/) {
    127136            $copiedFromPath = $1;
     
    131140        }
    132141    }
     142    $propertyChangePath = "" if isEndOfPropertyChange($_, $propertyChangePath);
    133143    $patch .= $_;
    134144    $patch .= $eol;
     
    169179    return if !$patch;
    170180
    171     unless ($patch =~ m|^Index: ([^\r\n]+)|) {
     181    my $fullPath;
     182    unless ($fullPath = parseStartOfPatch($patch) || parsePropertyChange($patch)) {
    172183        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";
    174185        return;
    175186    }
    176     my $fullPath = $1;
    177187    $directoriesToCheck{dirname($fullPath)} = 1;
    178188
     
    180190    my $addition = 0;
    181191    my $isBinary = 0;
     192    my $isSVNPropertyChange = 0;
    182193
    183194    $addition = 1 if ($patch =~ /\n--- .+\(revision 0\)\n/ || $patch =~ /\n@@ -0,0 .* @@/);
    184195    $deletion = 1 if $patch =~ /\n@@ .* \+0,0 @@/;
    185196    $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) {
    188200        # Standard patch, patch tool can handle this.
    189201        if (basename($fullPath) eq "ChangeLog") {
     
    227239            # Show status if the file is modifed
    228240            system "svn", "stat", $fullPath;
     241        } elsif ($isSVNPropertyChange) {
     242            # Reverse change of executable bit.
     243            togglePropertyChange($patch, $fullPath, 1);
    229244        } else {
    230245            # Reverse addition
Note: See TracChangeset for help on using the changeset viewer.