[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: Perl bindings

From: Nik Clayton <nik_at_ngo.org.uk>
Date: 2006-07-13 13:39:45 CEST

Garrett Rooney wrote:
> On 7/12/06, Nik Clayton <nik@ngo.org.uk> wrote:
> With regard to your question, it's likely just isn't exposed by the
> client level code, either because it's just not there, or because the
> perl bindings haven't been brought up to date with the new APIs. If
> you already know how to do it with the RA layer what's the problem
> with just using that?

Because I've found a bug in either the RA layer or my use of it.
'file:///' URIs work fine, any other (e.g., 'svn://') fail.

Here's two 'svn list' commands, using different access methods but
referring to the same underlying repository.

% svn list -v file:///home/nik/.svk/jc
    1072 nik Jul 12 20:22 local/
    1066 nik Jul 07 09:31 mirror/

% svn list -v svn://127.0.0.1/home/nik/.svk/jc
    1072 nik Jul 12 20:22 local/
    1066 nik Jul 07 09:31 mirror/

Same results, as expected.

Here's my code, using file:///

% ./bug.pl file:///home/nik/.svk/jc
    1066 nik 2006-07-07T08:31:26.127831Z mirror/
    1072 nik 2006-07-12T19:22:44.772832Z local/

Same (well, similar, I don't format the timestamp) results.

Here's the result using svn://

% ./bug.pl svn://127.0.0.1/home/nik/.svk/jc
Name does not refer to a filesystem file: Attempted to get checksum of a
*non*-file node at ./bug.pl line 36

Line 36 is a call to $ra->get_file().

I can understand that that might fail if I call it on a directory, since
the function name suggests that it's only supposed to work on files.

However, since it does work when using the file:/// RA layer I'm not
sure. And if it's *not* supposed to work I'm still in the dark as to
the correct way to retrieve this information in the directory case.

I've attached bug.pl. The results above were obtained using Subversion
1.3.2 (r19776).

N

#!/usr/bin/perl

use strict;
use warnings;

use SVN::Ra;

my $repo_url = shift;
my $path = '/';

my $ra = SVN::Ra->new(url => $repo_url);

# Get the directories entries for $path at the repo's youngest revision.
my $yrev = $ra->get_latest_revnum();
my $dirents = ($ra->get_dir($path, $yrev))[0];

# Iterate over these entries. Build up a list of hashes. Each list
# entry represents an entry in the directory, hash keys represent
# information about that entry.
my @entries;

my($name, $dirent);
while(($name, $dirent) = each %{ $dirents }) {
    push @entries, { name => $name,
                     kind => $dirent->kind(),
                     isdir => ($dirent->kind() == $SVN::Node::dir),
                   };
}

# Iterate over the entries, fetching additional information and storing
# it in the hash
foreach my $entry (@entries) {

    $entry->{irev} = recent_interesting_rev($ra, "$path/$entry->{name}", $yrev);

    my %props = %{ ($ra->get_file($path, $entry->{irev}, undef))[1] };

    $entry->{author} = $props{'svn:entry:last-author'};
    $entry->{date_modified} = $props{'svn:entry:committed-date'};

    $ra->get_log([ "$path/$entry->{name}" ], $entry->{irev}, 1, 1, 0, 1,
                 sub { $entry->{msg} = $_[4] });

}

# Iterate over the entries, printing the information in a format similar
# to 'svn list -v'
foreach my $entry (@entries) {
    printf("%7d %-8s %18s %s%s\n", $entry->{irev}, $entry->{author},
           $entry->{date_modified}, $entry->{name},
           $entry->{isdir} ? '/' : '');
}

# Find and return the most recent interesting rev for a path that is <= $rev
sub recent_interesting_rev {
    my $ra = shift;
    my $path = shift;
    my $rev = shift;

    $ra->get_log([$path], $rev, 1, 1, 0, 1,
                 sub { $rev = $_[1] });

    return $rev;
}

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Thu Jul 13 13:40:20 2006

This is an archived mail posted to the Subversion Dev mailing list.