#!/usr/bin/perl -w use strict; use Getopt::Std; use File::Which; use HTML::Template; use CVS::Metrics; my %opts; getopts('d:f:ht:vHS:', \%opts); if ($opts{h}) { print "Usage: $0 [-h] [-f file.log] [-t title] [-d \"dirs ...\"] [-S \"yyyy/mm/dd\"]\n"; print "\t-h : help\n"; print "\t-d \"dirs ...\" : list of directories\n"; print "\t-f file.log : off-line mode\n"; print "\t-t title\n"; print "\t-v : version\n"; print "\t-S start_date : yyyy/mm/dd \n"; exit(0); } if ($opts{v}) { print "$0\n"; print "CVS::Metrics Version $CVS::Metrics::VERSION\n"; exit(0); } my $cfg = ".cvs_metrics"; our ($title, @dirs, $start_date); if ( -r $cfg) { print "reading $cfg\n"; require $cfg; } my $cvs_logfile; if ($opts{f}) { $cvs_logfile = $opts{f}; } else { my $cvs = FindCvs(); $cvs_logfile = $cvs . " log |"; } if ($opts{d}) { my $dirs = $opts{d}; @dirs = split / /, $dirs; } if ($opts{t}) { $title = $opts{t}; } else { $title = "total" unless (defined $title); } if ($opts{S}) { $start_date = $opts{S}; } else { $start_date = "2003/01/01" unless (defined $start_date); } =head1 NAME cvs_activity - Extract metrics from cvs log =head1 SYNOPSYS cvs_activity [B<-h>] [B<-f> I] [B<-t> I] [B<-d> "I<dirs> ..."] [B<-S> I<yyyy/mm/dd>] =head1 OPTIONS =over 8 =item -h Display Usage. =item -d List of directories. =item -f Mode off-line. =item -t Specify the main title. =item -S Specify the start date (yyyy/mm/dd). =back =head1 DESCRIPTION B<cvs_activity> parses B<cvs log> and produces an HTML report. This report is composed of a list of bar charts, each chart represents the activity in a directory from a start date to now. The activity is defined by the number of added or modified files by day. This tool needs File::Which, GD, Chart::Plot::Canvas, HTML::Template and Parse::RecDescent modules. =head2 Configuration file (.cvs_metrics) If present, B<cvs_activity> reads the configuration file F<.cvs_metrics> in the current directory. The file could contains the following variables : $title = "main"; @dirs = ( "abc", "def" , "def/hij" ); $start_date = "2002/01/01"; =head1 SEE ALSO cvs_tklog, cvs_energy =head1 AUTHOR Francois PERRAD, francois.perrad@gadz.org =cut my $parser = new CVS::Metrics::Parser(); if ($parser) { my $cvs_log = $parser->parse($cvs_logfile); GeneratePNG($cvs_log, $title, @dirs); GenerateHTML($title, @dirs); print "Starting browser..."; exec "a_${title}.html"; } ####################################################################### sub FindCvs { my $cvs = which('cvs'); if ( !defined $cvs and $^O eq 'MSWin32' ) { use Win32::TieRegistry(Delimiter => "/"); my $cvs_setting = $Registry->{"HKEY_CURRENT_USER/Software/WinCvs/wincvs/CVS settings"}; $cvs = $cvs_setting->{'/P_WhichCvs'}; if (defined $cvs) { $cvs =~ s/[\000\001]//g; $cvs =~ s/wincvs\.exe\@$//; if ( -e "${cvs}CVSNT\\\\cvs.exe") { $cvs .= "CVSNT\\\\cvs.exe"; } else { $cvs .= "cvs.exe"; } } } die "$cvs not found !\n" unless (defined $cvs); warn "Using CVS : $cvs\n"; return '"' . $cvs . '"'; } ####################################################################### sub GeneratePNG { my ($cvs_log, $title, @dirs) = @_; my $img = $cvs_log->ActivityGD(".", $title, $start_date, 800, 225); if (defined $img) { my $outfile = "a_${title}.png"; $outfile =~ s/\//_/g; open OUT, "> $outfile" or die "can't open $outfile ($!).\n"; binmode OUT, ":raw"; print OUT $img->png(); close OUT; } for my $dir (@dirs) { $img = $cvs_log->ActivityGD($dir, $dir, $start_date, 800, 225); if (defined $img) { my $outfile = "a_${title}_${dir}.png"; $outfile =~ s/\//_/g; open OUT, "> $outfile" or die "can't open $outfile ($!).\n"; binmode OUT, ":raw"; print OUT $img->png(); close OUT; } } } ####################################################################### sub GenerateHTML { my ($title, @dirs) = @_; my $html = q{ <?xml version='1.0' encoding='ISO-8859-1'?> <!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'> <html xmlns='http://www.w3.org/1999/xhtml'> <head> <meta http-equiv='Content-Type' content='text/html; charset=ISO-8859-1' /> <meta name='generator' content='<TMPL_VAR NAME=generator>' /> <meta name='date' content='<TMPL_VAR NAME=date>' /> <title>cvs_activity <!-- TMPL_VAR NAME=title -->



Generated by cvs_activity () }; my $template = new HTML::Template( scalarref => \$html ); die "can't create template ($!).\n" unless (defined $template); my $now = localtime(); my $generator = "cvs_activity " . $CVS::Metrics::VERSION . " (Perl " . $] . ")"; my $path = "a_${title}.png"; $path =~ s/\//_/g; my @loop = ( { header => $title, img => $path } ); for my $dir (@dirs) { $path = "a_${title}_${dir}.png"; $path =~ s/\//_/g; push @loop, { header => $dir, img => $path }; } $template->param( generator => $generator, date => $now, title => $title, loop => \@loop, ); my $filename = "a_${title}.html"; open OUT, "> $filename" or die "can't open $filename ($!)\n"; print OUT $template->output(); close OUT; }