ANSI-Heatmap
view release on metacpan or search on metacpan
examples/git.pl view on Meta::CPAN
#!/usr/bin/perl
use strict;
use warnings;
# Git commits by week by author
use ANSI::Heatmap;
use List::Util qw(max min);
my $LIMIT = 20;
my $PER_ROW = 4;
my $i;
my %day2idx = map { $_ => $i++ } qw(Mon Tue Wed Thu Fri Sat Sun);
my %map;
my %commit_count;
my $repo = shift or die "usage: $0 /path/to/git-repo";
chdir $repo;
open my $log, '-|', 'git', 'log', '--no-merges', '--remove-empty', "--format=%cN\t%cD";
while (<$log>) {
/\A([^\t]+)\t(\w+), \d+ \w+ \d+ (\d+):\d+:\d+ [-+]\d+\Z/ or die "invalid line '$_'";
my ($name, $day, $hour) = ($1, $2, $3);
$day = $day2idx{$day}; defined $day or die "Invalid day";
$commit_count{$name}++;
if (!$map{$name}) {
$map{$name} = ANSI::Heatmap->new(
min_x => 0,
max_x => 23,
min_y => 0,
max_y => 6,
half => 1,
);
}
$map{$name}->inc($hour, $day);
}
my @order = sort { $commit_count{$b} <=> $commit_count{$a} } keys %commit_count;
@order = splice @order, 0, $LIMIT;
my %header = map { $_ => "$_ (" . $commit_count{$_} . ")" } @order;
my @hdrlens = map { length $_ } values %header;
my $hdrwidth = max(@hdrlens);
my $colwidth = max($hdrwidth, 24) + 2;
my $pad = ' ' x ($colwidth - 24);
binmode STDOUT, ':utf8';
while ( my @row = splice @order, 0, $PER_ROW ) {
my $fmt = (('%-' . $colwidth . 's') x @row) . "\n";
printf $fmt, map { $header{$_} } @row;
my @maps = @map{@row};
my @split = map { [ split /\n/, $_ ] } @maps;
for my $line (0..$#{$split[0]}) {
print join '', map { $split[$_][$line] . $pad } 0..$#split;
print "\n";
}
}
( run in 1.045 second using v1.01-cache-2.11-cpan-39bf76dae61 )