Squashed 'third_party/git/' content from commit cb71568594
git-subtree-dir: third_party/git git-subtree-split: cb715685942260375e1eb8153b0768a376e4ece7
This commit is contained in:
commit
1b593e1ea4
3629 changed files with 1139935 additions and 0 deletions
274
contrib/hooks/multimail/migrate-mailhook-config
Executable file
274
contrib/hooks/multimail/migrate-mailhook-config
Executable file
|
|
@ -0,0 +1,274 @@
|
|||
#! /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:
|
||||
t, e, traceback = sys.exc_info()
|
||||
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)
|
||||
)
|
||||
old_recipients = old.get_all(name, default=None)
|
||||
old_recipients = ', '.join(o.strip() for o in old_recipients)
|
||||
new.set_recipients(name, old_recipients)
|
||||
|
||||
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:])
|
||||
Loading…
Add table
Add a link
Reference in a new issue