Extract some utilities from git-svn to allow extracting Git::SVN.

Put them in a new module called Git::SVN::Utils. Yeah, not terribly original and it will be a dumping ground. But its better than having them in the main git-svn program. At least they can be documented and tested. * fatal() is used by many classes. * Change the $can_compress lexical into a function. This should be enough to extract Git::SVN. Signed-off-by: Michael G. Schwern <schwern@pobox.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Eric Wong <normalperson@yhbt.net>

Michael G. Schwern committed Jul 26, 2012 at 16:22 UTC c2768fa15234fd7eef7abb52eca2a3abe08e525c
6 files changed +132 -15
git-svn.perl
+19 -15
@@ -10,6 +10,8 @@ use vars qw/ $AUTHOR $VERSION
10 $AUTHOR = 'Eric Wong <normalperson@yhbt.net>';
11 $VERSION = '@@GIT_VERSION@@';
12
13 +use Git::SVN::Utils qw(fatal can_compress);
14 +
15 # From which subdir have we been invoked?
16 my $cmd_dir_prefix = eval {
17 command_oneline([qw/rev-parse --show-prefix/], STDERR => 0)
@@ -35,8 +37,6 @@ $Git::SVN::Log::TZ = $ENV{TZ};
37 $ENV{TZ} = 'UTC';
38 $| = 1; # unbuffer STDOUT
39
38 -sub fatal (@) { print STDERR "@_\n"; exit 1 }
39 -
40 # All SVN commands do it. Otherwise we may die on SIGPIPE when the remote
41 # repository decides to close the connection which we expect to be kept alive.
42 $SIG{PIPE} = 'IGNORE';
@@ -66,7 +66,7 @@ sub _req_svn {
66 fatal "Need SVN::Core 1.1.0 or better (got $SVN::Core::VERSION)";
67 }
68 }
69 -my $can_compress = eval { require Compress::Zlib; 1};
69 +
70 use Carp qw/croak/;
71 use Digest::MD5;
72 use IO::File qw//;
@@ -1578,7 +1578,7 @@ sub cmd_reset {
1578 }
1579
1580 sub cmd_gc {
1581 - if (!$can_compress) {
1581 + if (!can_compress()) {
1582 warn "Compress::Zlib could not be found; unhandled.log " .
1583 "files will not be compressed.\n";
1584 }
@@ -2013,13 +2013,13 @@ sub md5sum {
2013 } elsif (!$ref) {
2014 $md5->add($arg) or croak $!;
2015 } else {
2016 - ::fatal "Can't provide MD5 hash for unknown ref type: '", $ref, "'";
2016 + fatal "Can't provide MD5 hash for unknown ref type: '", $ref, "'";
2017 }
2018 return $md5->hexdigest();
2019 }
2020
2021 sub gc_directory {
2022 - if ($can_compress && -f $_ && basename($_) eq "unhandled.log") {
2022 + if (can_compress() && -f $_ && basename($_) eq "unhandled.log") {
2023 my $out_filename = $_ . ".gz";
2024 open my $in_fh, "<", $_ or die "Unable to open $_: $!\n";
2025 binmode $in_fh;
@@ -2054,6 +2054,9 @@ use Time::Local;
2054 use Memoize; # core since 5.8.0, Jul 2002
2055 use Memoize::Storable;
2056 use POSIX qw(:signal_h);
2057 +
2058 +use Git::SVN::Utils qw(fatal can_compress);
2059 +
2060 my $can_use_yaml;
2061 BEGIN {
2062 $can_use_yaml = eval { require Git::SVN::Memoize::YAML; 1};
@@ -2879,8 +2882,8 @@ sub assert_index_clean {
2882 command_noisy('read-tree', $treeish);
2883 $x = command_oneline('write-tree');
2884 if ($y ne $x) {
2882 - ::fatal "trees ($treeish) $y != $x\n",
2883 - "Something is seriously wrong...";
2885 + fatal "trees ($treeish) $y != $x\n",
2886 + "Something is seriously wrong...";
2887 }
2888 });
2889 }
@@ -3235,7 +3238,7 @@ sub mkemptydirs {
3238 my %empty_dirs = ();
3239 my $gz_file = "$self->{dir}/unhandled.log.gz";
3240 if (-f $gz_file) {
3238 - if (!$can_compress) {
3241 + if (!can_compress()) {
3242 warn "Compress::Zlib could not be found; ",
3243 "empty directories in $gz_file will not be read\n";
3244 } else {
@@ -3918,7 +3921,7 @@ sub set_tree {
3921 my ($self, $tree) = (shift, shift);
3922 my $log_entry = ::get_commit_entry($tree);
3923 unless ($self->{last_rev}) {
3921 - ::fatal("Must have an existing revision to commit");
3924 + fatal("Must have an existing revision to commit");
3925 }
3926 my %ed_opts = ( r => $self->{last_rev},
3927 log => $log_entry->{log},
@@ -4347,6 +4350,7 @@ sub remove_username {
4350 package Git::SVN::Log;
4351 use strict;
4352 use warnings;
4353 +use Git::SVN::Utils qw(fatal);
4354 use POSIX qw/strftime/;
4355 use constant commit_log_separator => ('-' x 72) . "\n";
4356 use vars qw/$TZ $limit $color $pager $non_recursive $verbose $oneline
@@ -4445,15 +4449,15 @@ sub config_pager {
4449 sub run_pager {
4450 return unless defined $pager;
4451 pipe my ($rfd, $wfd) or return;
4448 - defined(my $pid = fork) or ::fatal "Can't fork: $!";
4452 + defined(my $pid = fork) or fatal "Can't fork: $!";
4453 if (!$pid) {
4454 open STDOUT, '>&', $wfd or
4451 - ::fatal "Can't redirect to stdout: $!";
4455 + fatal "Can't redirect to stdout: $!";
4456 return;
4457 }
4454 - open STDIN, '<&', $rfd or ::fatal "Can't redirect stdin: $!";
4458 + open STDIN, '<&', $rfd or fatal "Can't redirect stdin: $!";
4459 $ENV{LESS} ||= 'FRSX';
4456 - exec $pager or ::fatal "Can't run pager: $! ($pager)";
4460 + exec $pager or fatal "Can't run pager: $! ($pager)";
4461 }
4462
4463 sub format_svn_date {
@@ -4602,7 +4606,7 @@ sub cmd_show_log {
4606 } elsif ($::_revision =~ /^\d+$/) {
4607 $r_min = $r_max = $::_revision;
4608 } else {
4605 - ::fatal "-r$::_revision is not supported, use ",
4609 + fatal "-r$::_revision is not supported, use ",
4610 "standard 'git log' arguments instead";
4611 }
4612 }
perl/Git/SVN/Utils.pm new
+59
@@ -0,0 +1,59 @@
1 +package Git::SVN::Utils;
2 +
3 +use strict;
4 +use warnings;
5 +
6 +use base qw(Exporter);
7 +
8 +our @EXPORT_OK = qw(fatal can_compress);
9 +
10 +
11 +=head1 NAME
12 +
13 +Git::SVN::Utils - utility functions used across Git::SVN
14 +
15 +=head1 SYNOPSIS
16 +
17 + use Git::SVN::Utils qw(functions to import);
18 +
19 +=head1 DESCRIPTION
20 +
21 +This module contains functions which are useful across many different
22 +parts of Git::SVN. Mostly it's a place to put utility functions
23 +rather than duplicate the code or have classes grabbing at other
24 +classes.
25 +
26 +=head1 FUNCTIONS
27 +
28 +All functions can be imported only on request.
29 +
30 +=head3 fatal
31 +
32 + fatal(@message);
33 +
34 +Display a message and exit with a fatal error code.
35 +
36 +=cut
37 +
38 +# Note: not certain why this is in use instead of die. Probably because
39 +# the exit code of die is 255? Doesn't appear to be used consistently.
40 +sub fatal (@) { print STDERR "@_\n"; exit 1 }
41 +
42 +
43 +=head3 can_compress
44 +
45 + my $can_compress = can_compress;
46 +
47 +Returns true if Compress::Zlib is available, false otherwise.
48 +
49 +=cut
50 +
51 +my $can_compress;
52 +sub can_compress {
53 + return $can_compress if defined $can_compress;
54 +
55 + return $can_compress = eval { require Compress::Zlib; };
56 +}
57 +
58 +
59 +1;
perl/Makefile
+1
@@ -34,6 +34,7 @@ modules += Git/SVN/Fetcher
34 modules += Git/SVN/Editor
35 modules += Git/SVN/Prompt
36 modules += Git/SVN/Ra
37 +modules += Git/SVN/Utils
38
39 $(makfile): ../GIT-CFLAGS Makefile
40 echo all: private-Error.pm Git.pm Git/I18N.pm > $@
t/Git-SVN/00compile.t new
+8
@@ -0,0 +1,8 @@
1 +#!/usr/bin/env perl
2 +
3 +use strict;
4 +use warnings;
5 +
6 +use Test::More tests => 1;
7 +
8 +require_ok 'Git::SVN::Utils';
t/Git-SVN/Utils/can_compress.t new
+11
@@ -0,0 +1,11 @@
1 +#!/usr/bin/perl
2 +
3 +use strict;
4 +use warnings;
5 +
6 +use Test::More 'no_plan';
7 +
8 +use Git::SVN::Utils qw(can_compress);
9 +
10 +# !! is the "convert this to boolean" operator.
11 +is !!can_compress(), !!eval { require Compress::Zlib };
t/Git-SVN/Utils/fatal.t new
+34
@@ -0,0 +1,34 @@
1 +#!/usr/bin/perl
2 +
3 +use strict;
4 +use warnings;
5 +
6 +use Test::More 'no_plan';
7 +
8 +BEGIN {
9 + # Override exit at BEGIN time before Git::SVN::Utils is loaded
10 + # so it will see our local exit later.
11 + *CORE::GLOBAL::exit = sub(;$) {
12 + return @_ ? CORE::exit($_[0]) : CORE::exit();
13 + };
14 +}
15 +
16 +use Git::SVN::Utils qw(fatal);
17 +
18 +# fatal()
19 +{
20 + # Capture the exit code and prevent exit.
21 + my $exit_status;
22 + no warnings 'redefine';
23 + local *CORE::GLOBAL::exit = sub { $exit_status = $_[0] || 0 };
24 +
25 + # Trap fatal's message to STDERR
26 + my $stderr;
27 + close STDERR;
28 + ok open STDERR, ">", \$stderr;
29 +
30 + fatal "Some", "Stuff", "Happened";
31 +
32 + is $stderr, "Some Stuff Happened\n";
33 + is $exit_status, 1;
34 +}