]>
git.p6c8.net - selfforum.git/blob - CVSROOT/syncmail
4 """Complicated notification for CVS checkins.
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.
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:
13 mymodule /path/to/this/script %%s some-email-addr@your.domain
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.
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.
25 It no longer makes sense to run this script from the command line. Doing so
26 will only print out this usage information.
30 %(PROGRAM)s [options] <%%S> email-addr [email-addr ...]
35 Use <path> as the environment variable CVSROOT. Otherwise this
36 variable must exist in the environment.
44 Include # lines of context around lines that differ (default: 2).
47 Produce a context diff (default).
50 Produce a unified diff (smaller, but harder to read).
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.
60 At least one email address.
70 # Notification command
71 MAILCMD
= '/bin/mail -s "CVS: %(SUBJECT)s" %(PEOPLE)s 2>&1 > /dev/null'
76 DIFF_TRUNCATE_IF_LARGER
= 1000
82 def usage(code
, msg
=''):
83 print __doc__
% globals()
90 def calculate_diff(filespec
, contextlines
):
92 file, oldrev
, newrev
= string
.split(filespec
, ',')
95 return '***** Bogus filespec: %s' % filespec
98 if os
.path
.exists(file):
101 update_cmd
= 'cvs -fn update -r %s -p %s' % (newrev
, file)
102 fp
= os
.popen(update_cmd
)
103 lines
= fp
.readlines()
105 lines
.insert(0, '--- NEW FILE: %s ---\n' % file)
107 lines
= ['***** Error reading new file: ',
108 str(e
), '\n***** file: ', file, ' cwd: ', os
.getcwd()]
109 elif newrev
== 'NONE':
110 lines
= ['--- %s DELETED ---\n' % file]
112 # This /has/ to happen in the background, otherwise we'll run into CVS
113 # lock contention. What a crock.
115 difftype
= "-C " + str(contextlines
)
118 diffcmd
= '/usr/bin/cvs -f diff -kk %s -r %s -r %s %s' % (
119 difftype
, oldrev
, newrev
, file)
120 fp
= os
.popen(diffcmd
)
121 lines
= fp
.readlines()
123 # ignore the error code, it always seems to be 1 :(
125 ## return 'Error code %d occurred during diff\n' % (sts >> 8)
126 if len(lines
) > DIFF_TRUNCATE_IF_LARGER
:
127 removedlines
= len(lines
) - DIFF_HEAD_LINES
- DIFF_TAIL_LINES
128 del lines
[DIFF_HEAD_LINES
:-DIFF_TAIL_LINES
]
129 lines
.insert(DIFF_HEAD_LINES
,
130 '[...%d lines suppressed...]\n' % removedlines
)
131 return string
.join(lines
, '')
135 def blast_mail(mailcmd
, filestodiff
, contextlines
):
136 # cannot wait for child process or that will cause parent to retain cvs
137 # lock for too long. Urg!
140 # give up the lock you cvs thang!
142 fp
= os
.popen(mailcmd
, 'w')
143 fp
.write(sys
.stdin
.read())
145 # append the diffs if available
146 for file in filestodiff
:
147 fp
.write(calculate_diff(file, contextlines
))
150 # doesn't matter what code we return, it isn't waited on
155 # scan args for options
159 opts
, args
= getopt
.getopt(sys
.argv
[1:], 'hC:cu',
160 ['context=', 'cvsroot=', 'help'])
161 except getopt
.error
, msg
:
165 for opt
, arg
in opts
:
166 if opt
in ('-h', '--help'):
168 elif opt
== '--cvsroot':
169 os
.environ
['CVSROOT'] = arg
170 elif opt
in ('-C', '--context'):
171 contextlines
= int(arg
)
173 if contextlines
<= 0:
178 # What follows is the specification containing the files that were
179 # modified. The argument actually must be split, with the first component
180 # containing the directory the checkin is being made in, relative to
181 # $CVSROOT, followed by the list of files that are changing.
183 usage(1, 'No CVS module specified')
185 specs
= string
.split(args
[0])
188 # The remaining args should be the email addresses
190 usage(1, 'No recipients specified')
192 # Now do the mail command
193 PEOPLE
= string
.join(args
)
194 mailcmd
= MAILCMD
% vars()
196 print 'Mailing %s...' % PEOPLE
197 if specs
== ['-', 'Imported', 'sources']:
199 if specs
[-3:] == ['-', 'New', 'directory']:
201 print 'Generating notification message...'
202 blast_mail(mailcmd
, specs
[1:], contextlines
)
203 print 'Generating notification message... done.'
207 if __name__
== '__main__':
patrick-canterino.de