[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: CVS Statistics
From: |
Jerry Nairn |
Subject: |
RE: CVS Statistics |
Date: |
Mon, 26 Nov 2001 14:50:01 -0800 |
> From: address@hidden [mailto:address@hidden
> Sent: Monday, November 26, 2001 2:02 AM
> I would like to know the statistics on a particular file ( say test.c
> ) from one version to another version ( say from 1.2 to 1.7 ).
>
> So for instance if i run the command/script
> <cvs_command> -R1.2 -R2.7 test.c
> i would like to know the number of lines added, deleted and modified
> between version 1.2 to 1.7 for test.c
Here's a perl script to do this.
Jerry
=====================================================
#!/usr/bin/perl -w
#
# diffcounter - Jerry Nairn, address@hidden
# based on diffdetailer by Josh Geller.
#
use strict;
use Cwd;
use vars qw(
$infile
$outfile
$first_arg
$second_arg
$modules
$workdir
$pwd
%extension
);
&input;
&seperate;
&cleanup;
sub input {
my @array;
if( ! ( $#ARGV > 1 ) ) {
print STDERR "Usage: $0 FIRST_ARG SECOND_ARG MODULE(S)\n";
print STDERR "Where ARGs are of the form -rTAG or -Ddate\n";
exit 1;
} else {
$first_arg = shift @ARGV;
if ( $first_arg !~ /^\-/ ) { $first_arg = "-r" . $first_arg };
$second_arg = shift @ARGV;
if ( $second_arg !~ /^\-/ ) { $second_arg = "-r" . $second_arg };
$modules = join " ",@ARGV;
$infile = "/tmp/temp_$$";
$workdir = "/tmp/WORK_$$";
mkdir($workdir, 0755);
}
$pwd = getcwd();
chdir($workdir);
system("cd $workdir; cvs -Q checkout $second_arg $modules");
open(INPIPE, "cvs -Q rdiff -s $first_arg $second_arg $modules|")
|| die "Could not open pipe: $! \n";
@array = <INPIPE>;
close(INPIPE);
open(INFILE, ">$infile") || die "Could not open $infile for writing: $!
\n";
foreach (@array) {
chomp;
print INFILE "$_ \n";
}
close(INFILE);
}
sub seperate {
my @new;
my @removed;
my @changed;
my @unknown;
my $numlines;
my $addedlines = 0;
my $removedlines = 0;
my $modifiedlines = 0;
my $print_arg1 = substr(${first_arg},2);
my $print_arg2 = substr(${second_arg},2);
my $report = "change_count.txt";
if ( substr(${second_arg},0,2) eq "-r" ) {
$report = $print_arg2 . "_change_count.txt";
}
open(INFILE, "<$infile") || die "Could not open $infile for reading: $!
\n";
chdir $pwd;
open(OUTFILE, ">$report") || die "Could not open $report for writing: $!
\n";
foreach (<INFILE>) {
chomp;
if(m/^.*\s(\S+)\s\w+\snew.*revision\s?([0-9].*[0-9])?\s*$/) {
push @new, "$1 $2";
} elsif(m/^.*\s(\S+)\sis\sremoved;\s(.*)$/) {
push @removed, "$1 has been removed, $2";
} elsif(m/^.*\s(\S+)\schanged.*revision\s?([0-9].*[0-9])?\s*$/) {
push @changed, "$1 $2";
} else {
push @unknown, $_;
}
}
if ( @new ) {
print OUTFILE <<EOT;
###
### Files added before $print_arg2
### (not in $print_arg1): Revision:
EOT
foreach(@new) {
m/(\S+)\s+(\S+)/;
$numlines = countlines($1,"-r$2",1);
print OUTFILE "$_\n";
print OUTFILE "$numlines\n";
}
}
if ( @removed ) {
print OUTFILE <<EOT;
###
### Files removed after $print_arg1
### (not in $print_arg2):
EOT
foreach(@removed) {
m/(\S+) has been removed.*/;
$numlines = countlines($1,$first_arg,0);
print OUTFILE "$_\n";
print OUTFILE "$numlines\n";
}
}
if ( @changed ) {
print OUTFILE <<EOT;
###
### Files changed between
### $print_arg1 and $print_arg2: Revisions:
EOT
foreach(@changed) {
m/(\S+)\s+(\S+) to (\S+)/;
$numlines = countdiff($1,$2,$3);
print OUTFILE "$_\n";
print OUTFILE "$numlines\n";
}
}
if ( @unknown ) {
print OUTFILE <<EOT;
###
### Lines from cvs rdiff which I could not interpret:
EOT
foreach(@unknown) {
print OUTFILE "$_\n";
}
}
if ( %extension ) {
print OUTFILE <<EOT;
###
### Summary of Affected Lines of Code, by File Name Extension:
## .ext| deleted| added| modified|
EOT
my $ext;
my $sumtotal;
foreach $ext ( sort keys %extension ) {
printf OUTFILE "%14s|%9d|%9d|%9d|\n", $ext,
address@hidden,
address@hidden,
address@hidden;
$sumtotal += address@hidden +
address@hidden +
address@hidden;
}
print OUTFILE "\n### $sumtotal Total Lines Affected, $print_arg1 to
$print_arg2\n";
}
close OUTFILE;
}
sub cleanup {
system("rm -rf $infile $workdir");
}
sub countlines {
my $filename = shift;
my $revision = shift;
my $newfile = shift;
my $result = "(binary file)";
my $lines = 0;
my $ext;
chdir($workdir);
system("cvs -Q -f up $revision $filename");
if ( iscvstext($filename) ) {
$lines = `wc -l < "$filename" | tr -d " "`;
chomp $lines;
$result = "($lines total lines)";
$ext = get_ext($filename);
if ( $newfile ) {
&ext_count($ext, 0, $lines, 0);
} else {
&ext_count($ext, $lines, 0, 0);
}
}
chdir($pwd);
return $result;
}
sub countdiff {
my $filename = shift;
my $revision1 = shift;
my $revision2 = shift;
my $result = "(binary file)";
my @diffout;
my $line;
my $ext;
my $linescut = 0;
my $linesnew = 0;
my $linesmod = 0;
my $inmod = 0;
my $cuthere = 0;
chdir($workdir);
if ( iscvstext($filename) ) {
@diffout = `cvs -Q diff -u -r$revision1 -r$revision2 $filename`;
while ( $line = shift @diffout ) {
if ( $line =~ /^\+\+\+.*/ ) {
last;
}
}
# A stretch of /^\-/ lines followed by the same number of /^\+/ lines
# is really a set of modified lines, not one set of deleted and one
# set of added lines.
while ( $line = shift @diffout ) {
if ( $line =~ /^\-.*/ ) {
# found a removed or modified line
# we are probably in a modification
$inmod = 1;
$cuthere++;
} elsif ( $line =~ /^\+.*/ ) {
# found an added or modified line
if ( $inmod && $cuthere ) {
# decided it was modified
$cuthere--;
$linesmod++;
} else {
# decided it was added
$linescut += $cuthere;
$cuthere = $inmod = 0;
$linesnew++;
}
} elsif ( $line =~ /^(\s|\@).*/ ) {
# found an unchanged line
$linescut += $cuthere;
$cuthere = $inmod = 0;
}
}
$result = "(";
if ( $linescut ) {
$result .= "$linescut removed";
}
if ( $linesnew ) {
if ( $linescut ) {
$result .= ", ";
}
$result .= "$linesnew added";
}
if ( $linesmod ) {
if ( $linesnew || $linescut ) {
$result .= ", ";
}
$result .= "$linesmod modified";
}
$result .= " lines)";
$ext = get_ext($filename);
&ext_count($ext, $linescut, $linesnew, $linesmod);
}
chdir($pwd);
return $result;
}
sub get_ext {
my $filename = shift;
my $ext;
($ext = $filename) =~ s/^.*(\.[^\.]+)$/$1/;
if ( $ext eq $filename ) {
$ext = "NONE";
}
return $ext;
}
sub iscvstext {
my $filename = shift;
chdir($workdir);
my @options= grep s/^\s+Sticky Options:\s+(\S+)\s*$/$1/, `cvs stat
"${filename}"`;
return 0 if ( $options[0] ne "(none)" );
return 1;
}
sub ext_count {
my $ext = shift;
my $cutlines = shift;
my $newlines = shift;
my $modlines = shift;
my @extlines = ($cutlines, $newlines, $modlines);
if ( $extension{$ext} ) {
address@hidden += $extlines[0];
address@hidden += $extlines[1];
address@hidden += $extlines[2];
} else {
address@hidden = $extlines[0];
address@hidden = $extlines[1];
address@hidden = $extlines[2];
}
}
- CVS Statistics, Desikan Narayanan, 2001/11/26
- RE: CVS Statistics,
Jerry Nairn <=