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