/[rdesktop]/sourceforge.net/trunk/CVSROOT/syncmail
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /sourceforge.net/trunk/CVSROOT/syncmail

Parent Directory Parent Directory | Revision Log Revision Log


Revision 41 - (hide annotations)
Sat Apr 6 05:11:05 2002 UTC (22 years, 2 months ago) by matthewc
File size: 7195 byte(s)
Setting up syncmail (3.18) to report CVS changes to rdesktop-cvs.

1 matthewc 41 #! /usr/bin/python
2     # -*- Python -*-
3    
4     """Complicated notification for CVS checkins.
5    
6     This script is used to provide email notifications of changes to the CVS
7     repository. These email changes will include context diffs of the changes.
8     Really big diffs will be trimmed.
9    
10     This script is run from a CVS loginfo file (see $CVSROOT/CVSROOT/loginfo). To
11     set this up, create a loginfo entry that looks something like this:
12    
13     mymodule /path/to/this/script %%s some-email-addr@your.domain
14    
15     In this example, whenever a checkin that matches `mymodule' is made, this
16     script is invoked, which will generate the diff containing email, and send it
17     to some-email-addr@your.domain.
18    
19     Note: This module used to also do repository synchronizations via
20     rsync-over-ssh, but since the repository has been moved to SourceForge,
21     this is no longer necessary. The syncing functionality has been ripped
22     out in the 3.0, which simplifies it considerably. Access the 2.x versions
23     to refer to this functionality. Because of this, the script is misnamed.
24    
25     It no longer makes sense to run this script from the command line. Doing so
26     will only print out this usage information.
27    
28     Usage:
29    
30     %(PROGRAM)s [options] <%%S> email-addr [email-addr ...]
31    
32     Where options is:
33    
34     --cvsroot=<path>
35     Use <path> as the environment variable CVSROOT. Otherwise this
36     variable must exist in the environment.
37    
38     --help
39     -h
40     Print this text.
41    
42     --context=#
43     -C #
44     Include # lines of context around lines that differ (default: 2).
45    
46     -c
47     Produce a context diff (default).
48    
49     -u
50     Produce a unified diff (smaller, but harder to read).
51    
52     <%%S>
53     CVS %%s loginfo expansion. When invoked by CVS, this will be a single
54     string containing the directory the checkin is being made in, relative
55     to $CVSROOT, followed by the list of files that are changing. If the
56     %%s in the loginfo file is %%{sVv}, context diffs for each of the
57     modified files are included in any email messages that are generated.
58    
59     email-addrs
60     At least one email address.
61    
62     """
63    
64     import os
65     import sys
66     import string
67     import time
68     import getopt
69    
70     # Notification command
71     MAILCMD = '/bin/mail -s "CVS: %(SUBJECT)s" %(PEOPLE)s 2>&1 > /dev/null'
72    
73     # Diff trimming stuff
74     DIFF_HEAD_LINES = 20
75     DIFF_TAIL_LINES = 20
76     DIFF_TRUNCATE_IF_LARGER = 1000
77    
78     PROGRAM = sys.argv[0]
79    
80     BINARY_EXPLANATION_LINES = [
81     "(This appears to be a binary file; contents omitted.)\n"
82     ]
83    
84    
85     def usage(code, msg=''):
86     print __doc__ % globals()
87     if msg:
88     print msg
89     sys.exit(code)
90    
91    
92    
93     def calculate_diff(filespec, contextlines):
94     try:
95     file, oldrev, newrev = string.split(filespec, ',')
96     except ValueError:
97     # No diff to report
98     return '***** Bogus filespec: %s' % filespec
99     if oldrev == 'NONE':
100     try:
101     if os.path.exists(file):
102     fp = open(file)
103     else:
104     update_cmd = 'cvs -fn update -r %s -p %s' % (newrev, file)
105     fp = os.popen(update_cmd)
106     lines = fp.readlines()
107     fp.close()
108     # Is this a binary file? Let's look at the first few
109     # lines to figure it out:
110     for line in lines[:5]:
111     for c in string.rstrip(line):
112     if c < ' ' or c > chr(127):
113     lines = BINARY_EXPLANATION_LINES[:]
114     break
115     lines.insert(0, '--- NEW FILE: %s ---\n' % file)
116     except IOError, e:
117     lines = ['***** Error reading new file: ',
118     str(e), '\n***** file: ', file, ' cwd: ', os.getcwd()]
119     elif newrev == 'NONE':
120     lines = ['--- %s DELETED ---\n' % file]
121     else:
122     # This /has/ to happen in the background, otherwise we'll run into CVS
123     # lock contention. What a crock.
124     if contextlines > 0:
125     difftype = "-C " + str(contextlines)
126     else:
127     difftype = "-u"
128     diffcmd = "/usr/bin/cvs -f diff -kk %s --minimal -r %s -r %s '%s'" % (
129     difftype, oldrev, newrev, file)
130     fp = os.popen(diffcmd)
131     lines = fp.readlines()
132     sts = fp.close()
133     # ignore the error code, it always seems to be 1 :(
134     ## if sts:
135     ## return 'Error code %d occurred during diff\n' % (sts >> 8)
136     if len(lines) > DIFF_TRUNCATE_IF_LARGER:
137     removedlines = len(lines) - DIFF_HEAD_LINES - DIFF_TAIL_LINES
138     del lines[DIFF_HEAD_LINES:-DIFF_TAIL_LINES]
139     lines.insert(DIFF_HEAD_LINES,
140     '[...%d lines suppressed...]\n' % removedlines)
141     return string.join(lines, '')
142    
143    
144    
145     def blast_mail(mailcmd, filestodiff, contextlines):
146     # cannot wait for child process or that will cause parent to retain cvs
147     # lock for too long. Urg!
148     if not os.fork():
149     # in the child
150     # give up the lock you cvs thang!
151     time.sleep(2)
152     fp = os.popen(mailcmd, 'w')
153     fp.write(sys.stdin.read())
154     fp.write('\n')
155     # append the diffs if available
156     for file in filestodiff:
157     fp.write(calculate_diff(file, contextlines))
158     fp.write('\n')
159     fp.close()
160     # doesn't matter what code we return, it isn't waited on
161     os._exit(0)
162    
163    
164    
165     # scan args for options
166     def main():
167     contextlines = 2
168     try:
169     opts, args = getopt.getopt(sys.argv[1:], 'hC:cu',
170     ['context=', 'cvsroot=', 'help'])
171     except getopt.error, msg:
172     usage(1, msg)
173    
174     # parse the options
175     for opt, arg in opts:
176     if opt in ('-h', '--help'):
177     usage(0)
178     elif opt == '--cvsroot':
179     os.environ['CVSROOT'] = arg
180     elif opt in ('-C', '--context'):
181     contextlines = int(arg)
182     elif opt == '-c':
183     if contextlines <= 0:
184     contextlines = 2
185     elif opt == '-u':
186     contextlines = 0
187    
188     # What follows is the specification containing the files that were
189     # modified. The argument actually must be split, with the first component
190     # containing the directory the checkin is being made in, relative to
191     # $CVSROOT, followed by the list of files that are changing.
192     if not args:
193     usage(1, 'No CVS module specified')
194     SUBJECT = args[0]
195     specs = string.split(args[0])
196     del args[0]
197    
198     # The remaining args should be the email addresses
199     if not args:
200     usage(1, 'No recipients specified')
201    
202     # Now do the mail command
203     PEOPLE = string.join(args)
204     mailcmd = MAILCMD % vars()
205    
206     print 'Mailing %s...' % PEOPLE
207     if specs == ['-', 'Imported', 'sources']:
208     return
209     if specs[-3:] == ['-', 'New', 'directory']:
210     del specs[-3:]
211     elif len(specs) > 2:
212     L = specs[:2]
213     for s in specs[2:]:
214     prev = L[-1]
215     if string.count(prev, ",") < 2:
216     L[-1] = "%s %s" % (prev, s)
217     else:
218     L.append(s)
219     specs = L
220     print 'Generating notification message...'
221     blast_mail(mailcmd, specs[1:], contextlines)
222     print 'Generating notification message... done.'
223    
224    
225    
226     if __name__ == '__main__':
227     main()
228     sys.exit(0)

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26