1 #! /usr/bin/env python2
3 """Migrate a post-receive-email configuration to be usable with git_multimail.py.
5 See README.migrate-from-post-receive-email for more information.
12 from git_multimail import CommandError
13 from git_multimail import Config
14 from git_multimail import read_output
48 Your post-receive-email configuration has been converted to
49 git-multimail format. Please see README and
50 README.migrate-from-post-receive-email to learn about other
51 git-multimail configuration possibilities.
53 For example, git-multimail has the following new options with no
54 equivalent in post-receive-email. You might want to read about them
55 to see if they would be useful in your situation:
60 def _check_old_config_exists(old):
61 """Check that at least one old configuration value is set."""
63 for name in OLD_NAMES:
70 def _check_new_config_clear(new):
71 """Check that none of the new configuration names are set."""
74 for name in NEW_NAMES:
77 sys.stderr.write('INFO: The following configuration values already exist:\n\n')
78 sys.stderr.write(' "%s.%s"\n' % (new.section, name))
84 def erase_values(config, names):
86 if config.has_key(name):
88 sys.stderr.write('...unsetting "%s.%s"\n' % (config.section, name))
89 config.unset_all(name)
92 '\nWARNING: could not unset "%s.%s". '
93 'Perhaps it is not set at the --local level?\n\n'
94 % (config.section, name)
98 def is_section_empty(section, local):
99 """Return True iff the specified configuration section is empty.
101 Iff local is True, use the --local option when invoking 'git
105 local_option = ['--local']
113 + ['--get-regexp', '^%s\.' % (section,)]
115 except CommandError, e:
117 # This means that no settings were found.
125 def remove_section_if_empty(section):
126 """If the specified configuration section is empty, delete it."""
129 empty = is_section_empty(section, local=True)
131 # Older versions of git do not support the --local option, so
132 # if the first attempt fails, try without --local.
134 empty = is_section_empty(section, local=False)
137 '\nINFO: If configuration section "%s.*" is empty, you might want '
144 sys.stderr.write('...removing section "%s.*"\n' % (section,))
145 read_output(['git', 'config', '--remove-section', section])
148 '\nINFO: Configuration section "%s.*" still has contents. '
149 'It will not be deleted.\n\n'
154 def migrate_config(strict=False, retain=False, overwrite=False):
155 old = Config('hooks')
156 new = Config('multimailhook')
157 if not _check_old_config_exists(old):
159 'Your repository has no post-receive-email configuration. '
162 if not _check_new_config_clear(new):
164 sys.stderr.write('\nWARNING: Erasing the above values...\n\n')
165 erase_values(new, NEW_NAMES)
168 '\nERROR: Refusing to overwrite existing values. Use the --overwrite\n'
169 'option to continue anyway.'
173 if old.has_key(name):
174 msg = 'git-multimail does not support "%s.%s"' % (old.section, name,)
178 'Please unset that value then try again, or run without --strict.'
182 sys.stderr.write('\nWARNING: %s (ignoring).\n\n' % (msg,))
184 for name in ['mailinglist', 'announcelist']:
185 if old.has_key(name):
187 '...copying "%s.%s" to "%s.%s"\n' % (old.section, name, new.section, name)
189 new.set_recipients(name, old.get_recipients(name))
193 '...setting "%s.commitlist" to the empty string\n' % (new.section,)
195 new.set_recipients('commitlist', '')
197 '...setting "%s.announceshortlog" to "true"\n' % (new.section,)
199 new.set('announceshortlog', 'true')
201 for name in ['envelopesender', 'emailmaxlines', 'diffopts']:
202 if old.has_key(name):
204 '...copying "%s.%s" to "%s.%s"\n' % (old.section, name, new.section, name)
206 new.set(name, old.get(name))
209 if old.has_key(name):
211 '...copying "%s.%s" to "%s.%s"\n' % (old.section, name, new.section, name)
213 new.set(name, old.get(name))
216 '...setting "%s.%s" to "[SCM]" to preserve old subject lines\n'
217 % (new.section, name)
219 new.set(name, '[SCM]')
222 erase_values(old, OLD_NAMES)
223 remove_section_if_empty(old.section)
225 sys.stderr.write(INFO)
226 for name in NEW_NAMES:
227 if name not in OLD_NAMES:
228 sys.stderr.write(' "%s.%s"\n' % (new.section, name,))
229 sys.stderr.write('\n')
233 parser = optparse.OptionParser(
235 usage='%prog [OPTIONS]',
239 '--strict', action='store_true', default=False,
241 'Slavishly configure git-multimail as closely as possible to '
242 'the post-receive-email configuration. Default is to turn '
243 'on some new features that have no equivalent in post-receive-email.'
247 '--retain', action='store_true', default=False,
249 'Retain the post-receive-email configuration values. '
250 'Default is to delete them after the new values are set.'
254 '--overwrite', action='store_true', default=False,
256 'Overwrite any existing git-multimail configuration settings. '
257 'Default is to abort if such settings already exist.'
261 (options, args) = parser.parse_args(args)
264 parser.error('Unexpected arguments: %s' % (' '.join(args),))
266 migrate_config(strict=options.strict, retain=options.retain, overwrite=options.overwrite)