WebKitTools:
[WebKit-https.git] / WebKitTools / Scripts / svn-apply
index f96d7b38c38257ef0eb1135ae007f8ce00c3a52c..299d70e36bd4ee32438a614988c29477aa10fb87 100755 (executable)
 #       makes patches generated by "cvs diff" work (increasingly unimportant since we
 #       use Subversion now).
 #   ChangeLog patches use --fuzz=3 to prevent rejects.
+#   Handles binary files (requires patches made by svn-create-patch).
 #
 # Missing features:
 #
 #   Handle property changes.
-#   Handle binary files (requires patches made by svn-create-patch).
 #   Handle file moves (requires patches made by svn-create-patch).
 #   When doing a removal, check that old file matches what's being removed.
 #   Notice a patch that's being applied at the "wrong level" and make it work anyway.
@@ -52,6 +52,7 @@
 use strict;
 use Cwd;
 use Getopt::Long;
+use MIME::Base64;
 
 my $merge = 0;
 GetOptions("merge" => \$merge); 
@@ -127,42 +128,46 @@ sub patch
 
     my $deletion = 0;
     my $addition = 0;
+    my $isBinary = 0;
 
     $addition = 1 if $patch =~ /\n--- .+\(revision 0\)\n/;
     $deletion = 1 if $patch =~ /\n@@ .* \+0,0 @@/;
+    $isBinary = 1 if $patch =~ /\nCannot display: file marked as a binary type\./;
 
-    if (!$addition && !$deletion) {
+    if (!$addition && !$deletion && !$isBinary) {
         # Standard patch, patch tool can handle this.
         if ($base eq "ChangeLog") {
             my $changeLogDotOrigExisted = -f "${fullpath}.orig";
             applyPatch($patch, $fullpath, ["--fuzz=3"]);
             unlink("${fullpath}.orig") if (! $changeLogDotOrigExisted);
-        }
-        else {
+        } else {
             applyPatch($patch, $fullpath);
         }
     } else {
-        # Either a deletion or an addition.
+        # Either a deletion, an addition or a binary change.
 
         # Change directory down into the directory in question.
         chdirAddingDirectoriesIfNeeded($prefix);
 
-        if ($deletion) {
+        if ($isBinary) {
+            # Binary change
+            handleBinaryChange($base, $patch);
+        } elsif ($deletion) {
             # Deletion.
             system "svn", "rm", $base;
         } else {
             # Addition.
-            my $file = $patch;
-            if ($file !~ s/^(.*\n)*@@[^\n]+@@\n//) {
-                # Empty file.
-                $file = "";
+            my $contents = $patch;
+            if ($contents !~ s/^(.*\n)*@@[^\n]+@@\n//) {
+                # Empty contents.
+                $contents = "";
             } else {
-                # Non-empty file: Remove leading + signs.
-                $file =~ s/^\+//;
-                $file =~ s/\n\+/\n/g;
+                # Non-empty contents: Remove leading + signs.
+                $contents =~ s/^\+//;
+                $contents =~ s/\n\+/\n/g;
             }
             open FILE, ">", $base or die;
-            print FILE $file;
+            print FILE $contents;
             close FILE;
             system "svn", "add", "$base";
         }
@@ -171,6 +176,30 @@ sub patch
     }
 }
 
+sub handleBinaryChange
+{
+    my ($base, $contents) = @_;
+    if ($contents =~ m#((\n[A-Za-z0-9+/]{76})+\n[A-Za-z0-9+/=]{4,76}\n)\n#) {
+        # Addition or Modification
+        open FILE, ">", $base or die;
+        print FILE decode_base64($1);
+        close FILE;
+        open SVN, "svn stat '$base' |" or die;
+        my $svnStatus = <SVN>;
+        close SVN;
+        if (substr($svnStatus, 0 ,1) eq "?") {
+            # Addition
+            system "svn", "add", "$base";
+        } else {
+            # Modification
+            print $svnStatus;
+        }
+    } else {
+        # Deletion
+        system "svn", "rm", "$base";
+    }
+}
+
 sub chdirAddingDirectoriesIfNeeded
 {
     my $path = shift;