package System::Introspector::Repositories::Git;
use Moo;
+use System::Introspector::Util qw(
+ handle_from_command
+ transform_exceptions
+ lines_from_command
+);
+
has root => (
is => 'ro',
default => sub { '/' },
sub gather {
my ($self) = @_;
- my $pipe = $self->_open_locate_git_config_pipe;
- my %location;
- while (defined( my $line = <$pipe> )) {
- chomp $line;
- next unless $line =~ m{^(.+)/\.git/config$};
- my $base = $1;
- $location{ $base } = $self->_gather_git_info($line);
- }
- return \%location;
+ return transform_exceptions {
+ my $pipe = $self->_open_locate_git_config_pipe;
+ my %location;
+ while (defined( my $line = <$pipe> )) {
+ chomp $line;
+ next unless $line =~ m{^(.+)/\.git/config$};
+ my $base = $1;
+ $location{ $base } = $self->_gather_git_info($line);
+ }
+ return { git => \%location };
+ };
}
sub _gather_git_info {
my ($self, $config) = @_;
return {
- config_file => $config,
- config => $self->_gather_git_config($config),
- tracked => $self->_gather_track_info($config),
+ config_file => $config,
+ config => transform_exceptions {
+ $self->_gather_git_config($config);
+ },
+ tracked => transform_exceptions {
+ $self->_gather_track_info($config);
+ },
};
}
sub _gather_track_info {
my ($self, $config) = @_;
(my $git_dir = $config) =~ s{/config$}{};
- my @tracked = $self->_find_tracking($git_dir);
+ return $self->_find_tracking($git_dir);
}
sub _find_tracking {
my ($self, $dir) = @_;
- my $command = sprintf
- q{GIT_DIR=%s git for-each-ref --format '%s' refs/heads},
- $dir,
- q{OK %(refname:short) %(upstream:short)};
- my @lines = `$command 2>&1`;
- chomp @lines;
+ local $ENV{GIT_DIR} = $dir;
+ my @lines = lines_from_command
+ ['git', 'for-each-ref',
+ '--format', q{'OK %(refname:short) %(upstream:short)'},
+ 'refs/heads',
+ ];
my %branch;
for my $line (@lines) {
if ($line =~ m{^OK\s+(\S+)\s+(\S+)?$}) {
my ($local, $remote) = ($1, $2);
$branch{ $local } = {
upstream => $remote,
- changed_files
- => $self->_find_changes($dir, $local, $remote),
- local_commit_count
- => $self->_find_commits($dir, $local, $remote),
+ changed_files => transform_exceptions {
+ $self->_find_changes($dir, $local, $remote);
+ },
+ local_commit_count => transform_exceptions {
+ $self->_find_commits($dir, $local, $remote);
+ },
}
}
else {
my ($self, $dir, $local, $remote) = @_;
return { error => "No remote" }
unless defined $remote;
- my $command = sprintf
- q{GIT_DIR=%s git log --oneline %s..%s},
- $dir, $remote, $local;
- my @lines = `$command 2>&1`;
- return scalar @lines;
+ local $ENV{GIT_DIR} = $dir;
+ my @lines = lines_from_command
+ ['git', 'log', '--oneline', "$remote..$local"];
+ return { count => scalar @lines };
}
sub _find_changes {
my ($self, $dir, $local, $remote) = @_;
return { error => "No remote" }
unless defined $remote;
- my $command = sprintf
- q{GIT_DIR=%s git diff --name-only %s %s},
- $dir, $local, $remote;
- my @lines = `$command 2>&1`;
- chomp @lines;
- return \@lines;
+ local $ENV{GIT_DIR} = $dir;
+ my @lines = lines_from_command
+ ['git', 'diff', '--name-only', $local, $remote];
+ return { list => \@lines };
}
sub _gather_git_config {
my ($name, $value) = split m{=}, $line, 2;
$config{ $name } = $value;
}
- return \%config;
+ return { contents => \%config };
}
sub _open_git_config_pipe {
my ($self, $config) = @_;
- my $command = "git config --file $config --list";
- open my $pipe, '-|', $command
- or die "Unable to open pipe to '$command': $!\n";
- return $pipe;
+ return handle_from_command "git config --file $config --list";
}
sub _open_locate_git_config_pipe {
my ($self) = @_;
- my $root = $self->root;
- $root =~ s{/$}{};
- my $command = sprintf q{locate --regex '^%s/.*\\.git/config$'}, $root;
- open my $pipe, '-|', $command
- or die "Unable to open pipe to '$command': $!\n";
- return $pipe;
+ (my $root = $self->root) =~ s{/$}{};
+ return handle_from_command sprintf
+ q{locate --regex '^%s/.*\\.git/config$'}, $root;
}
1;