aboutsummaryrefslogtreecommitdiffstats
path: root/admin/bin
diff options
context:
space:
mode:
Diffstat (limited to 'admin/bin')
-rwxr-xr-xadmin/bin/Release.py229
-rwxr-xr-xadmin/bin/faq2ht.py102
-rwxr-xr-xadmin/bin/mm2do76
3 files changed, 407 insertions, 0 deletions
diff --git a/admin/bin/Release.py b/admin/bin/Release.py
new file mode 100755
index 00000000..227cdb5a
--- /dev/null
+++ b/admin/bin/Release.py
@@ -0,0 +1,229 @@
+#! /usr/bin/env python
+#
+# Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+"""Manage releases of Mailman.
+
+Usage: %(program)s [options] tagname
+
+Where `options' are:
+
+ --tag
+ -t
+ Tag all release files with tagname.
+
+ --TAG
+ -T
+ Like --tag, but relocates any existing tag. See `cvs tag -F'. Only
+ one of --tag or --TAG can be given on the command line.
+
+ --package
+ -p
+ create the distribution package
+
+ --bump
+ -b
+ Bump the revision number in key files to tagname. This is done by
+ textual substitution.
+
+ --help
+ -h
+ Print this help message.
+
+ tagname is used in the various commands above. It should essentially be
+ the version number for the release, and is required.
+"""
+
+import sys
+import os
+import errno
+import re
+import time
+import tempfile
+import getopt
+
+program = sys.argv[0]
+
+def usage(code, msg=''):
+ print >> sys.stderr, __doc__ % globals()
+ if msg:
+ print >> sys.stderr, msg
+ sys.exit(code)
+
+
+
+_releasedir = None
+def releasedir(tagname=None):
+ global _releasedir
+ if not _releasedir:
+ tmpdir = tempfile.gettempdir()
+ _releasedir = os.path.join(tmpdir, 'mailman-' + tagname)
+ return _releasedir
+
+
+
+# CVS related commands
+
+def tag2rel(tagname):
+ return '"Release_%s"' % tagname.replace('.', '_')
+
+def cvsdo(cvscmd):
+ # I don't know why -d is suddenly required -- $CVSROOT used to work just
+ # fine but now (RH7.3) doesn't at all.
+ cmd = 'cvs -d %s %s' % (os.environ['CVSROOT'], cvscmd)
+ os.system(cmd)
+
+def tag_release(tagname, retag):
+ # Convert dots in tagname to underscores
+ relname = tag2rel(tagname)
+ print 'Tagging release with', relname, '...'
+ option = ''
+ if retag:
+ option = '-F'
+ cvsdo('tag %s %s' % (option, relname))
+
+def checkout(tagname, tail):
+ print 'checking out...',
+ relname = tag2rel(tagname)
+ cvsdo('export -k kv -r %s -d %s mailman' % (relname, tail))
+ os.rename('%s/doc' % tail, 'mailman-doc')
+
+
+
+def make_pkg(tagname):
+ dir = releasedir(tagname)
+ print 'Exporting release dir', dir, '...'
+ head, tail = os.path.split(dir)
+ # this can't be done from a working directory
+ curdir = os.getcwd()
+ try:
+ os.chdir(head)
+ checkout(tagname, tail)
+ print 'making tarball...'
+ relname = 'mailman-' + tagname
+ os.system('tar cvzf %s --exclude .cvsignore %s' %
+ (relname + '.tgz', relname))
+ os.system('tar cvzf mailman-doc.tgz --exclude .cvsignore mailman-doc')
+ finally:
+ os.chdir(curdir)
+
+
+VERSIONMARK = '<!-VERSION--->'
+DATEMARK = '<!-DATE--->'
+
+
+def do_bump(newvers):
+ print 'doing bump...',
+ # hack some files
+ for file in ('index.ht', 'version.ht'):
+ print '%s...' % file,
+ fp = open(os.path.join('admin', 'www', file), 'r+')
+ text = fp.read()
+ parts = text.split(VERSIONMARK)
+ parts[1] = newvers
+ text = VERSIONMARK.join(parts)
+ parts = text.split(DATEMARK)
+ parts[1] = time.strftime('%d-%b-%Y', time.localtime(time.time()))
+ text = DATEMARK.join(parts)
+ fp.seek(0)
+ fp.write(text)
+ fp.close()
+ # hack the configure.in file
+ print 'Version.py...',
+ infp = open('Mailman/Version.py')
+ outfp = open('Mailman/Version.py.new', 'w')
+ matched = 0
+ cre = re.compile(r'^VERSION(?P<ws>[ \t]*)=')
+ while 1:
+ line = infp.readline()
+ if not line:
+ if not matched:
+ print 'Error! VERSION line not found'
+ break
+ mo = cre.search(line)
+ if matched or not mo:
+ outfp.write(line)
+ else:
+ outfp.write('VERSION%s= "%s"\n' % (mo.group('ws'), newvers))
+ matched = 1
+ infp.close()
+ outfp.close()
+ os.rename('Mailman/Version.py.new', 'Mailman/Version.py')
+
+
+
+def main():
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], 'btTph',
+ ['bump', 'tag', 'TAG', 'package', 'help'])
+ except getopt.error, msg:
+ usage(1, msg)
+
+ # required minor rev number
+ if len(args) <> 1:
+ usage(1, 'tagname argument is required')
+
+ tagname = args[0]
+
+ # We need a $CVSROOT
+ if not os.environ.get('CVSROOT'):
+ try:
+ fp = open('CVS/Root')
+ os.environ['CVSROOT'] = fp.read().strip()
+ fp.close()
+ except IOError, e:
+ if e.errno <> errno.ENOENT: raise
+ usage(1, 'CVSROOT is not set and could not be guessed')
+ print 'Using CVSROOT:', os.environ['CVSROOT']
+
+ # default options
+ tag = 0
+ retag = 0
+ package = 0
+ bump = 0
+
+ for opt, arg in opts:
+ if opt in ('-h', '--help'):
+ usage(0)
+ elif opt in ('-t', '--tag'):
+ tag = 1
+ elif opt in ('-T', '--TAG'):
+ tag = 1
+ retag = 1
+ elif opt in ('-p', '--package'):
+ package = 1
+ elif opt in ('-b', '--bump'):
+ bump = 1
+
+ # very important!!!
+ omask = os.umask(0)
+ try:
+ if tag:
+ tag_release(tagname, retag)
+
+ if package:
+ make_pkg(tagname)
+
+ if bump:
+ do_bump(tagname)
+ finally:
+ os.umask(omask)
+
+
+
+if __name__ == '__main__':
+ main()
diff --git a/admin/bin/faq2ht.py b/admin/bin/faq2ht.py
new file mode 100755
index 00000000..29db9ea7
--- /dev/null
+++ b/admin/bin/faq2ht.py
@@ -0,0 +1,102 @@
+#! /usr/bin/env python
+
+"""Convert the plain text FAQ file to its .ht template.
+"""
+
+import sys
+import os
+import re
+
+
+
+def main():
+ faqfile = sys.argv[1]
+ fp = open(faqfile)
+ lines = fp.readlines()
+ fp.close()
+
+ outfile = sys.argv[2]
+ if outfile == '-':
+ closep = 0
+ out = sys.stdout
+ else:
+ closep = 1
+ out = open(outfile, 'w')
+
+ # skip over cruft in FAQ file
+ lineno = 0
+ while not lines[lineno].startswith('FREQUENTLY'):
+ lineno += 1
+ lineno += 1
+
+ # skip blanks
+ while not lines[lineno].strip():
+ lineno += 1
+
+ # first print out standard .ht boilerplate
+ print >> out, '''\
+Title: Mailman Frequently Asked Questions
+
+See also the <a href="http://www.python.org/cgi-bin/faqw-mm.py">Mailman
+FAQ Wizard</a> for more information.
+
+ <h3>Mailman Frequently Asked Questions</h3>
+'''
+ first = 1
+ question = []
+ answer = []
+ faq = []
+ while 1:
+ line = lines[lineno][:-1]
+
+ if line.startswith('Q.'):
+ inquestion = 1
+ if not first:
+ faq.append((question, answer))
+ question = []
+ answer = []
+ else:
+ first = 0
+ elif line.startswith('A.'):
+ inquestion = 0
+ elif line.startswith('\f'):
+ break
+
+ if inquestion:
+ question.append(line)
+ else:
+ # watch for lists
+ if line.lstrip().startswith('*'):
+ answer.append('<li>')
+ line = line.replace('*', '', 1)
+ # substitute <...>
+ line = re.sub(r'<(?P<var>[^>]+)>',
+ '<em>\g<var></em>',
+ line)
+ # make links active
+ line = re.sub(r'(?P<url>http://\S+)',
+ '<a href="\g<url>">\g<url></a>',
+ line)
+ answer.append(line)
+
+ lineno += 1
+ faq.append((question, answer))
+
+ for question, answer in faq:
+ print >> out, '<b>',
+ for line in question:
+ print >> out, line
+ print >> out, '</b><br>',
+ for line in answer:
+ if not line:
+ print >> out, '<p>',
+ else:
+ print >> out, line
+
+ if closep:
+ out.close()
+
+
+
+if __name__ == '__main__':
+ main()
diff --git a/admin/bin/mm2do b/admin/bin/mm2do
new file mode 100755
index 00000000..661a25f4
--- /dev/null
+++ b/admin/bin/mm2do
@@ -0,0 +1,76 @@
+#! /usr/bin/env python
+#
+# Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+"""Generate the todo.ht file from the plain-text TODO file."""
+
+import sys
+
+infp = open(sys.argv[1])
+outfp = open(sys.argv[2], 'w')
+
+SPACE = ' '
+
+print >> outfp, 'Title: The Mailman Wishlist\n'
+
+def dumpsection(header, items, hasitems):
+ # We're looking at a header
+ if header:
+ # output the previous section
+ print >> outfp, '<h3>', header, '</h3>'
+ if hasitems:
+ print >> outfp, '<ul>'
+ for item in items:
+ if item:
+ print >> outfp, ' <li>', SPACE.join(item)
+ print >> outfp, '</ul>'
+ else:
+ for item in items:
+ print >> outfp, SPACE.join(item), '<p>'
+
+
+
+header = ''
+items = [['']]
+hasitems = False
+inpreamble = True
+while True:
+ line = infp.readline()
+ if not line or line[0] == '\f':
+ break
+ # Skip the legalese preamble
+ if inpreamble:
+ if line.strip():
+ continue
+ else:
+ inpreamble = False
+ if not line[0].isspace():
+ dumpsection(header, items, hasitems)
+ header = line
+ items = [[]]
+ continue
+ # find out what the first non-ws character on the line is
+ line = line.lstrip()
+ if line and line[0] == '-':
+ items.append([line[2:-1]])
+ hasitems = True
+ else:
+ if not line:
+ continue
+ items[-1].append(line)
+
+dumpsection(header, items, hasitems)