1 | #!/usr/athena/bin/perl |
---|
2 | |
---|
3 | # Usage: |
---|
4 | # logfilter subject commit-address diff-adddress |
---|
5 | |
---|
6 | # Mails the CVS commit log to commit-address. Also mails the commit log to |
---|
7 | # diff-address, followed by context diffs of the modified files and the |
---|
8 | # initial contents of added files. |
---|
9 | |
---|
10 | # This script is not specific to any particular repository, but it is |
---|
11 | # specific to the Athena environment in that it assumes the existence |
---|
12 | # of /usr/athena/bin/perl and of mhmail. |
---|
13 | |
---|
14 | open(COMMITMAIL, "|mhmail -s '$ARGV[0]' $ARGV[1]"); |
---|
15 | open(DIFFMAIL, "|mhmail -s '$ARGV[0]' $ARGV[2]"); |
---|
16 | |
---|
17 | # Display the commit log as proffered by CVS. Remember the repository |
---|
18 | # directory, the branch, and the added and modified files. |
---|
19 | while (<STDIN>) { |
---|
20 | print COMMITMAIL; |
---|
21 | print DIFFMAIL; |
---|
22 | if (/^Update of (.*)$/) { |
---|
23 | $repdir = $1; |
---|
24 | } |
---|
25 | if (/^Revision\/Branch: (.*)$/) { |
---|
26 | $branch = $1; |
---|
27 | } |
---|
28 | if (/^Added Files:$/) { |
---|
29 | $line = <STDIN>; |
---|
30 | print COMMITMAIL $line; |
---|
31 | print DIFFMAIL $line; |
---|
32 | $line =~ s/^\s+//; |
---|
33 | @added = split(/\s/, $line); |
---|
34 | } |
---|
35 | if (/^Modified Files:$/) { |
---|
36 | $line = <STDIN>; |
---|
37 | print COMMITMAIL $line; |
---|
38 | print DIFFMAIL $line; |
---|
39 | $line =~ s/^\s+//; |
---|
40 | @modified = split(/\s+/, $line); |
---|
41 | } |
---|
42 | if (/^Log Message:$/) { |
---|
43 | # Flush the rest of the text to avoid confusion. |
---|
44 | while (<STDIN>) { |
---|
45 | print COMMITMAIL; |
---|
46 | print DIFFMAIL; |
---|
47 | } |
---|
48 | } |
---|
49 | } |
---|
50 | |
---|
51 | close COMMITMAIL; |
---|
52 | |
---|
53 | foreach $i (@modified) { |
---|
54 | $rcsfile = "$repdir/$i,v"; |
---|
55 | open(RCSFILE, "<$rcsfile") || die "Can't open $rcsfile"; |
---|
56 | if ($branch) { |
---|
57 | # Skip to the symbols section. |
---|
58 | while (<RCSFILE> !~ /^symbols$/) { |
---|
59 | } |
---|
60 | |
---|
61 | # Compare each symbol with the branch. |
---|
62 | while (($line = <RCSFILE>) =~ /^\s+([^:]+):([0-9\.]+)$/) { |
---|
63 | if ($1 eq $branch) { |
---|
64 | # The prefix is the symbol value without the |
---|
65 | # .0 in the second-to-last slot. The base |
---|
66 | # revision for the branch is the symbol value |
---|
67 | # before the .0. |
---|
68 | die if ($2 !~ /^([0-9\.]+)\.0\.([0-9]+)$/); |
---|
69 | $prefix = $1 . "." . $2 . "."; |
---|
70 | $base = $1; |
---|
71 | } |
---|
72 | } |
---|
73 | } else { |
---|
74 | $prefix = "1."; |
---|
75 | } |
---|
76 | |
---|
77 | # Scan for revisions starting with the prefix. |
---|
78 | $maxrev = 0; |
---|
79 | while (<RCSFILE>) { |
---|
80 | if (/^[0-9\.]+$/) { |
---|
81 | # It's a revision number; does it start with $prefix? |
---|
82 | chop; |
---|
83 | if (substr($_, 0, length($prefix)) eq $prefix) { |
---|
84 | $rev = substr($_, length($prefix)); |
---|
85 | next if ($rev !~ /^[0-9]+$/); |
---|
86 | |
---|
87 | # Remember the highest revision we've seen. |
---|
88 | if ($rev > $maxrev) { |
---|
89 | $maxrev = $rev; |
---|
90 | } |
---|
91 | } |
---|
92 | } |
---|
93 | if (/^desc$/) { |
---|
94 | last; |
---|
95 | } |
---|
96 | } |
---|
97 | close RCSFILE; |
---|
98 | |
---|
99 | # Determine current and previous revision. |
---|
100 | if ($maxrev == 0 || ($maxrev == 1 && !$branch)) { |
---|
101 | die "Couldn't find suitable current revision."; |
---|
102 | } |
---|
103 | $current = $prefix . $maxrev; |
---|
104 | $prev = ($maxrev == 1) ? $base : $prefix . ($maxrev - 1); |
---|
105 | |
---|
106 | # Add the diff to the mail message. |
---|
107 | print DIFFMAIL "\n"; |
---|
108 | print DIFFMAIL "==================================================\n"; |
---|
109 | print DIFFMAIL "Differences for $i (revision $prev -> $current)\n"; |
---|
110 | print DIFFMAIL "==================================================\n"; |
---|
111 | open(DIFF, "rcsdiff -c -kk -r$prev -r$current $rcsfile 2>/dev/null|"); |
---|
112 | print DIFFMAIL while (<DIFF>); |
---|
113 | close DIFF; |
---|
114 | } |
---|
115 | |
---|
116 | foreach $i (@added) { |
---|
117 | print DIFFMAIL "\n"; |
---|
118 | print DIFFMAIL "==================================================\n"; |
---|
119 | print DIFFMAIL "Initial contents of new file $i\n"; |
---|
120 | print DIFFMAIL "==================================================\n"; |
---|
121 | open(DIFF, "diff -c /dev/null $i|"); |
---|
122 | print DIFFMAIL while (<DIFF>); |
---|
123 | close DIFF; |
---|
124 | } |
---|
125 | |
---|
126 | close DIFFMAIL; |
---|