4925410dd1ebed4c279a124a25557fd4c767cd83
   1package Git::SVN::Utils;
   2
   3use strict;
   4use warnings;
   5
   6use SVN::Core;
   7
   8use base qw(Exporter);
   9
  10our @EXPORT_OK = qw(
  11        fatal
  12        can_compress
  13        canonicalize_path
  14        canonicalize_url
  15);
  16
  17
  18=head1 NAME
  19
  20Git::SVN::Utils - utility functions used across Git::SVN
  21
  22=head1 SYNOPSIS
  23
  24    use Git::SVN::Utils qw(functions to import);
  25
  26=head1 DESCRIPTION
  27
  28This module contains functions which are useful across many different
  29parts of Git::SVN.  Mostly it's a place to put utility functions
  30rather than duplicate the code or have classes grabbing at other
  31classes.
  32
  33=head1 FUNCTIONS
  34
  35All functions can be imported only on request.
  36
  37=head3 fatal
  38
  39    fatal(@message);
  40
  41Display a message and exit with a fatal error code.
  42
  43=cut
  44
  45# Note: not certain why this is in use instead of die.  Probably because
  46# the exit code of die is 255?  Doesn't appear to be used consistently.
  47sub fatal (@) { print STDERR "@_\n"; exit 1 }
  48
  49
  50=head3 can_compress
  51
  52    my $can_compress = can_compress;
  53
  54Returns true if Compress::Zlib is available, false otherwise.
  55
  56=cut
  57
  58my $can_compress;
  59sub can_compress {
  60        return $can_compress if defined $can_compress;
  61
  62        return $can_compress = eval { require Compress::Zlib; };
  63}
  64
  65
  66=head3 canonicalize_path
  67
  68    my $canoncalized_path = canonicalize_path($path);
  69
  70Converts $path into a canonical form which is safe to pass to the SVN
  71API as a file path.
  72
  73=cut
  74
  75# Turn foo/../bar into bar
  76sub _collapse_dotdot {
  77        my $path = shift;
  78
  79        1 while $path =~ s{/[^/]+/+\.\.}{};
  80        1 while $path =~ s{[^/]+/+\.\./}{};
  81        1 while $path =~ s{[^/]+/+\.\.}{};
  82
  83        return $path;
  84}
  85
  86
  87sub canonicalize_path {
  88        my ($path) = @_;
  89        my $dot_slash_added = 0;
  90        if (substr($path, 0, 1) ne "/") {
  91                $path = "./" . $path;
  92                $dot_slash_added = 1;
  93        }
  94        # File::Spec->canonpath doesn't collapse x/../y into y (for a
  95        # good reason), so let's do this manually.
  96        $path =~ s#/+#/#g;
  97        $path =~ s#/\.(?:/|$)#/#g;
  98        $path = _collapse_dotdot($path);
  99        $path =~ s#/$##g;
 100        $path =~ s#^\./## if $dot_slash_added;
 101        $path =~ s#^/##;
 102        $path =~ s#^\.$##;
 103        return $path;
 104}
 105
 106
 107=head3 canonicalize_url
 108
 109    my $canonicalized_url = canonicalize_url($url);
 110
 111Converts $url into a canonical form which is safe to pass to the SVN
 112API as a URL.
 113
 114=cut
 115
 116sub canonicalize_url {
 117        my $url = shift;
 118
 119        # The 1.7 way to do it
 120        if ( defined &SVN::_Core::svn_uri_canonicalize ) {
 121                return SVN::_Core::svn_uri_canonicalize($url);
 122        }
 123        # There wasn't a 1.6 way to do it, so we do it ourself.
 124        else {
 125                return _canonicalize_url_ourselves($url);
 126        }
 127}
 128
 129
 130sub _canonicalize_url_ourselves {
 131        my ($url) = @_;
 132        $url =~ s#^([^:]+://[^/]*/)(.*)$#$1 . canonicalize_path($2)#e;
 133        return $url;
 134}
 135
 136
 1371;