The code is
#!/bin/bash
date1=$(date -v -180d +'%Y-%m-%d')
date2=$(date -v -1d +'%Y-%m-%d')
svn='svn+ssh://.../branches'
svn log --revision {$date1}:{$date2} $svn | perl -e '
my %D = (); # dates
my %U = (); # users
while( <> ) {
if ( /\| (.*?) \| (\d\d\d\d-\d\d-\d\d) / ) {
my $u = $1;
my $d = $2;
$D{$d} ||= {};
$D{$d}->{$u} += 1;
$U{$u} = 1;
}
}
my @d = sort keys %D;
my ( $l ) = reverse sort map { length($_); } @d; # max length
for my $u ( sort keys %U ) {
printf( "%*s %s | ", -$l, $u, $d[0] );
for my $d ( @d ) {
print $D{$d}->{$u} ? "*" : "-";
}
printf( " | %s\n", $d[$#d] );
}
'
# END
Update: A failing of this script is that it only shows days with activity. Days without activity by any developer will be missing from the timeline. I replaced this script with this one#!/usr/bin/perl -w
use strict;
use DateTime;
my $svn_url='svn+ssh://.../branches';
my $stop = DateTime->today();
my $start = $stop->clone()->subtract( days => shift @ARGV || 90 );
my %W = (); # week days
my %D = (); # dates
my %U = (); # users
# initialize the dates and the weekdays hashs with days between the start and stop dates
for ( my $next = $start->clone(); $next->compare($stop) <= 0; $next->add( days => 1) ) {
my $F = $next->strftime('%Y-%m-%d');
$D{$F} = {};
$W{$F} = $next->day_of_week();
}
# collect the svn usage data
if ( open( IN, "svn log --revision \{$start\}:\{$stop\} $svn_url |" ) ) {
while( <IN> ) {
if ( /\| (.*?) \| (\d\d\d\d-\d\d-\d\d) / ) {
my $u = $1;
my $d = $2;
if ( defined $D{$d} ) {
$D{$d}->{$u} += 1;
$U{$u} = 1;
}
}
}
close(IN);
}
my @d = sort keys %D;
my ( $l ) = reverse sort { $a <=> $b } map { length($_); } keys %U; # max user length
# output the chart
for my $u ( sort keys %U ) {
printf( "%*s %s | ", -$l, $u, $d[0] );
for my $d ( @d ) {
print $D{$d}->{$u} ? "*" : "-";
}
printf( " | %s\n", $d[$#d] );
}
# output the line of mondays
printf( "%*s %*s | ", -$l, "", length($d[0]), "" );
for my $d ( @d ) {
print $W{$d} == 1 ? "M" : " ";
}
printf( " |\n" );
# END