comparison maps.py @ 307:1d48d9a34c19

Put authormap into a separate file, and make it much better too. See the doc-strings in maps.py for details.
author Dan Villiom Podlaski Christiansen <danchr@gmail.com>
date Sun, 03 May 2009 15:28:43 +0200
parents
children 15b8bab03504
comparison
equal deleted inserted replaced
306:e6853c7fa3af 307:1d48d9a34c19
1 ''' Module for self-contained maps. '''
2
3 import os
4 from mercurial import util as hgutil
5
6 class AuthorMap(dict):
7 '''A mapping from Subversion-style authors to Mercurial-style
8 authors, and back. The data is stored persistently on disk.
9
10 If the 'hgsubversion.defaultauthors' configuration option is set to false,
11 attempting to obtain an unknown author will fail with an Abort.
12 '''
13
14 def __init__(self, ui, path, defaulthost=None):
15 '''Initialise a new AuthorMap.
16
17 The ui argument is used to print diagnostic messages.
18
19 The path argument is the location of the backing store,
20 typically .hg/authormap.
21 '''
22 self.ui = ui
23 self.path = path
24 if defaulthost:
25 self.defaulthost = '@%s' % defaulthost.lstrip('@')
26 else:
27 self.defaulthost = ''
28 self.super = super(AuthorMap, self)
29 self.super.__init__()
30 self.load(path)
31
32 def load(self, path):
33 ''' Load mappings from a file at the specified path. '''
34 if os.path.exists(path):
35 self.ui.note('Reading authormap from %s\n' % path)
36 f = open(path, 'r')
37 for number, line in enumerate(f):
38 if not line.strip():
39 continue
40 try:
41 srcauth, dstauth = line.split('=', 1)
42 srcauth = srcauth.strip()
43 dstauth = dstauth.strip()
44 if srcauth in self and dstauth != self[srcauth]:
45 self.ui.warn(('Overriding author mapping for "%s" from '
46 + '"%s" to "%s"\n')
47 % (srcauth, self[srcauth], dstauth))
48 else:
49 self[srcauth] = dstauth
50 except IndexError:
51 self.ui.warn('Ignoring line %i in author map %s: %s\n'
52 % (number, path, line.rstrip()))
53 f.close()
54
55 def __setitem__(self, key, value):
56 ''' Similar to dict.__setitem__, but also updates the new mapping in the
57 backing store. '''
58 self.super.__setitem__(key, value)
59
60 self.ui.debug(('Writing author map to %s\n') % self.path)
61 f = open(self.path, 'w+')
62 for k, v in self.iteritems():
63 f.write("%s=%s\n" % (k, v))
64 f.close()
65
66 def __getitem__(self, author):
67 ''' Similar to dict.__getitem__, except in case of an unknown author.
68 In such cases, a new value is generated and added to the dictionary
69 as well as the backing store. '''
70 if author in self:
71 result = self.super.__getitem__(author)
72 elif self.ui.configbool('hgsubversion', 'defaultauthors', True):
73 self[author] = result = \
74 '%s <%s%s>' % (author, author, self.defaulthost)
75 self.ui.warn('Substituting author "%s" for default "%s"\n'
76 % (author, result))
77 else:
78 raise hgutil.Abort('Author %s has no entry in the author map!'
79 % author)
80 self.ui.debug('Mapping author "%s" to "%s"\n' % (author, result))
81 return result
82
83 def reverselookup(self, author):
84 for svnauthor, hgauthor in self.iteritems():
85 if author == hgauthor:
86 return svnauthor
87 else:
88 # Mercurial incorrectly splits at e.g. '.', so we roll our own.
89 return author.rsplit('@', 1)[0]