git-svn: add join_paths() to safely concatenate paths
Otherwise you might wind up with things like... my $path1 = undef; my $path2 = 'foo'; my $path = $path1 . '/' . $path2; creating '/foo'. Or this... my $path1 = 'foo/'; my $path2 = 'bar'; my $path = $path1 . '/' . $path2; creating 'foo//bar'. Could have used File::Spec, but I'm shying away from it due to SVN 1.7's pickiness about paths. Felt it would be better to have our own we can control completely. [ew: commit title] Signed-off-by: Eric Wong <normalperson@yhbt.net>
This commit is contained in:

committed by
Eric Wong

parent
280ad88aa0
commit
ca475a61f8
@ -34,6 +34,7 @@ use Git::SVN::Utils qw(
|
|||||||
can_compress
|
can_compress
|
||||||
canonicalize_path
|
canonicalize_path
|
||||||
canonicalize_url
|
canonicalize_url
|
||||||
|
join_paths
|
||||||
);
|
);
|
||||||
|
|
||||||
use Git qw(
|
use Git qw(
|
||||||
@ -1275,7 +1276,7 @@ sub get_svnprops {
|
|||||||
$path = $cmd_dir_prefix . $path;
|
$path = $cmd_dir_prefix . $path;
|
||||||
fatal("No such file or directory: $path") unless -e $path;
|
fatal("No such file or directory: $path") unless -e $path;
|
||||||
my $is_dir = -d $path ? 1 : 0;
|
my $is_dir = -d $path ? 1 : 0;
|
||||||
$path = $gs->{path} . '/' . $path;
|
$path = join_paths($gs->{path}, $path);
|
||||||
|
|
||||||
# canonicalize the path (otherwise libsvn will abort or fail to
|
# canonicalize the path (otherwise libsvn will abort or fail to
|
||||||
# find the file)
|
# find the file)
|
||||||
|
@ -23,7 +23,11 @@ use Git qw(
|
|||||||
command_output_pipe
|
command_output_pipe
|
||||||
command_close_pipe
|
command_close_pipe
|
||||||
);
|
);
|
||||||
use Git::SVN::Utils qw(fatal can_compress);
|
use Git::SVN::Utils qw(
|
||||||
|
fatal
|
||||||
|
can_compress
|
||||||
|
join_paths
|
||||||
|
);
|
||||||
|
|
||||||
my $can_use_yaml;
|
my $can_use_yaml;
|
||||||
BEGIN {
|
BEGIN {
|
||||||
@ -316,9 +320,7 @@ sub init_remote_config {
|
|||||||
}
|
}
|
||||||
my $old_path = $self->path;
|
my $old_path = $self->path;
|
||||||
$url =~ s!^\Q$min_url\E(/|$)!!;
|
$url =~ s!^\Q$min_url\E(/|$)!!;
|
||||||
if (length $old_path) {
|
$url = join_paths($url, $old_path);
|
||||||
$url .= "/$old_path";
|
|
||||||
}
|
|
||||||
$self->path($url);
|
$self->path($url);
|
||||||
$url = $min_url;
|
$url = $min_url;
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ our @EXPORT_OK = qw(
|
|||||||
can_compress
|
can_compress
|
||||||
canonicalize_path
|
canonicalize_path
|
||||||
canonicalize_url
|
canonicalize_url
|
||||||
|
join_paths
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -134,4 +135,35 @@ sub _canonicalize_url_ourselves {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
=head3 join_paths
|
||||||
|
|
||||||
|
my $new_path = join_paths(@paths);
|
||||||
|
|
||||||
|
Appends @paths together into a single path. Any empty paths are ignored.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub join_paths {
|
||||||
|
my @paths = @_;
|
||||||
|
|
||||||
|
@paths = grep { defined $_ && length $_ } @paths;
|
||||||
|
|
||||||
|
return '' unless @paths;
|
||||||
|
return $paths[0] if @paths == 1;
|
||||||
|
|
||||||
|
my $new_path = shift @paths;
|
||||||
|
$new_path =~ s{/+$}{};
|
||||||
|
|
||||||
|
my $last_path = pop @paths;
|
||||||
|
$last_path =~ s{^/+}{};
|
||||||
|
|
||||||
|
for my $path (@paths) {
|
||||||
|
$path =~ s{^/+}{};
|
||||||
|
$path =~ s{/+$}{};
|
||||||
|
$new_path .= "/$path";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $new_path .= "/$last_path";
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
32
t/Git-SVN/Utils/join_paths.t
Normal file
32
t/Git-SVN/Utils/join_paths.t
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env perl
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
use Test::More 'no_plan';
|
||||||
|
|
||||||
|
use Git::SVN::Utils qw(
|
||||||
|
join_paths
|
||||||
|
);
|
||||||
|
|
||||||
|
# A reference cannot be a hash key, so we use an array.
|
||||||
|
my @tests = (
|
||||||
|
[] => '',
|
||||||
|
["/x.com", "bar"] => '/x.com/bar',
|
||||||
|
["x.com", ""] => 'x.com',
|
||||||
|
["/x.com/foo/", undef, "bar"] => '/x.com/foo/bar',
|
||||||
|
["x.com/foo/", "/bar/baz/"] => 'x.com/foo/bar/baz/',
|
||||||
|
["foo", "bar"] => 'foo/bar',
|
||||||
|
["/foo/bar", "baz", "/biff"] => '/foo/bar/baz/biff',
|
||||||
|
["", undef, "."] => '.',
|
||||||
|
[] => '',
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
while(@tests) {
|
||||||
|
my($have, $want) = splice @tests, 0, 2;
|
||||||
|
|
||||||
|
my $args = join ", ", map { qq['$_'] } map { defined($_) ? $_ : 'undef' } @$have;
|
||||||
|
my $name = "join_paths($args) eq '$want'";
|
||||||
|
is join_paths(@$have), $want, $name;
|
||||||
|
}
|
Reference in New Issue
Block a user