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