[LrdeTools] 292: Add svn-stats.

https://svn.lrde.epita.fr/svn/lrde-tools/trunk/build-farm Ce script n'�tait enregistr� dans aucun d�p�t SVN. Index: ChangeLog from Roland Levillain <roland@lrde.epita.fr> Add svn-stats. * svn-stats/svn-stats: New. * svn-stats/README: New. README | 9 + svn-stats | 291 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 300 insertions(+) Index: svn-stats/svn-stats --- svn-stats/svn-stats (revision 0) +++ svn-stats/svn-stats (revision 0) @@ -0,0 +1,291 @@ +#! /usr/bin/perl -w +# +# Subversion statistics extractor - svn-stats +# Copyright (C) 2004, 2005, 2006 EPITA Research and Development Laboratory +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +# Author: +# Clement Vasseur <clement.vasseur@lrde.epita.fr> + +use strict; +use Time::Local; +use GD::Graph::hbars; +use GD::Graph::lines; +use GD::Graph::points; + +my $report_dir = "/tmp/stats"; + +my %proj = ( + Transformers => 'https://svn.lrde.epita.fr/svn/transformers', + Vaucanson => 'https://svn.lrde.epita.fr/svn/vaucanson', + Olena => 'https://svn.lrde.epita.fr/svn/oln', + TC => 'https://svn.lrde.epita.fr/svn/tc', + Havm => 'https://svn.lrde.epita.fr/svn/havm', + Nolimips => 'https://svn.lrde.epita.fr/svn/nolimips', + MonoBurg => 'https://svn.lrde.epita.fr/svn/monoburg' +); + +my %alias = ( + 'elrond' => 'raph', + 'noe' => 'benoit', + 'adl' => 'duret_g', + 'pollux' => 'duret_g', + 'levill_r' => 'roland' +); + +my $current_week = &week_from_time(time); + +unless (-d $report_dir) { + system("/bin/mkdir -p \"$report_dir\"") + and die "$0: unable to mkdir `$report_dir'\n"; +} + +&print_css; + +open REPORT, ">$report_dir/index.html" + or die "$0: unable to open `$report_dir/index.html': $!\n"; + +select REPORT; + +print <<HTML; +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" +"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> + <title>LRDE Projects Activity</title> + <link rel="stylesheet" type="text/css" href="style.css" /> + </head> + <body> + <h1>LRDE projects activity statistics</h1> +HTML + +$| = 1; + +foreach (sort keys %proj) { + print STDOUT "$_\n"; + &commits($_, $proj{$_}); +} + +my $date = localtime; + +print <<HTML; + <h4>Automatically generated by <em>svn-stats</em> - $date</h4> + </body> +</html> +HTML +select STDOUT; +close REPORT; + +sub commits { + my ($name, $repository) = @_; + my @commits_week; + my %commits; + my $revision; + + my @log; + $commits_week[$current_week - 1] = 0; + + @log = `svn log -q \"$repository\"`; + + foreach (@log) { + next unless m/^r([^ ]+) \| ([\w \(\)-]+) \| (\d+)-(\d+)-(\d+)/; + print STDOUT '.'; + $revision = $1 unless defined $revision; + my $name = $2; + $name = $alias{$name} if defined $alias{$name}; + $commits{$name}++; + my $time = timegm(0, 0, 0, $5, $4 - 1, $3); + $commits_week[&week_from_time($time) - 1]++ if $3 eq '2006'; + } + print STDOUT "\n"; + + my @data; + my $max = 0; + foreach (sort { $commits{$b} <=> $commits{$a} } keys %commits) { + push @{$data[0]}, $_; + push @{$data[1]}, $commits{$_}; + $max = $commits{$_} if $commits{$_} > $max; + } + $max += 49; + $max -= $max % 50; + + &commits_per_contributor(\@data, "$report_dir/$name.1.png", $max); + +# @data = (); +# foreach (sort { $commits{$b} <=> $commits{$a} } keys %commits) { +# push @{$data[0]}, $_; +# push @{$data[1]}, $commits{$_}; +# } +# +# use Data::Dumper; +# print Dumper(\@data); +# +# &commits_per_contributor_per_week(\@data, "$report_dir/$name.3.png"); + + my $i = 1; + @data = (); + $max = 0; + foreach (@commits_week) { + $_ = 0 unless defined $_; + if ($_ < 170) { + push @{$data[0]}, $i; + push @{$data[1]}, $_; + $max = $_ if $_ > $max; + } + $i++; + } + + $max += 9; + $max -= $max % 10; + + &commits_per_week(\@data, "$report_dir/$name.2.png", $max); + + print <<HTML; + <h2>$name (<span style="color:green">$revision</span>)</h2> + <div> + <img src="$name.1.png" alt="$name 1" /> + <img src="$name.2.png" alt="$name 2" /> + </div> + <hr/> +HTML +} + +sub commits_per_contributor { + my ($data, $filename, $max) = @_; + my $graph = GD::Graph::hbars->new(600, 300); + + $graph->set( + y_label => 'Number of commits', + title => 'Commits per contributor', + dclrs => [ 'green' ], + valuesclr => 'black', + y_max_value => $max, + shadow_depth => 2, + bar_spacing => 3, + y_long_ticks => 1, + x_tick_length => 0, + show_values => 1, + transparent => '' + ) or die $graph->error; + + open IMG, ">$filename" + or die "$0: unable to open `$filename': $!\n"; + binmode IMG; + print IMG $graph->plot($data)->png; + close IMG; +} + +sub commits_per_week { + my ($data, $filename, $max) = @_; + my $graph = GD::Graph::lines->new(600, 300); + + $graph->set( + y_label => 'Number of commits', + x_label => 'Week in 2006', + title => 'Commits per week', + dclrs => [ 'red' ], + valuesclr => 'black', + y_max_value => $max, + shadow_depth => 2, + bar_spacing => 3, + y_long_ticks => 1, + show_values => 1, + transparent => '' + ) or die $graph->error; + + open IMG, ">$filename" + or die "$0: unable to open `$filename': $!\n"; + binmode IMG; + print IMG $graph->plot($data)->png; + close IMG; +} + +sub commits_per_contributor_per_week { + my ($data, $filename) = @_; + my $graph = GD::Graph::points->new(600, 300); + + $graph->set( + title => 'Commits per contributor and per week', + transparent => '' + ) or die $graph->error; + + open IMG, ">$filename" + or die "$0: unable to open `$filename': $!\n"; + binmode IMG; + print IMG $graph->plot($data)->png; + close IMG; +} + +sub week_from_time { + my $time = shift; + my $sday = 0; + my $day_offset = 0; + my ($year) = (localtime $time)[5]; + $year += 1900; + + while ($sday != 1) { + ($sday) = (localtime timelocal(0, 0, 0, 1 + $day_offset, 0, $year))[6]; + $day_offset++; + } + return int(((localtime $time)[7] + (8 - $day_offset)) / 7) + 1; +} + +sub month { + my %months = ( + Jan => 1, Feb => 2, Mar => 3, Apr => 4, May => 5, Jun => 6, + Jul => 7, Aug => 8, Sep => 9, Oct => 10, Nov => 11, Dec => 12 + ); + + my $m = shift; + return $months{$m}; +} + +sub print_css { + open CSS, ">$report_dir/style.css" + or die "$0: unable to open `$report_dir/style.css': $!\n"; + + print CSS <<CSS; +body { + text-align: center; + background-color: #EEEEEE; + font-family: Verdana, Helvetica, sans-serif; +} + +h1,h2,h3,h4,h5,h6 { + font-family: Verdana, Helvetica, sans-serif; + color: #003377; +} + +.left { text-align: left; } +table { margin-left:auto; margin-right:auto; } +h1,h4 { text-align: center; background-color: #CCCCFF; } +h3 { text-align: left; text-indent: 1em } +a { text-decoration: none; color: #003377; } +a:hover { text-decoration: underline; color: #003377; } +pre { text-align: left; font-family: Courier, monospace; } +tr { text-indent: 0em; text-align: center; } +td { text-indent: 0em; font-family: Verdana, Helvetica, sans-serif; } +tr.body { background-color: #E5E5E5; } +td.time { color: gray } +td.st_succeeded { color: green } +td.st_failed { color: red } +td.st_skipped { color: gray } +CSS + + close CSS; +} Property changes on: svn-stats/svn-stats ___________________________________________________________________ Name: svn:executable + * Index: svn-stats/README --- svn-stats/README (revision 0) +++ svn-stats/README (revision 0) @@ -0,0 +1,9 @@ +* svn-stats -*- outline -*- + +A script initially (and still) installed on marvejols that produces +statistics on commits to the Subversion repository of the LRDE. + +svn-stats is to be launched regularly, through cron; for instance, the +crontab of the user build on marjevols contains: + + 0 2 * * * /home/build/svn-stats && rsync -e "ssh -i /home/build/build_farm/id_dsa_build -l pm" -qr /tmp/stats/* goa::svn-stats/
participants (1)
-
Roland Levillain