# New Ticket Created by  David Romano 
# Please include the string:  [perl #44783]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=44783 >


Testing svn file metadata isn't always appropriate when using git. When
git mirrors an svn repo, it can store the metadata for each file in
.git/svn/git-svn/unhandled.log, but sometimes the user chooses not to
store the metadata. If the user does store it, this patch allows for the
tests to pass (and not hang). If the user doesn't have the metadata but
has a .git directory, then the tests are skipped.

- David

-- 
"For the fear of death is indeed the pretence of wisdom, and not real
wisdom, being a pretence of knowing the unknown; and no one knows
whether death, which men in their fear apprehend to be the greatest
evil, may not be the greatest good. Is not this ignorance of a
disgraceful sort, the ignorance which is the conceit that man knows what
he does not know?"
    -- Socrates, The Apology by Plato
diff --git a/t/distro/file_metadata.t b/t/distro/file_metadata.t
index 1833cbe..9a1a29a 100644
--- a/t/distro/file_metadata.t
+++ b/t/distro/file_metadata.t
@@ -34,6 +34,7 @@ Note: These tests would benefit from judicial application of 
Iterators.
 =cut
 
 my $cmd = -d '.svn' ? 'svn' : 'svk';
+my @git_svn_metadata; # set in BEGIN block
 
 # how many files to check at a time. May have to lower this when we run
 # this on systems with finicky command lines.
@@ -60,6 +61,7 @@ TEST_MIME: {
     if (@failed) {
         my $failure = join q{}, "Set $test with:\n",
             map { " $cmd ps $test '$expected' $_;\n" } @failed;
+        $failure = "git svn metadata $test incorrect for @failed" if -d '.git';
         is( $failure, '', $test );
     }
     else {
@@ -92,6 +94,7 @@ KEYWORD_EXP: {
     if (@failed) {
         my $failure = join q{}, "Set $test with:\n",
             map { " $cmd ps $test '$expected' $_;\n" } @failed;
+        $failure = "git svn metadata $test incorrect for @failed" if -d '.git';
         is( $failure, '', $test );
     }
     else {
@@ -140,6 +143,7 @@ NATIVE_EOL_STYLE: {
     if (@failed) {
         my $failure = join q{}, "Set $test with:\n",
             map { " $cmd ps $test '$expected' $_;\n" } @failed;
+        $failure = "git svn metadata $test incorrect for @failed" if -d '.git';
         is( $failure, '', $test_name );
     }
     else {
@@ -171,6 +175,7 @@ LF_EOL_STYLE: {
     if (@failed) {
         my $failure = join q{}, "Set $test with:\n",
             map { " $cmd ps $test '$expected' $_;\n" } @failed;
+        $failure = "git svn metadata $test incorrect for @failed" if -d '.git';
         is( $failure, '', $test_name );
     }
     else {
@@ -217,7 +222,25 @@ COPYRIGHT: {
 =cut
 
 BEGIN {
-    unless ( $Parrot::Revision::current or `svk ls .` ) {
+    if ( -d '.git' ) {
+        my $git_svn_metadata = catfile(qw/.git svn git-svn unhandled.log/);
+        if ( -e  $git_svn_metadata ) {
+            diag 'Checking git svn metadata';
+            plan tests => 4;
+            # Read the file once and store lines
+            if (! open my $git_svn_metadata_fh, '<', $git_svn_metadata ) {
+                diag "trouble opening metadata file: $git_svn_metadata";
+            }
+            else {
+                @git_svn_metadata = <$git_svn_metadata_fh>;
+                close $git_svn_metadata_fh;
+            }
+        }
+        else {
+            plan skip_all => q{git svn file metadata not retained};
+        }
+    }
+    elsif ( !($Parrot::Revision::current or `svk ls .`) ) {
         plan skip_all => 'not a working copy';
     }
     else { plan tests => 4 }
@@ -262,6 +285,10 @@ sub get_attribute {
     my %results;
     map { $results{$_} = undef } @list;
 
+    if ( -d '.git' ) {
+        return git_svn_metadata($attribute, \%results);
+    }
+
     # choose a chunk size such that we don't end calling svn on
     # a single file (which causes the output format to change).
     my $csize = $chunk_size;
@@ -337,6 +364,26 @@ sub verify_attributes {
     return @failures;
 }
 
+sub git_svn_metadata {
+    my $attribute   = shift;
+    my $results_ref = shift;
+
+    GIT_SVN:
+    for my $line (@git_svn_metadata) {
+
+        # Determine file name and attribute value for the files we want
+        my ($filename, $value) = $line =~ m/prop: (\S+) $attribute (\S+)/;
+        next GIT_SVN unless $filename && exists $results_ref->{$filename};
+
+        # Unescape hex values that are in git-svn log and remove any newlines
+        $value =~ s/%([0-9A-F]{2})/chr(hex($1))/gie;
+        chomp($value);
+
+        $results_ref->{$filename} = $value;
+    }
+    return $results_ref;
+}
+
 # Local Variables:
 #   mode: cperl
 #   cperl-indent-level: 4

Reply via email to