You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
271 lines
7.7 KiB
271 lines
7.7 KiB
#! /usr/bin/env python |
|
|
|
"""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', |
|
'scancommitforcc', |
|
] |
|
|
|
NEW_NAMES = [ |
|
'environment', |
|
'reponame', |
|
'mailinglist', |
|
'refchangelist', |
|
'commitlist', |
|
'announcelist', |
|
'announceshortlog', |
|
'envelopesender', |
|
'administrator', |
|
'emailprefix', |
|
'emailmaxlines', |
|
'diffopts', |
|
'emaildomain', |
|
'scancommitforcc', |
|
] |
|
|
|
|
|
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 name in old: |
|
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 name in new: |
|
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 name in config: |
|
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 name in old: |
|
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 name in old: |
|
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', 'scancommitforcc']: |
|
if name in old: |
|
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 name in old: |
|
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:])
|
|
|