1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
|
#!/usr/bin/perl
#/**
# *
# * stats_cvs.pl - NIGHTLY SCRIPT
# *
# * Recurses through the /cvsroot directory tree and parses each projects
# * '~/CVSROOT/history' file, and create and fill the sql table with
# * modified, and added to each project.
# *
# * @version $Id: stats_cvs.pl,v 1.1.1.1 2004/05/16 16:52:23 lo-lan-do Exp $
# *
# */
# For the files
#use strict;
use Time::Local;
use POSIX qw( strftime );
# For the database
use DBI;
require("/usr/lib/gforge/lib/include.pl");
my $cvsroot = "/var/lib/gforge/chroot/cvsroot";
my $verbose = 1;
$|=0 if $verbose;
$|++;
sub drop_tables {
db_drop_table_if_exists ("deb_cvs_dump") ;
db_drop_table_if_exists ("deb_cvs_group") ;
db_drop_table_if_exists ("deb_cvs_group_user") ;
}
sub create_dump_table {
my ($sql);
$sql = "CREATE TABLE deb_cvs_dump (
type char(1),
year integer NOT NULL,
month integer NOT NULL,
day integer NOT NULL,
time integer NOT NULL,
cvsuser text,
cvsgroup text
)";
$dbh->do( $sql );
}
sub dump_history {
my ($year, $month, $day, $day_begin, $day_end);
print "Running tree at $cvsroot/\n";
chdir( "$cvsroot" ) || die("Unable to make $cvsroot the working directory.\n");
foreach $group ( glob("*") ) {
next if ( ! -d "$group" );
my ($cvs_co, $cvs_commit, $cvs_add, %usr_commit, %usr_add );
print "Parsing $group/\n";
open(HISTORY, "< $cvsroot/$group/CVSROOT/history") or print "E::Unable to open history for $group\n";
while ( <HISTORY> ) {
my ($time_parsed, $type, $cvstime, $user, $curdir, $module, $rev, $file );
## Split the cvs history entry into it's 6 fields.
($cvstime,$user,$curdir,$module,$rev,$file) = split(/\|/, $_, 6 );
## log modified $type eq "M"
## log added $type eq "A"
## log others $type neq "A" neq "M"
$type = substr($cvstime, 0, 1);
$time_parsed = hex( substr($cvstime, 1, 8) );
$year = strftime("%Y", gmtime( $time_parsed ) );
$month = strftime("%m", gmtime( $time_parsed ) );
$day = strftime("%d", gmtime( $time_parsed ) );
$sql = "INSERT INTO deb_cvs_dump
(type,year,month,day,time,cvsuser,cvsgroup)
VALUES ('$type','$year','$month','$day','$time_parsed','$user','$group')";
#print "$sql";
$dbh->do( $sql );
}
close( HISTORY );
}
}
sub parse_history {
my ($sql);
# CVS doc says the meaning of the code letters.
#
#Letter Meaning
#====== =========================================================
#O Checkout
#T Tag
#F Release
#W Update (no user file, remove from entries file)
#U Update (file overwrote unmodified user file)
#G Update (file was merged successfully into modified user file)
#C Update (file was merged, but conflicts w/ modified user file)
#M Commit (from modified file)
#A Commit (an added file)
#R Commit (the removal of a file)
#E Export
$sql = "
CREATE TABLE deb_cvs_group_user AS
SELECT agg.cvsgroup,agg.cvsuser,agg.year,agg.month,agg.day,agg.total AS total,m.modified AS modified,a.added AS added,o.others AS others
FROM (
SELECT cvsgroup,cvsuser,year,month,day,COUNT(*) AS total
FROM deb_cvs_dump
GROUP BY year,month,day,cvsgroup,cvsuser
) agg
LEFT JOIN (
SELECT cvsgroup,cvsuser,year,month,day,COUNT(*) AS modified
FROM deb_cvs_dump
WHERE type='M'
GROUP BY year,month,day,cvsgroup,cvsuser
) m USING (cvsgroup,cvsuser,year,month,day)
LEFT JOIN (
SELECT cvsgroup,cvsuser,year,month,day,COUNT(*) AS added
FROM deb_cvs_dump
WHERE type='A'
GROUP BY year,month,day,cvsgroup,cvsuser
) a USING (cvsgroup,cvsuser,year,month,day)
LEFT JOIN (
SELECT cvsgroup,cvsuser,year,month,day,COUNT(*) AS others
FROM deb_cvs_dump
WHERE type!='A' and type!='M'
GROUP BY year,month,day,cvsgroup,cvsuser
) o USING (cvsgroup,cvsuser,year,month,day)
";
$dbh->do( $sql );
}
sub print_stats {
my ($sql,$res,$temp);
$sql = "SELECT * FROM deb_cvs_group_user order by year, month, day";
$res = $dbh->prepare($sql);
$res->execute();
while ( my ($cvsgroup, $cvsuser, $year, $month, $day, $total, $modified, $added, $others) = $res->fetchrow()) {
print "$cvsgroup $cvsuser $year $month $day $total=$modified+$added+$others\n";
}
print "-----------------------------------------------------\n";
print "cvsgroup\tcvsuser\tmodified\tadded\tothers\n";
print "-----------------------------------------------------\n";
$sql = "SELECT cvsgroup, cvsuser, SUM(modified), SUM(added), SUM(others) FROM deb_cvs_group_user group by cvsgroup,cvsuser";
$res = $dbh->prepare($sql);
$res->execute();
while ( my ($cvsgroup, $cvsuser, $modified, $added, $others) = $res->fetchrow()) {
print "$cvsgroup\t$cvsuser\t$modified\t$added\t$others\n";
}
print "-----------------------------------------------------\n";
}
sub cvs_stats_merge {
print "-----------------------------------------------------\n";
print "Inserting cvs data into\n";
print "-----------------------------------------------------\n";
my ($sql,$res,$temp);
$sql = "DELETE FROM stats_cvs_group
WHERE (month,day,group_id) IN (
SELECT d.month+ d.year*100,
d.day,g.group_id
FROM deb_cvs_group_user AS d, groups AS g
WHERE d.cvsgroup=g.unix_group_name
GROUP BY d.month,d.year,d.day,g.group_id
)";
$dbh->do ( $sql );
$sql = "INSERT INTO stats_cvs_group
SELECT d.month + d.year * 100,
d.day,g.group_id,
sum(coalesce(d.others,0)),
sum(coalesce(d.modified,0)),
sum(COALESCE(d.added,0))
FROM deb_cvs_group_user AS d,groups AS g
WHERE d.cvsgroup=g.unix_group_name
and (d.month + d.year * 100,
d.day,
g.group_id) NOT IN (
SELECT month,day,group_id FROM stats_cvs_group
)
GROUP BY year,month,day,group_id
";
$dbh->do ( $sql );
$sql = "DELETE FROM stats_cvs_user
WHERE (month,day,group_id,user_id) IN (
SELECT d.month+ d.year*100,
d.day,g.group_id,u.user_id
FROM deb_cvs_group_user AS d, groups AS g, users as u
WHERE d.cvsgroup=g.unix_group_name AND d.cvsuser=u.user_name
GROUP BY d.month,d.year,d.day,g.group_id,u.user_id
)";
$dbh->do ( $sql );
$sql = "INSERT INTO stats_cvs_user
SELECT d.month + d.year * 100,
d.day,
g.group_id,
u.user_id,
sum(coalesce(d.others,0)),
sum(coalesce(d.modified,0)),
sum(COALESCE(d.added,0))
FROM deb_cvs_group_user AS d,groups AS g, users AS u
WHERE d.cvsgroup=g.unix_group_name and
d.cvsuser=u.user_name
and (d.month + d.year * 100,
d.day,
g.group_id,
u.user_id) NOT IN (
SELECT month,day,group_id,user_id FROM stats_cvs_user
)
GROUP BY year,month,day,group_id,user_id
";
$dbh->do ( $sql );
print " [ x ] Done\n";
}
#############
# main #
#############
&db_connect;
&drop_tables;
&create_dump_table;
&dump_history;
&parse_history;
&print_stats;
&cvs_stats_merge;
&drop_tables;
|