more info fetching for Repositories::Git probe
Robert 'phaylon' Sedlacek [Tue, 8 May 2012 16:38:29 +0000 (16:38 +0000)]
lib/System/Introspector/Repositories/Git.pm

index 66776eb..ab8ccc3 100644 (file)
@@ -1,6 +1,11 @@
 package System::Introspector::Repositories::Git;
 use Moo;
 
+has root => (
+    is      => 'ro',
+    default => sub { '/' },
+);
+
 sub gather {
     my ($self) = @_;
     my $pipe = $self->_open_locate_git_config_pipe;
@@ -19,9 +24,66 @@ sub _gather_git_info {
     return {
         config_file     => $config,
         config          => $self->_gather_git_config($config),
+        tracked         => $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);
+}
+
+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;
+    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),
+            }
+        }
+        else {
+            return { error => join "\n", @lines };
+        }
+    }
+    return { branches => \%branch };
+}
+
+sub _find_commits {
+    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;
+}
+
+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;
+}
+
 sub _gather_git_config {
     my ($self, $config) = @_;
     my $pipe = $self->_open_git_config_pipe($config);
@@ -44,7 +106,9 @@ sub _open_git_config_pipe {
 
 sub _open_locate_git_config_pipe {
     my ($self) = @_;
-    my $command = 'locate .git/config';
+    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;