--- /dev/null
+package System::Introspector::Report::Builder::Repositories::Git::Locations;
+use Moo;
+
+extends 'System::Introspector::Report::Builder';
+
+has collect_matching => (is => 'ro', default => sub { [] });
+has _locations_by_origin => (is => 'lazy', default => sub { {} });
+
+sub required_data {
+ return qw(
+ repositories/git
+ host
+ );
+}
+
+sub _match_origin {
+ my ($self, $origin) = @_;
+ my @match_rx = @{ $self->collect_matching };
+ for my $rx (@match_rx) {
+ if ($origin =~ qr{^$rx$}i) {
+ return $1;
+ }
+ }
+ return undef;
+}
+
+sub collect_from {
+ my ($self, $remote, $data) = @_;
+ my $git = $data->{'repositories/git'}{git} || {};
+ for my $location (keys %$git) {
+ my $origin = $git->{$location}{config}{contents}{'remote.origin.url'}
+ or next;
+ my $matched = $self->_match_origin($origin)
+ or next;
+ push @{$self->_locations_by_origin->{$matched}}, {
+ remote => $remote,
+ hostname => $data->{host}{hostname},
+ location => $location,
+ origin => $origin,
+ };
+ }
+ return 1;
+}
+
+sub render_reports {
+ my ($self) = @_;
+ my @columns = (
+ { key => 'remote', label => 'Remote Host' },
+ { key => 'hostname', label => 'Hostname' },
+ { key => 'location', label => 'Location' },
+ );
+ my $collected = $self->_locations_by_origin;
+ return map {
+ my $identifier = $_;
+ my $rows = $collected->{$identifier};
+ {
+ columns => [@columns],
+ title => "$identifier Checkouts",
+ id => ['repositories-git-locations', $identifier],
+ rowid => [qw( remote location )],
+ meta => { repository => $identifier },
+ rows => [
+ sort {
+ ($a->{remote} cmp $b->{remote})
+ ||
+ ($a->{location} cmp $b->{location})
+ } @$rows,
+ ],
+ };
+ } keys %$collected;
+}
+
+1;