1#! /usr/bin/env python2 2 3"""Migrate a post-receive-email configuration to be usable with git_multimail.py. 4 5See README.migrate-from-post-receive-email for more information. 6 7""" 8 9import sys 10import optparse 11 12from git_multimail import CommandError 13from git_multimail import Config 14from git_multimail import read_output 15 16 17OLD_NAMES = [ 18'mailinglist', 19'announcelist', 20'envelopesender', 21'emailprefix', 22'showrev', 23'emailmaxlines', 24'diffopts', 25] 26 27NEW_NAMES = [ 28'environment', 29'reponame', 30'mailinglist', 31'refchangelist', 32'commitlist', 33'announcelist', 34'announceshortlog', 35'envelopesender', 36'administrator', 37'emailprefix', 38'emailmaxlines', 39'diffopts', 40'emaildomain', 41] 42 43 44INFO ="""\ 45 46SUCCESS! 47 48Your post-receive-email configuration has been converted to 49git-multimail format. Please see README and 50README.migrate-from-post-receive-email to learn about other 51git-multimail configuration possibilities. 52 53For example, git-multimail has the following new options with no 54equivalent in post-receive-email. You might want to read about them 55to see if they would be useful in your situation: 56 57""" 58 59 60def_check_old_config_exists(old): 61"""Check that at least one old configuration value is set.""" 62 63for name in OLD_NAMES: 64if old.has_key(name): 65return True 66 67return False 68 69 70def_check_new_config_clear(new): 71"""Check that none of the new configuration names are set.""" 72 73 retval =True 74for name in NEW_NAMES: 75if new.has_key(name): 76if retval: 77 sys.stderr.write('INFO: The following configuration values already exist:\n\n') 78 sys.stderr.write(' "%s.%s"\n'% (new.section, name)) 79 retval =False 80 81return retval 82 83 84deferase_values(config, names): 85for name in names: 86if config.has_key(name): 87try: 88 sys.stderr.write('...unsetting "%s.%s"\n'% (config.section, name)) 89 config.unset_all(name) 90except CommandError: 91 sys.stderr.write( 92'\nWARNING: could not unset "%s.%s". ' 93'Perhaps it is not set at the --local level?\n\n' 94% (config.section, name) 95) 96 97 98defis_section_empty(section, local): 99"""Return True iff the specified configuration section is empty. 100 101 Iff local is True, use the --local option when invoking 'git 102 config'.""" 103 104if local: 105 local_option = ['--local'] 106else: 107 local_option = [] 108 109try: 110read_output( 111['git','config'] 112+ local_option 113+ ['--get-regexp','^%s\.'% (section,)] 114) 115except CommandError, e: 116if e.retcode ==1: 117# This means that no settings were found. 118return True 119else: 120raise 121else: 122return False 123 124 125defremove_section_if_empty(section): 126"""If the specified configuration section is empty, delete it.""" 127 128try: 129 empty =is_section_empty(section, local=True) 130except CommandError: 131# Older versions of git do not support the --local option, so 132# if the first attempt fails, try without --local. 133try: 134 empty =is_section_empty(section, local=False) 135except CommandError: 136 sys.stderr.write( 137'\nINFO: If configuration section "%s.*" is empty, you might want ' 138'to delete it.\n\n' 139% (section,) 140) 141return 142 143if empty: 144 sys.stderr.write('...removing section "%s.*"\n'% (section,)) 145read_output(['git','config','--remove-section', section]) 146else: 147 sys.stderr.write( 148'\nINFO: Configuration section "%s.*" still has contents. ' 149'It will not be deleted.\n\n' 150% (section,) 151) 152 153 154defmigrate_config(strict=False, retain=False, overwrite=False): 155 old =Config('hooks') 156 new =Config('multimailhook') 157if not_check_old_config_exists(old): 158 sys.exit( 159'Your repository has no post-receive-email configuration. ' 160'Nothing to do.' 161) 162if not_check_new_config_clear(new): 163if overwrite: 164 sys.stderr.write('\nWARNING: Erasing the above values...\n\n') 165erase_values(new, NEW_NAMES) 166else: 167 sys.exit( 168'\nERROR: Refusing to overwrite existing values. Use the --overwrite\n' 169'option to continue anyway.' 170) 171 172 name ='showrev' 173if old.has_key(name): 174 msg ='git-multimail does not support "%s.%s"'% (old.section, name,) 175if strict: 176 sys.exit( 177'ERROR:%s.\n' 178'Please unset that value then try again, or run without --strict.' 179% (msg,) 180) 181else: 182 sys.stderr.write('\nWARNING:%s(ignoring).\n\n'% (msg,)) 183 184for name in['mailinglist','announcelist']: 185if old.has_key(name): 186 sys.stderr.write( 187'...copying "%s.%s" to "%s.%s"\n'% (old.section, name, new.section, name) 188) 189 new.set_recipients(name, old.get_recipients(name)) 190 191if strict: 192 sys.stderr.write( 193'...setting "%s.commitlist" to the empty string\n'% (new.section,) 194) 195 new.set_recipients('commitlist','') 196 sys.stderr.write( 197'...setting "%s.announceshortlog" to "true"\n'% (new.section,) 198) 199 new.set('announceshortlog','true') 200 201for name in['envelopesender','emailmaxlines','diffopts']: 202if old.has_key(name): 203 sys.stderr.write( 204'...copying "%s.%s" to "%s.%s"\n'% (old.section, name, new.section, name) 205) 206 new.set(name, old.get(name)) 207 208 name ='emailprefix' 209if old.has_key(name): 210 sys.stderr.write( 211'...copying "%s.%s" to "%s.%s"\n'% (old.section, name, new.section, name) 212) 213 new.set(name, old.get(name)) 214elif strict: 215 sys.stderr.write( 216'...setting "%s.%s" to "[SCM]" to preserve old subject lines\n' 217% (new.section, name) 218) 219 new.set(name,'[SCM]') 220 221if not retain: 222erase_values(old, OLD_NAMES) 223remove_section_if_empty(old.section) 224 225 sys.stderr.write(INFO) 226for name in NEW_NAMES: 227if name not in OLD_NAMES: 228 sys.stderr.write(' "%s.%s"\n'% (new.section, name,)) 229 sys.stderr.write('\n') 230 231 232defmain(args): 233 parser = optparse.OptionParser( 234 description=__doc__, 235 usage='%prog [OPTIONS]', 236) 237 238 parser.add_option( 239'--strict', action='store_true', default=False, 240help=( 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.' 244), 245) 246 parser.add_option( 247'--retain', action='store_true', default=False, 248help=( 249'Retain the post-receive-email configuration values. ' 250'Default is to delete them after the new values are set.' 251), 252) 253 parser.add_option( 254'--overwrite', action='store_true', default=False, 255help=( 256'Overwrite any existing git-multimail configuration settings. ' 257'Default is to abort if such settings already exist.' 258), 259) 260 261(options, args) = parser.parse_args(args) 262 263if args: 264 parser.error('Unexpected arguments:%s'% (' '.join(args),)) 265 266migrate_config(strict=options.strict, retain=options.retain, overwrite=options.overwrite) 267 268 269main(sys.argv[1:])