1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-11-16 14:04:52 +01:00
git/contrib/hooks/multimail/migrate-mailhook-config

270 lines
7.6 KiB
Text
Raw Normal View History

git-multimail: an improved replacement for post-receive-email Add git-multimail, a tool for generating notification emails for pushes to a Git repository. It is largely plug-in compatible with post-receive-email, and is proposed to eventually replace that script. The advantages of git-multimail relative to post-receive-email are described in README.migrate-from-post-receive-email. git-multimail is organized in a directory contrib/hooks/multimail. The directory contains: * git_multimail.py -- a Python module that can generate notification emails for pushes to a Git repository. The file can be used directly as a post-receive script (configured via git config settings), or it can be imported as a Python module and configured via arbitrary Python code. * README -- user-level documentation for configuring and using git-multimail. * post-receive -- an example of building a post-receive script that imports git_multimail.py as a Python module, with an example of how to change the email templates. * README.migrate-from-post-receive-email -- documentation targeted at current users of post-receive-email, explaining the differences and how to migrate a post-receive-email configuration to git-multimail. * migrate-mailhook-config -- a script that can migrate a user's post-receive-email configuration options to the equivalent git-multimail options. * README.Git -- a short explanation of the relationship between git-multimail and the rest of the Git project, plus the exact date and revision when this version was taken from the upstream project. All but the last file are taken verbatim from the upstream git-multimail project. git-multimail is originally derived from post-receive-email and also incorporates suggestions from the mailing list as well as patches by the people listed below. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Contributions-by: Matthieu Moy <Matthieu.Moy@imag.fr> Contributions-by: Ramkumar Ramachandra <artagnon@gmail.com> Contributions-by: Chris Hiestand <chrishiestand@gmail.com> Contributions-by: Michiel Holtkamp <git@elfstone.nl> Contributions-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Reviewed-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-14 10:09:02 +02:00
#! /usr/bin/env python2
"""Migrate a post-receive-email configuration to be usable with git_multimail.py.
See README.migrate-from-post-receive-email for more information.
"""
import sys
import optparse
from git_multimail import CommandError
from git_multimail import Config
from git_multimail import read_output
OLD_NAMES = [
'mailinglist',
'announcelist',
'envelopesender',
'emailprefix',
'showrev',
'emailmaxlines',
'diffopts',
]
NEW_NAMES = [
'environment',
'reponame',
'mailinglist',
'refchangelist',
'commitlist',
'announcelist',
'announceshortlog',
'envelopesender',
'administrator',
'emailprefix',
'emailmaxlines',
'diffopts',
'emaildomain',
]
INFO = """\
SUCCESS!
Your post-receive-email configuration has been converted to
git-multimail format. Please see README and
README.migrate-from-post-receive-email to learn about other
git-multimail configuration possibilities.
For example, git-multimail has the following new options with no
equivalent in post-receive-email. You might want to read about them
to see if they would be useful in your situation:
"""
def _check_old_config_exists(old):
"""Check that at least one old configuration value is set."""
for name in OLD_NAMES:
if old.has_key(name):
return True
return False
def _check_new_config_clear(new):
"""Check that none of the new configuration names are set."""
retval = True
for name in NEW_NAMES:
if new.has_key(name):
if retval:
sys.stderr.write('INFO: The following configuration values already exist:\n\n')
sys.stderr.write(' "%s.%s"\n' % (new.section, name))
retval = False
return retval
def erase_values(config, names):
for name in names:
if config.has_key(name):
try:
sys.stderr.write('...unsetting "%s.%s"\n' % (config.section, name))
config.unset_all(name)
except CommandError:
sys.stderr.write(
'\nWARNING: could not unset "%s.%s". '
'Perhaps it is not set at the --local level?\n\n'
% (config.section, name)
)
def is_section_empty(section, local):
"""Return True iff the specified configuration section is empty.
Iff local is True, use the --local option when invoking 'git
config'."""
if local:
local_option = ['--local']
else:
local_option = []
try:
read_output(
['git', 'config']
+ local_option
+ ['--get-regexp', '^%s\.' % (section,)]
)
except CommandError, e:
if e.retcode == 1:
# This means that no settings were found.
return True
else:
raise
else:
return False
def remove_section_if_empty(section):
"""If the specified configuration section is empty, delete it."""
try:
empty = is_section_empty(section, local=True)
except CommandError:
# Older versions of git do not support the --local option, so
# if the first attempt fails, try without --local.
try:
empty = is_section_empty(section, local=False)
except CommandError:
sys.stderr.write(
'\nINFO: If configuration section "%s.*" is empty, you might want '
'to delete it.\n\n'
% (section,)
)
return
if empty:
sys.stderr.write('...removing section "%s.*"\n' % (section,))
read_output(['git', 'config', '--remove-section', section])
else:
sys.stderr.write(
'\nINFO: Configuration section "%s.*" still has contents. '
'It will not be deleted.\n\n'
% (section,)
)
def migrate_config(strict=False, retain=False, overwrite=False):
old = Config('hooks')
new = Config('multimailhook')
if not _check_old_config_exists(old):
sys.exit(
'Your repository has no post-receive-email configuration. '
'Nothing to do.'
)
if not _check_new_config_clear(new):
if overwrite:
sys.stderr.write('\nWARNING: Erasing the above values...\n\n')
erase_values(new, NEW_NAMES)
else:
sys.exit(
'\nERROR: Refusing to overwrite existing values. Use the --overwrite\n'
'option to continue anyway.'
)
name = 'showrev'
if old.has_key(name):
msg = 'git-multimail does not support "%s.%s"' % (old.section, name,)
if strict:
sys.exit(
'ERROR: %s.\n'
'Please unset that value then try again, or run without --strict.'
% (msg,)
)
else:
sys.stderr.write('\nWARNING: %s (ignoring).\n\n' % (msg,))
for name in ['mailinglist', 'announcelist']:
if old.has_key(name):
sys.stderr.write(
'...copying "%s.%s" to "%s.%s"\n' % (old.section, name, new.section, name)
)
new.set_recipients(name, old.get_recipients(name))
if strict:
sys.stderr.write(
'...setting "%s.commitlist" to the empty string\n' % (new.section,)
)
new.set_recipients('commitlist', '')
sys.stderr.write(
'...setting "%s.announceshortlog" to "true"\n' % (new.section,)
)
new.set('announceshortlog', 'true')
for name in ['envelopesender', 'emailmaxlines', 'diffopts']:
if old.has_key(name):
sys.stderr.write(
'...copying "%s.%s" to "%s.%s"\n' % (old.section, name, new.section, name)
)
new.set(name, old.get(name))
name = 'emailprefix'
if old.has_key(name):
sys.stderr.write(
'...copying "%s.%s" to "%s.%s"\n' % (old.section, name, new.section, name)
)
new.set(name, old.get(name))
elif strict:
sys.stderr.write(
'...setting "%s.%s" to "[SCM]" to preserve old subject lines\n'
% (new.section, name)
)
new.set(name, '[SCM]')
if not retain:
erase_values(old, OLD_NAMES)
remove_section_if_empty(old.section)
sys.stderr.write(INFO)
for name in NEW_NAMES:
if name not in OLD_NAMES:
sys.stderr.write(' "%s.%s"\n' % (new.section, name,))
sys.stderr.write('\n')
def main(args):
parser = optparse.OptionParser(
description=__doc__,
usage='%prog [OPTIONS]',
)
parser.add_option(
'--strict', action='store_true', default=False,
help=(
'Slavishly configure git-multimail as closely as possible to '
'the post-receive-email configuration. Default is to turn '
'on some new features that have no equivalent in post-receive-email.'
),
)
parser.add_option(
'--retain', action='store_true', default=False,
help=(
'Retain the post-receive-email configuration values. '
'Default is to delete them after the new values are set.'
),
)
parser.add_option(
'--overwrite', action='store_true', default=False,
help=(
'Overwrite any existing git-multimail configuration settings. '
'Default is to abort if such settings already exist.'
),
)
(options, args) = parser.parse_args(args)
if args:
parser.error('Unexpected arguments: %s' % (' '.join(args),))
migrate_config(strict=options.strict, retain=options.retain, overwrite=options.overwrite)
main(sys.argv[1:])