1#!/usr/bin/env perl 2# 3# This script can be used to run the cvs log 4# command and extract comments made by a specific user 5# after a specific date. 6# 7# To use this script, first run 8# 9# ./smartlog -u <username> -d <yyyy-mm-dd> or <yyyy/mm/dd> 10# 11# to create a listing of all comments. If this is done in 12# a high level directory, it will take some time to complete. 13# The date can be in either the format 14# yyyy-mm-dd or yyyy/mm/dd. 15# 16# The script outputs two files. The first file is name cvs.log and contains 17# the output of the cvs log command. The second file is name cvs.out 18# contains the output of the comments made by a specific user after 19# a specific date. 20 21################################################################################ 22$FILENAME = "smartlog"; 23# 24# 25$SYNTAX = "$FILENAME [-h] [-u <username>] [-d <yyyy-mm-dd> or <yyyy/mm/dd>]"; 26# 27$DESCRIPTION = <<EOT; 28 [-h] Display usage. 29 [-u username] To specify a different user other than the current user. 30 [-d <yyyy-mm-dd> or <yyyy/mm/dd>] Listing of all comments made by the user <username> after the date <date>. 31EOT 32################################################################################ 33 34use Getopt::Std; 35 36# retrieve options 37if (!getopts('hu:d:')) { 38 print "$SYNTAX\n"; 39 exit; 40} 41 42if ( $opt_h ) { 43 print "$SYNTAX\n\n$DESCRIPTION\n"; 44 exit; 45} 46 47if ( $opt_u ){ 48 $me = $opt_u; 49} 50else{ 51 $me = `whoami`; 52 chop($me); 53} 54 55if( $opt_d ){ 56 $start_date = $opt_d; 57} 58 59$status = `cvs log > cvs.log`; 60if($?){ 61 print "Unable to run cvs log command.\n"; 62 print "Please check to make sure the CVSROOT environment\n"; 63 print "variable is set or that the cvs executable is in your path.\n"; 64 exit 1; 65} 66 67$start_year = 0; 68$start_month = 0; 69$start_day = 0; 70if ($start_date =~ /\s*(\d+)\/0*(\d+)\/0*(\d+)\s*/ || 71 $start_date =~ /\s*(\d+)-0*(\d+)-0*(\d+)\s*/) { 72 $start_year = $1; 73 $start_month = $2; 74 $start_day = $3; 75} 76 77$break; 78$header = ""; 79$comment = ""; 80$output = ""; 81$mycomment = ""; 82$is_me = 0; 83$is_since = 0; 84$is_header = 1; 85$is_comment = 0; 86 87%commentlog = (); 88%filelog = (); 89 90open(CVSLOG, "cvs.log") or die "Unable to open cvs.log file. Did cvs log command run correctly?\n"; 91 92while (<CVSLOG>) { 93 if ($is_header != 0) { 94 if (/-------/) { 95 $is_header = 0; #read through the file til we get to the first -------- 96 $is_comment = 1; 97 $break = $_; 98 } 99 else { 100 if(/RCS file/){ 101 102 $filename = $_; 103 104 if( $filename =~ /(devroot\/\S*)/ ){ #if the file is from the Ecce tree 105 $filename = $1; 106 } 107 elsif ( $filename =~ /(src\/\S*)/ ){ #if the file is from the NWChem tree 108 $filename = $1; 109 } 110 else{ #don't know what tree the file is from, use the full filename 111 } 112 chop($filename); 113 } 114 else{ 115 $header .= $_; 116 } 117 } 118 } 119 else { 120 if (/=======/) { 121 $header = ""; 122 $mycomment = ""; 123 $comment = ""; 124 $is_me = 0; 125 $is_since = 0; 126 $is_header = 1; 127 $is_comment = 0; 128 } 129 elsif (/------/) { 130 if ($is_me != 0 && $is_since != 0) { 131 @mycomment = split(/\n/, $comment); 132 133 $revision = shift(@mycomment); 134 135 if($revision =~ /revision\s+(\S*)/){ 136 $revision = $1; 137 } 138 139 $filedata = shift(@mycomment); 140 141 if($filedata =~ /date:\s+(\d+\/0*\d+\/0*\d+\s+\d+:\d+:\d+)/){ 142 $date = $1; 143 } 144 145 if($filedata =~ /author:\s+(\w+)/){ 146 $author = $1; 147 } 148 149 if($filedata =~ /lines:\s+(\+\d+\s-\d+)/){ 150 $lines = $1; 151 } 152 153 $mycomment = join("\n", @mycomment); 154 $filedata = $filename . $revision . "\t" . $date . "\t" . $author . "\t" . $lines . "\n"; 155 156 157 if ( $filelog{$filedata} ){ 158 $fileog{$filedata} .= $mycomment; 159 } 160 else{ 161 $filelog{$filedata} = $mycomment; 162 } 163 164 165 if ( $commentlog{$mycomment} ){ 166 $commentlog{$mycomment} .= $filedata; 167 } 168 else{ 169 $commentlog{$mycomment} = $filedata; 170 } 171 } 172 $is_me = 0; 173 $is_since = 0; 174 $comment = ""; 175 $mycomment = ""; 176 @mycomment = ""; 177 $revision = ""; 178 $date = ""; 179 $author = ""; 180 $lines = ""; 181 $filedata = ""; 182 } 183 else { 184 if (/$me/) { 185 $is_me = 1; 186 } 187 if (/date:\s+(\d+)\/0*(\d+)\/0*(\d+)/) { 188 $cyear = $1; 189 $cmonth = $2; 190 $cday = $3; 191 if ($cyear > $start_year) { 192 $is_since = 1; 193 } 194 elsif ($cyear == $start_year) { 195 if ($cmonth > $start_month) { 196 $is_since = 1; 197 } 198 elsif ($cmonth == $start_month) { 199 if ($cday >= $start_day) { 200 $is_since = 1; 201 } 202 } 203 } 204 } 205 $comment .= $_; 206 } 207 } 208} 209 210close(CVSLOG); 211$begin = 0; 212$isduplicate = 0; 213@dcomment = ""; 214 215foreach $file (sort keys(%filelog)){ 216 217 $file_key = $filelog{$file}; 218 @fname = split(/,/, $file); 219 220 if ($old_fname eq $fname[0]){ 221 $isduplicate = &Find_Duplicates($file_key, @dcomment); 222 if($isduplicate == 0){ 223 print $fname[1]; 224 } 225 }else{ 226 227 if ($begin == 1){ 228 print "\n=================================="; 229 print "=========================\n\n"; 230 }else{ 231 $begin = 1; 232 } 233 234 print "File: "; 235 print $fname[0]; 236 print "\n"; 237 print $break; 238 print $fname[1]; 239 } 240 241 $record = $commentlog{$file_key}; 242 $isduplicate = &Find_Duplicates($file_key, @dcomment); 243 244 @file_record = split(/\n/, $record); 245 $rlength = @file_record; 246 247 for($i=0; $i < $rlength; $i++){ 248 @frecord= split(/,/, $file_record[$i]); 249 $/ = "\n"; 250 chomp($fname[1]); 251 if($frecord[0] eq $fname[0]){ 252 253 if($frecord[1] ne $fname[1]){ 254 if( $isduplicate == 0 ){ 255 print $frecord[1]; 256 print "\n"; 257 } 258 } 259 }else{ 260 if( $isduplicate == 0){ 261 print "file: "; 262 print $frecord[0]; 263 print " "; 264 print $frecord[1]; 265 print "\n"; 266 } 267 } 268 } 269 if($isduplicate == 0){ 270 print $file_key; 271 push (@dcomment, $file_key); 272 print "\n"; 273 print $break; 274 } 275 $old_fname = $fname[0]; 276} 277 278 279$status = `rm cvs.log`; 280if($?){ 281 print "Unable to remove cvs.log file.\n"; 282 print "File will need to be removed manually.\n"; 283} 284 285 286sub Find_Duplicates{ 287 288 $my_found = 0; 289 my ($my_comment, @my_dcomment) = @_; 290 #$my_found = grep (/$my_comment/, @my_dcomment); 291 $dlength = @my_dcomment; 292 for($k = 0; $k < $dlength; $k++){ 293 if($my_comment eq $my_dcomment[$k]){ 294 $my_found = 1; 295 } 296 } 297 298 return $my_found; 299} 300 301 302