| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package AnyEvent::Git::Wrapper; | 
| 2 |  |  |  |  |  |  |  | 
| 3 | 11 |  |  | 11 |  | 384078 | use strict; | 
|  | 11 |  |  |  |  | 23 |  | 
|  | 11 |  |  |  |  | 250 |  | 
| 4 | 11 |  |  | 11 |  | 49 | use warnings; | 
|  | 11 |  |  |  |  | 21 |  | 
|  | 11 |  |  |  |  | 319 |  | 
| 5 | 11 |  |  | 11 |  | 50 | use Carp qw( croak ); | 
|  | 11 |  |  |  |  | 29 |  | 
|  | 11 |  |  |  |  | 576 |  | 
| 6 | 11 |  |  | 11 |  | 48 | use base qw( Git::Wrapper ); | 
|  | 11 |  |  |  |  | 17 |  | 
|  | 11 |  |  |  |  | 8178 |  | 
| 7 | 11 |  |  | 11 |  | 368204 | use File::pushd; | 
|  | 11 |  |  |  |  | 20006 |  | 
|  | 11 |  |  |  |  | 547 |  | 
| 8 | 11 |  |  | 11 |  | 12289 | use AnyEvent; | 
|  | 11 |  |  |  |  | 44902 |  | 
|  | 11 |  |  |  |  | 294 |  | 
| 9 | 11 |  |  | 11 |  | 8193 | use AnyEvent::Open3::Simple; | 
|  | 11 |  |  |  |  | 27940 |  | 
|  | 11 |  |  |  |  | 331 |  | 
| 10 | 11 |  |  | 11 |  | 66 | use Git::Wrapper::Exception; | 
|  | 11 |  |  |  |  | 18 |  | 
|  | 11 |  |  |  |  | 252 |  | 
| 11 | 11 |  |  | 11 |  | 48 | use Git::Wrapper::Statuses; | 
|  | 11 |  |  |  |  | 17 |  | 
|  | 11 |  |  |  |  | 247 |  | 
| 12 | 11 |  |  | 11 |  | 130 | use Git::Wrapper::Log; | 
|  | 11 |  |  |  |  | 20 |  | 
|  | 11 |  |  |  |  | 227 |  | 
| 13 | 11 |  |  | 11 |  | 50 | use Scalar::Util qw( blessed ); | 
|  | 11 |  |  |  |  | 18 |  | 
|  | 11 |  |  |  |  | 20504 |  | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | # ABSTRACT: Wrap git command-line interface without blocking | 
| 16 |  |  |  |  |  |  | our $VERSION = '0.08'; # VERSION | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  |  | 
| 19 |  |  |  |  |  |  | sub new | 
| 20 |  |  |  |  |  |  | { | 
| 21 | 15 |  |  | 15 | 1 | 883240 | my $class = shift; | 
| 22 |  |  |  |  |  |  |  | 
| 23 | 15 |  |  |  |  | 39 | my $args; | 
| 24 | 15 | 100 |  |  |  | 68 | if(scalar @_ == 1) | 
| 25 |  |  |  |  |  |  | { | 
| 26 | 12 |  |  |  |  | 31 | my $arg = shift; | 
| 27 | 12 | 100 |  |  |  | 136 | if(ref $arg eq 'HASH') { $args = $arg } | 
|  | 2 | 100 |  |  |  | 6 |  | 
|  |  | 100 |  |  |  |  |  | 
| 28 | 2 |  |  |  |  | 11 | elsif(blessed $arg)    { $args = { dir => "$arg" } } | 
| 29 | 6 |  |  |  |  | 29 | elsif(! ref $arg)      { $args = { dir => $arg } } | 
| 30 | 2 |  |  |  |  | 39 | else { die "Singlearg must be hashref, scalar or stringify-able object" } | 
| 31 |  |  |  |  |  |  | } | 
| 32 |  |  |  |  |  |  | else | 
| 33 |  |  |  |  |  |  | { | 
| 34 | 3 |  |  |  |  | 19 | my($dir, %opts) = @_; | 
| 35 | 3 | 50 |  |  |  | 54 | $dir = "$dir" if blessed $dir; | 
| 36 | 3 |  |  |  |  | 18 | $args = { dir => $dir, %opts }; | 
| 37 |  |  |  |  |  |  | } | 
| 38 | 13 |  |  |  |  | 78 | my $cache_version = delete $args->{cache_version}; | 
| 39 | 13 |  |  |  |  | 173 | my $self = $class->SUPER::new($args); | 
| 40 | 11 |  |  |  |  | 384 | $self->{ae_cache_version} = $cache_version; | 
| 41 | 11 |  |  |  |  | 41 | $self; | 
| 42 |  |  |  |  |  |  | } | 
| 43 |  |  |  |  |  |  |  | 
| 44 |  |  |  |  |  |  |  | 
| 45 |  |  |  |  |  |  | sub RUN | 
| 46 |  |  |  |  |  |  | { | 
| 47 | 162 |  |  | 162 | 1 | 557534 | my($self) = shift; | 
| 48 | 162 |  |  |  |  | 464 | my $cv; | 
| 49 | 162 | 100 |  |  |  | 1065 | if(ref($_[-1]) eq 'CODE') | 
|  |  | 100 |  |  |  |  |  | 
| 50 |  |  |  |  |  |  | { | 
| 51 | 30 |  |  |  |  | 2101 | $cv = AE::cv; | 
| 52 | 30 |  |  |  |  | 632 | $cv->cb(pop); | 
| 53 |  |  |  |  |  |  | } | 
| 54 | 132 |  |  |  |  | 2400 | elsif(eval { $_[-1]->isa('AnyEvent::CondVar') }) | 
| 55 |  |  |  |  |  |  | { | 
| 56 | 27 |  |  |  |  | 104 | $cv = pop; | 
| 57 |  |  |  |  |  |  | } | 
| 58 |  |  |  |  |  |  | else | 
| 59 |  |  |  |  |  |  | { | 
| 60 | 105 |  |  |  |  | 743 | return $self->SUPER::RUN(@_); | 
| 61 |  |  |  |  |  |  | } | 
| 62 |  |  |  |  |  |  |  | 
| 63 | 57 |  |  |  |  | 929 | my $cmd = shift; | 
| 64 |  |  |  |  |  |  |  | 
| 65 | 57 |  |  |  |  | 208 | my $customize; | 
| 66 | 57 | 100 |  |  |  | 603 | $customize = pop if ref($_[-1]) eq 'CODE'; | 
| 67 |  |  |  |  |  |  |  | 
| 68 | 57 |  |  |  |  | 739 | my ($parts, $in) = Git::Wrapper::_parse_args( $cmd, @_ ); | 
| 69 | 57 |  |  |  |  | 3948 | my @out; | 
| 70 |  |  |  |  |  |  | my @err; | 
| 71 |  |  |  |  |  |  |  | 
| 72 |  |  |  |  |  |  | my $ipc = AnyEvent::Open3::Simple->new( | 
| 73 |  |  |  |  |  |  | on_stdout => \@out, | 
| 74 |  |  |  |  |  |  | on_stderr => \@err, | 
| 75 |  |  |  |  |  |  | on_error  => sub { | 
| 76 |  |  |  |  |  |  | #my($error) = @_; | 
| 77 | 0 |  |  | 0 |  | 0 | $cv->croak( | 
| 78 |  |  |  |  |  |  | Git::Wrapper::Exception->new( | 
| 79 |  |  |  |  |  |  | output => \@out, | 
| 80 |  |  |  |  |  |  | error  => \@err, | 
| 81 |  |  |  |  |  |  | status => -1, | 
| 82 |  |  |  |  |  |  | ) | 
| 83 |  |  |  |  |  |  | ); | 
| 84 |  |  |  |  |  |  | }, | 
| 85 |  |  |  |  |  |  | on_exit   => sub { | 
| 86 | 57 |  |  | 57 |  | 159998 | my(undef, $exit, $signal) = @_; | 
| 87 |  |  |  |  |  |  |  | 
| 88 |  |  |  |  |  |  | # borrowed from superclass, see comment there | 
| 89 | 57 |  | 66 |  |  | 560 | my $stupid_status = $cmd eq 'status' && @out && ! @err; | 
| 90 |  |  |  |  |  |  |  | 
| 91 | 57 | 100 | 66 |  |  | 897 | if(($exit || $signal) && ! $stupid_status) | 
|  |  |  | 66 |  |  |  |  | 
| 92 |  |  |  |  |  |  | { | 
| 93 | 1 |  |  |  |  | 32 | $cv->croak( | 
| 94 |  |  |  |  |  |  | Git::Wrapper::Exception->new( | 
| 95 |  |  |  |  |  |  | output => \@out, | 
| 96 |  |  |  |  |  |  | error  => \@err, | 
| 97 |  |  |  |  |  |  | status => $exit, | 
| 98 |  |  |  |  |  |  | ) | 
| 99 |  |  |  |  |  |  | ); | 
| 100 |  |  |  |  |  |  | } | 
| 101 |  |  |  |  |  |  | else | 
| 102 |  |  |  |  |  |  | { | 
| 103 | 56 |  |  |  |  | 341 | $self->{err} = \@err; | 
| 104 | 56 |  |  |  |  | 236 | $self->{out} = \@out; | 
| 105 | 56 |  |  |  |  | 554 | $cv->send(\@out, \@err); | 
| 106 |  |  |  |  |  |  | } | 
| 107 |  |  |  |  |  |  | }, | 
| 108 | 57 | 100 |  |  |  | 1348 | $customize ? $customize->() : () | 
| 109 |  |  |  |  |  |  | ); | 
| 110 |  |  |  |  |  |  |  | 
| 111 | 57 |  |  |  |  | 4508 | do { | 
| 112 | 57 | 50 |  |  |  | 685 | my $d = pushd $self->dir unless $cmd eq 'clone'; | 
| 113 |  |  |  |  |  |  |  | 
| 114 | 57 |  |  |  |  | 10752 | my @cmd = ( $self->git, @$parts ); | 
| 115 |  |  |  |  |  |  |  | 
| 116 | 57 | 50 |  |  |  | 1390 | local $ENV{GIT_EDITOR} = $^O eq 'MSWin32' ? 'cmd /c "exit 2"' : ''; | 
| 117 | 57 |  |  |  |  | 455 | $ipc->run(@cmd, \$in); | 
| 118 |  |  |  |  |  |  |  | 
| 119 | 57 |  |  |  |  | 537882 | undef $d; | 
| 120 |  |  |  |  |  |  | }; | 
| 121 |  |  |  |  |  |  |  | 
| 122 | 57 |  |  |  |  | 6804 | $cv; | 
| 123 |  |  |  |  |  |  | } | 
| 124 |  |  |  |  |  |  |  | 
| 125 |  |  |  |  |  |  |  | 
| 126 |  |  |  |  |  |  | my %STATUS_CONFLICTS = map { $_ => 1 } qw; | 
| 127 |  |  |  |  |  |  |  | 
| 128 |  |  |  |  |  |  | sub status | 
| 129 |  |  |  |  |  |  | { | 
| 130 | 4 |  |  | 4 | 1 | 336 | my($self) = shift; | 
| 131 | 4 |  |  |  |  | 15 | my $cv; | 
| 132 | 4 | 50 |  |  |  | 46 | if(ref($_[-1]) eq 'CODE') | 
|  |  | 100 |  |  |  |  |  | 
| 133 |  |  |  |  |  |  | { | 
| 134 | 0 |  |  |  |  | 0 | $cv = AE::cv; | 
| 135 | 0 |  |  |  |  | 0 | $cv->cb(pop); | 
| 136 |  |  |  |  |  |  | } | 
| 137 | 4 |  |  |  |  | 91 | elsif(eval { $_[-1]->isa('AnyEvent::CondVar') }) | 
| 138 |  |  |  |  |  |  | { | 
| 139 | 2 |  |  |  |  | 14 | $cv = pop; | 
| 140 |  |  |  |  |  |  | } | 
| 141 |  |  |  |  |  |  | else | 
| 142 |  |  |  |  |  |  | { | 
| 143 | 2 |  |  |  |  | 38 | return $self->SUPER::status(@_); | 
| 144 |  |  |  |  |  |  | } | 
| 145 |  |  |  |  |  |  |  | 
| 146 | 2 | 50 |  |  |  | 24 | my $opt = ref $_[0] eq 'HASH' ? shift : {}; | 
| 147 | 2 |  |  |  |  | 35 | $opt->{porcelain} = 1; | 
| 148 |  |  |  |  |  |  |  | 
| 149 |  |  |  |  |  |  | $self->RUN('status' => $opt, @_, sub { | 
| 150 | 2 |  |  | 2 |  | 62 | my $out = shift->recv; | 
| 151 | 2 |  |  |  |  | 77 | my $stat = Git::Wrapper::Statuses->new; | 
| 152 |  |  |  |  |  |  |  | 
| 153 | 2 |  |  |  |  | 28 | for(@$out) | 
| 154 |  |  |  |  |  |  | { | 
| 155 | 1 |  |  |  |  | 17 | my ($x, $y, $from, $to) = $_ =~ /\A(.)(.) (.*?)(?: -> (.*))?\z/; | 
| 156 | 1 | 50 | 33 |  |  | 31 | if ($STATUS_CONFLICTS{"$x$y"}) | 
|  |  | 50 |  |  |  |  |  | 
| 157 |  |  |  |  |  |  | { | 
| 158 | 0 |  |  |  |  | 0 | $stat->add('conflict', "$x$y", $from, $to); | 
| 159 |  |  |  |  |  |  | } | 
| 160 |  |  |  |  |  |  | elsif ($x eq '?' && $y eq '?') | 
| 161 |  |  |  |  |  |  | { | 
| 162 | 0 |  |  |  |  | 0 | $stat->add('unknown', '?', $from, $to); | 
| 163 |  |  |  |  |  |  | } | 
| 164 |  |  |  |  |  |  | else | 
| 165 |  |  |  |  |  |  | { | 
| 166 | 1 | 50 |  |  |  | 11 | $stat->add('changed', $y, $from, $to) | 
| 167 |  |  |  |  |  |  | if $y ne ' '; | 
| 168 | 1 | 50 |  |  |  | 13 | $stat->add('indexed', $x, $from, $to) | 
| 169 |  |  |  |  |  |  | if $x ne ' '; | 
| 170 |  |  |  |  |  |  | } | 
| 171 |  |  |  |  |  |  | } | 
| 172 |  |  |  |  |  |  |  | 
| 173 | 2 |  |  |  |  | 56 | $cv->send($stat); | 
| 174 | 2 |  |  |  |  | 63 | }); | 
| 175 |  |  |  |  |  |  |  | 
| 176 | 2 |  |  |  |  | 60 | $cv; | 
| 177 |  |  |  |  |  |  | } | 
| 178 |  |  |  |  |  |  |  | 
| 179 |  |  |  |  |  |  |  | 
| 180 |  |  |  |  |  |  | sub log | 
| 181 |  |  |  |  |  |  | { | 
| 182 | 22 |  |  | 22 | 1 | 132997 | my($self) = shift; | 
| 183 | 22 |  |  |  |  | 87 | my $cv; | 
| 184 | 22 | 50 |  |  |  | 231 | if(ref($_[-1]) eq 'CODE') | 
|  |  | 100 |  |  |  |  |  | 
| 185 |  |  |  |  |  |  | { | 
| 186 | 0 |  |  |  |  | 0 | $cv = AE::cv; | 
| 187 | 0 |  |  |  |  | 0 | $cv->cb(pop); | 
| 188 |  |  |  |  |  |  | } | 
| 189 | 22 |  |  |  |  | 529 | elsif(eval { $_[-1]->isa('AnyEvent::CondVar') }) | 
| 190 |  |  |  |  |  |  | { | 
| 191 | 11 |  |  |  |  | 53 | $cv = pop; | 
| 192 |  |  |  |  |  |  | } | 
| 193 |  |  |  |  |  |  | else | 
| 194 |  |  |  |  |  |  | { | 
| 195 | 11 |  |  |  |  | 161 | return $self->SUPER::log(@_); | 
| 196 |  |  |  |  |  |  | } | 
| 197 |  |  |  |  |  |  |  | 
| 198 | 11 |  |  |  |  | 53 | my $cb; | 
| 199 | 11 | 100 |  |  |  | 123 | if(ref($_[-1]) eq 'CODE') | 
| 200 |  |  |  |  |  |  | { | 
| 201 | 1 |  |  |  |  | 5 | $cb = pop; | 
| 202 |  |  |  |  |  |  | } | 
| 203 |  |  |  |  |  |  |  | 
| 204 | 11 | 100 |  |  |  | 100 | my $opt = ref $_[0] eq 'HASH' ? shift : {}; | 
| 205 | 11 |  |  |  |  | 93 | $opt->{no_color}         = 1; | 
| 206 | 11 |  |  |  |  | 95 | $opt->{pretty}           = 'medium'; | 
| 207 | 11 | 50 |  |  |  | 245 | $opt->{no_abbrev_commit} = 1 | 
| 208 |  |  |  |  |  |  | if $self->supports_log_no_abbrev_commit; | 
| 209 |  |  |  |  |  |  |  | 
| 210 | 11 |  | 66 |  |  | 1723 | my $raw = defined $opt->{raw} && $opt->{raw}; | 
| 211 |  |  |  |  |  |  |  | 
| 212 | 11 |  |  |  |  | 101 | my $out = []; | 
| 213 | 11 |  |  |  |  | 45 | my @logs; | 
| 214 |  |  |  |  |  |  |  | 
| 215 |  |  |  |  |  |  | my $process_commit = sub { | 
| 216 | 14 | 50 |  | 14 |  | 73 | if(my $line = shift @$out) | 
| 217 |  |  |  |  |  |  | { | 
| 218 | 14 | 100 |  |  |  | 103 | unless($line =~ /^commit (\S+)/) | 
| 219 |  |  |  |  |  |  | { | 
| 220 | 1 |  |  |  |  | 33 | $cv->croak("unhandled: $line"); | 
| 221 | 1 |  |  |  |  | 16 | return; | 
| 222 |  |  |  |  |  |  | } | 
| 223 |  |  |  |  |  |  |  | 
| 224 | 13 |  |  |  |  | 348 | my $current = Git::Wrapper::Log->new($1); | 
| 225 |  |  |  |  |  |  |  | 
| 226 | 13 |  |  |  |  | 419 | $line = shift @$out;  # next line | 
| 227 |  |  |  |  |  |  |  | 
| 228 | 13 |  |  |  |  | 147 | while($line =~ /^(\S+):\s+(.+)$/) | 
| 229 |  |  |  |  |  |  | { | 
| 230 | 26 |  |  |  |  | 136 | $current->attr->{lc $1} = $2; | 
| 231 | 26 |  |  |  |  | 414 | $line = shift @$out; # next line | 
| 232 |  |  |  |  |  |  | } | 
| 233 |  |  |  |  |  |  |  | 
| 234 | 13 | 50 |  |  |  | 53 | if($line) | 
| 235 |  |  |  |  |  |  | { | 
| 236 | 0 |  |  |  |  | 0 | $cv->croak("no blank line separating head from message"); | 
| 237 | 0 |  |  |  |  | 0 | return; | 
| 238 |  |  |  |  |  |  | } | 
| 239 |  |  |  |  |  |  |  | 
| 240 | 13 | 50 |  |  |  | 136 | my($initial_indent) = $out->[0] =~ /^(\s*)/ if @$out; | 
| 241 |  |  |  |  |  |  |  | 
| 242 | 13 |  |  |  |  | 55 | my $message = ''; | 
| 243 | 13 |  | 100 |  |  | 230 | while(@$out and $out->[0] !~ /^commit (\S+)/ and length($line = shift @$out)) | 
|  |  |  | 100 |  |  |  |  | 
| 244 |  |  |  |  |  |  | { | 
| 245 | 20 |  |  |  |  | 242 | $line =~ s/^$initial_indent//; # strip just the indenting added by git | 
| 246 | 20 |  |  |  |  | 191 | $message .= "$line\n"; | 
| 247 |  |  |  |  |  |  | } | 
| 248 |  |  |  |  |  |  |  | 
| 249 | 13 |  |  |  |  | 83 | $current->message($message); | 
| 250 |  |  |  |  |  |  |  | 
| 251 | 13 | 100 |  |  |  | 137 | if($raw) | 
| 252 |  |  |  |  |  |  | { | 
| 253 | 1 |  |  |  |  | 2 | my @modifications; | 
| 254 | 1 |  | 66 |  |  | 19 | while(@$out and $out->[0] =~ m/^\:(\d{6}) (\d{6}) (\w{7})\.\.\. (\w{7})\.\.\. (\w{1})\t(.*)$/) | 
| 255 |  |  |  |  |  |  | { | 
| 256 | 1 |  |  |  |  | 20 | push @modifications, Git::Wrapper::File::RawModification->new($6,$5,$1,$2,$3,$4); | 
| 257 | 1 |  |  |  |  | 36 | shift @$out; | 
| 258 |  |  |  |  |  |  | } | 
| 259 | 1 | 50 |  |  |  | 12 | $current->modifications(@modifications) if @modifications; | 
| 260 |  |  |  |  |  |  | } | 
| 261 |  |  |  |  |  |  |  | 
| 262 | 13 | 100 |  |  |  | 55 | if($cb) | 
| 263 | 2 |  |  |  |  | 11 | { $cb->($current) } | 
| 264 |  |  |  |  |  |  | else | 
| 265 | 11 |  |  |  |  | 98 | { push @logs, $current } | 
| 266 |  |  |  |  |  |  | } | 
| 267 | 11 |  |  |  |  | 276 | }; | 
| 268 |  |  |  |  |  |  |  | 
| 269 |  |  |  |  |  |  | my $on_stdout = sub { | 
| 270 | 77 |  |  | 77 |  | 33367 | my $line = pop; | 
| 271 | 77 |  |  |  |  | 290 | push @$out, $line; | 
| 272 | 77 | 100 | 100 |  |  | 889 | $process_commit->() if $line =~ /^commit (\S+)/ && @$out > 1; | 
| 273 | 11 |  |  |  |  | 152 | }; | 
| 274 |  |  |  |  |  |  |  | 
| 275 | 11 |  |  | 11 |  | 328 | $self->RUN(log => $opt, @_, sub { on_stdout => $on_stdout }, sub { | 
| 276 | 11 |  |  | 11 |  | 201 | eval { shift->recv }; | 
|  | 11 |  |  |  |  | 67 |  | 
| 277 | 11 | 50 |  |  |  | 162 | $cv->croak($@) if $@; | 
| 278 |  |  |  |  |  |  |  | 
| 279 | 11 |  |  |  |  | 59 | while($out->[0]) { | 
| 280 | 11 |  |  |  |  | 39 | $process_commit->(); | 
| 281 |  |  |  |  |  |  | } | 
| 282 |  |  |  |  |  |  |  | 
| 283 | 11 |  |  |  |  | 70 | $cv->send(@logs); | 
| 284 | 11 |  |  |  |  | 352 | }); | 
| 285 |  |  |  |  |  |  |  | 
| 286 | 11 |  |  |  |  | 468 | $cv; | 
| 287 |  |  |  |  |  |  | } | 
| 288 |  |  |  |  |  |  |  | 
| 289 |  |  |  |  |  |  |  | 
| 290 |  |  |  |  |  |  | sub version | 
| 291 |  |  |  |  |  |  | { | 
| 292 | 58 |  |  | 58 | 1 | 96721 | my($self) = @_; | 
| 293 | 58 |  |  |  |  | 142 | my $cv; | 
| 294 | 58 | 50 |  |  |  | 437 | if(ref($_[-1]) eq 'CODE') | 
|  |  | 100 |  |  |  |  |  | 
| 295 |  |  |  |  |  |  | { | 
| 296 | 0 |  |  |  |  | 0 | $cv = AE::cv; | 
| 297 | 0 |  |  |  |  | 0 | $cv->cb(pop); | 
| 298 |  |  |  |  |  |  | } | 
| 299 | 58 |  |  |  |  | 1036 | elsif(eval { $_[-1]->isa('AnyEvent::CondVar') }) | 
| 300 |  |  |  |  |  |  | { | 
| 301 | 10 |  |  |  |  | 30 | $cv = pop; | 
| 302 |  |  |  |  |  |  | } | 
| 303 |  |  |  |  |  |  | else | 
| 304 |  |  |  |  |  |  | { | 
| 305 | 48 | 100 | 66 |  |  | 391 | if($self->{ae_cache_version} && $self->{ae_version}) | 
| 306 | 2 |  |  |  |  | 20 | { return $self->{ae_version} } | 
| 307 | 46 |  |  |  |  | 511 | $self->{ae_version} = $self->SUPER::version(@_); | 
| 308 | 46 |  |  |  |  | 485471 | return $self->{ae_version}; | 
| 309 |  |  |  |  |  |  | } | 
| 310 |  |  |  |  |  |  |  | 
| 311 | 10 | 100 | 66 |  |  | 78 | if($self->{ae_cache_version} && $self->{ae_version}) | 
| 312 |  |  |  |  |  |  | { | 
| 313 | 2 |  |  |  |  | 21 | $cv->send($self->{ae_version}); | 
| 314 |  |  |  |  |  |  | } | 
| 315 |  |  |  |  |  |  | else | 
| 316 |  |  |  |  |  |  | { | 
| 317 |  |  |  |  |  |  | $self->RUN('version', sub { | 
| 318 | 8 |  |  | 8 |  | 150 | my $out = eval { shift->recv }; | 
|  | 8 |  |  |  |  | 70 |  | 
| 319 | 8 | 50 |  |  |  | 102 | if($@) | 
| 320 |  |  |  |  |  |  | { | 
| 321 | 0 |  |  |  |  | 0 | $cv->croak($@); | 
| 322 |  |  |  |  |  |  | } | 
| 323 |  |  |  |  |  |  | else | 
| 324 |  |  |  |  |  |  | { | 
| 325 | 8 |  |  |  |  | 45 | $self->{ae_version} = $out->[0]; | 
| 326 | 8 |  |  |  |  | 74 | $self->{ae_version} =~ s/^git version //; | 
| 327 | 8 |  |  |  |  | 50 | $cv->send($self->{ae_version}); | 
| 328 |  |  |  |  |  |  | } | 
| 329 | 8 |  |  |  |  | 70 | }); | 
| 330 |  |  |  |  |  |  | } | 
| 331 |  |  |  |  |  |  |  | 
| 332 | 10 |  |  |  |  | 312 | $cv; | 
| 333 |  |  |  |  |  |  | } | 
| 334 |  |  |  |  |  |  |  | 
| 335 |  |  |  |  |  |  |  | 
| 336 |  |  |  |  |  |  | 1; | 
| 337 |  |  |  |  |  |  |  | 
| 338 |  |  |  |  |  |  | __END__ |