Correct constraint names in preprocess for MySQL producer
[dbsrgits/SQL-Translator.git] / CVSROOT / syncmail
CommitLineData
f0630c2d 1#!/usr/bin/python
2# -*- Python -*-
3
4"""Complicated notification for CVS checkins.
5
6This script is used to provide email notifications of changes to the CVS
7repository. These email changes will include context diffs of the changes.
8Really big diffs will be trimmed.
9
10This script is run from a CVS loginfo file (see $CVSROOT/CVSROOT/loginfo). To
11set 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
15In this example, whenever a checkin that matches `mymodule' is made, this
16script is invoked, which will generate the diff containing email, and send it
17to 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
25It no longer makes sense to run this script from the command line. Doing so
26will only print out this usage information.
27
28
29Usage:
30
31 %(PROGRAM)s [options] <%%S> email-addr [email-addr ...]
32
33Where options is:
34
35 --cvsroot=<path>
36 Use <path> as the environment variable CVSROOT. Otherwise this
37 variable must exist in the environment.
38
39 --help
40 -h
41 Print this text.
42
43 <%%S>
44 CVS %%s loginfo expansion. When invoked by CVS, this will be a single
45 string containing the directory the checkin is being made in, relative
46 to $CVSROOT, followed by the list of files that are changing. If the
47 %%s in the loginfo file is %%{sVv}, context diffs for each of the
48 modified files are included in any email messages that are generated.
49
50 email-addrs
51 At least one email address.
52
53"""
54
55import os
56import sys
57import string
58import time
59import getopt
60
61# Notification command
62MAILCMD = '/bin/mail -s "CVS: %(SUBJECT)s" %(PEOPLE)s 2>&1 > /dev/null'
63
64# Diff trimming stuff
65DIFF_HEAD_LINES = 20
66DIFF_TAIL_LINES = 20
67DIFF_TRUNCATE_IF_LARGER = 1000
68
69PROGRAM = sys.argv[0]
70
71
72\f
73def usage(code, msg=''):
74 print __doc__ % globals()
75 if msg:
76 print msg
77 sys.exit(code)
78
79
80\f
81def calculate_diff(filespec):
82 try:
83 file, oldrev, newrev = string.split(filespec, ',')
84 except ValueError:
85 # No diff to report
86 return '***** Bogus filespec: %s' % filespec
87 if oldrev == 'NONE':
88 try:
89 if os.path.exists(file):
90 fp = open(file)
91 else:
92 update_cmd = 'cvs -fn update -r %s -p %s' % (newrev, file)
93 fp = os.popen(update_cmd)
94 lines = fp.readlines()
95 fp.close()
96 lines.insert(0, '--- NEW FILE ---\n')
97 except IOError, e:
98 lines = ['***** Error reading new file: ',
99 str(e), '\n***** file: ', file, ' cwd: ', os.getcwd()]
100 elif newrev == 'NONE':
101 lines = ['--- %s DELETED ---\n' % file]
102 else:
103 # This /has/ to happen in the background, otherwise we'll run into CVS
104 # lock contention. What a crock.
105 diffcmd = '/usr/bin/cvs -f diff -kk -C 2 -w -r %s -r %s %s' % (
106 oldrev, newrev, file)
107 fp = os.popen(diffcmd)
108 lines = fp.readlines()
109 sts = fp.close()
110 # ignore the error code, it always seems to be 1 :(
111## if sts:
112## return 'Error code %d occurred during diff\n' % (sts >> 8)
113 if len(lines) > DIFF_TRUNCATE_IF_LARGER:
114 removedlines = len(lines) - DIFF_HEAD_LINES - DIFF_TAIL_LINES
115 del lines[DIFF_HEAD_LINES:-DIFF_TAIL_LINES]
116 lines.insert(DIFF_HEAD_LINES,
117 '[...%d lines suppressed...]\n' % removedlines)
118 return string.join(lines, '')
119
120
121\f
122def blast_mail(mailcmd, filestodiff):
123 # cannot wait for child process or that will cause parent to retain cvs
124 # lock for too long. Urg!
125 if not os.fork():
126 # in the child
127 # give up the lock you cvs thang!
128 time.sleep(2)
129 fp = os.popen(mailcmd, 'w')
130 fp.write(sys.stdin.read())
131 fp.write('\n')
132 # append the diffs if available
133 for file in filestodiff:
134 fp.write(calculate_diff(file))
135 fp.write('\n')
136 fp.close()
137 # doesn't matter what code we return, it isn't waited on
138 os._exit(0)
139
140
141\f
142# scan args for options
143def main():
144 try:
145 opts, args = getopt.getopt(sys.argv[1:], 'h', ['cvsroot=', 'help'])
146 except getopt.error, msg:
147 usage(1, msg)
148
149 # parse the options
150 for opt, arg in opts:
151 if opt in ('-h', '--help'):
152 usage(0)
153 elif opt == '--cvsroot':
154 os.environ['CVSROOT'] = arg
155
156 # What follows is the specification containing the files that were
157 # modified. The argument actually must be split, with the first component
158 # containing the directory the checkin is being made in, relative to
159 # $CVSROOT, followed by the list of files that are changing.
160 if not args:
161 usage(1, 'No CVS module specified')
162 SUBJECT = args[0]
163 specs = string.split(args[0])
164 del args[0]
165
166 # The remaining args should be the email addresses
167 if not args:
168 usage(1, 'No recipients specified')
169
170 # Now do the mail command
171 PEOPLE = string.join(args)
172 mailcmd = MAILCMD % vars()
173
174 print 'Mailing %s...' % PEOPLE
175 if specs == ['-', 'Imported', 'sources']:
176 return
177 if specs[-3:] == ['-', 'New', 'directory']:
178 del specs[-3:]
179 print 'Generating notification message...'
180 blast_mail(mailcmd, specs[1:])
181 print 'Generating notification message... done.'
182
183
184\f
185if __name__ == '__main__':
186 main()
187 sys.exit(0)