Skip to content

Commit

Permalink
Extract Git::SVN::GlobSpec from git-svn.
Browse files Browse the repository at this point in the history
Straight cut & paste.  That's the last class.

* Make Git::SVN load it on its own, its the only thing that needs it.

Signed-off-by: Eric Wong <normalperson@yhbt.net>
  • Loading branch information
Michael G. Schwern authored and Eric Wong committed Jul 27, 2012
1 parent 10c2aa5 commit 3d9be15
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 60 deletions.
59 changes: 0 additions & 59 deletions git-svn.perl
Original file line number Diff line number Diff line change
Expand Up @@ -2039,65 +2039,6 @@ sub gc_directory {
}
}


package Git::SVN::GlobSpec;
use strict;
use warnings;

sub new {
my ($class, $glob, $pattern_ok) = @_;
my $re = $glob;
$re =~ s!/+$!!g; # no need for trailing slashes
my (@left, @right, @patterns);
my $state = "left";
my $die_msg = "Only one set of wildcard directories " .
"(e.g. '*' or '*/*/*') is supported: '$glob'\n";
for my $part (split(m|/|, $glob)) {
if ($part =~ /\*/ && $part ne "*") {
die "Invalid pattern in '$glob': $part\n";
} elsif ($pattern_ok && $part =~ /[{}]/ &&
$part !~ /^\{[^{}]+\}/) {
die "Invalid pattern in '$glob': $part\n";
}
if ($part eq "*") {
die $die_msg if $state eq "right";
$state = "pattern";
push(@patterns, "[^/]*");
} elsif ($pattern_ok && $part =~ /^\{(.*)\}$/) {
die $die_msg if $state eq "right";
$state = "pattern";
my $p = quotemeta($1);
$p =~ s/\\,/|/g;
push(@patterns, "(?:$p)");
} else {
if ($state eq "left") {
push(@left, $part);
} else {
push(@right, $part);
$state = "right";
}
}
}
my $depth = @patterns;
if ($depth == 0) {
die "One '*' is needed in glob: '$glob'\n";
}
my $left = join('/', @left);
my $right = join('/', @right);
$re = join('/', @patterns);
$re = join('\/',
grep(length, quotemeta($left), "($re)", quotemeta($right)));
my $left_re = qr/^\/\Q$left\E(\/|$)/;
bless { left => $left, right => $right, left_regex => $left_re,
regex => qr/$re/, glob => $glob, depth => $depth }, $class;
}

sub full_path {
my ($self, $path) = @_;
return (length $self->{left} ? "$self->{left}/" : '') .
$path . (length $self->{right} ? "/$self->{right}" : '');
}

__END__
Data structures:
Expand Down
2 changes: 2 additions & 0 deletions perl/Git/SVN.pm
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ sub read_all_remotes {
. "must start with 'refs/'\n")
unless $remote_ref =~ m{^refs/};
$local_ref = uri_decode($local_ref);

require Git::SVN::GlobSpec;
my $rs = {
t => $t,
remote => $remote,
Expand Down
59 changes: 59 additions & 0 deletions perl/Git/SVN/GlobSpec.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package Git::SVN::GlobSpec;
use strict;
use warnings;

sub new {
my ($class, $glob, $pattern_ok) = @_;
my $re = $glob;
$re =~ s!/+$!!g; # no need for trailing slashes
my (@left, @right, @patterns);
my $state = "left";
my $die_msg = "Only one set of wildcard directories " .
"(e.g. '*' or '*/*/*') is supported: '$glob'\n";
for my $part (split(m|/|, $glob)) {
if ($part =~ /\*/ && $part ne "*") {
die "Invalid pattern in '$glob': $part\n";
} elsif ($pattern_ok && $part =~ /[{}]/ &&
$part !~ /^\{[^{}]+\}/) {
die "Invalid pattern in '$glob': $part\n";
}
if ($part eq "*") {
die $die_msg if $state eq "right";
$state = "pattern";
push(@patterns, "[^/]*");
} elsif ($pattern_ok && $part =~ /^\{(.*)\}$/) {
die $die_msg if $state eq "right";
$state = "pattern";
my $p = quotemeta($1);
$p =~ s/\\,/|/g;
push(@patterns, "(?:$p)");
} else {
if ($state eq "left") {
push(@left, $part);
} else {
push(@right, $part);
$state = "right";
}
}
}
my $depth = @patterns;
if ($depth == 0) {
die "One '*' is needed in glob: '$glob'\n";
}
my $left = join('/', @left);
my $right = join('/', @right);
$re = join('/', @patterns);
$re = join('\/',
grep(length, quotemeta($left), "($re)", quotemeta($right)));
my $left_re = qr/^\/\Q$left\E(\/|$)/;
bless { left => $left, right => $right, left_regex => $left_re,
regex => qr/$re/, glob => $glob, depth => $depth }, $class;
}

sub full_path {
my ($self, $path) = @_;
return (length $self->{left} ? "$self->{left}/" : '') .
$path . (length $self->{right} ? "/$self->{right}" : '');
}

1;
1 change: 1 addition & 0 deletions perl/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ modules += Git/SVN
modules += Git/SVN/Memoize/YAML
modules += Git/SVN/Fetcher
modules += Git/SVN/Editor
modules += Git/SVN/GlobSpec
modules += Git/SVN/Log
modules += Git/SVN/Migration
modules += Git/SVN/Prompt
Expand Down
3 changes: 2 additions & 1 deletion t/Git-SVN/00compile.t
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
use strict;
use warnings;

use Test::More tests => 6;
use Test::More tests => 7;

require_ok 'Git::SVN';
require_ok 'Git::SVN::Utils';
require_ok 'Git::SVN::Ra';
require_ok 'Git::SVN::Log';
require_ok 'Git::SVN::Migration';
require_ok 'Git::IndexInfo';
require_ok 'Git::SVN::GlobSpec';

0 comments on commit 3d9be15

Please sign in to comment.