|
1 # Copyright 2007 Bryan O'Sullivan <bos@serpentine.com> |
|
2 # |
|
3 # This software may be used and distributed according to the terms of |
|
4 # the GNU General Public License, incorporated herein by reference. |
|
5 |
|
6 import shlex |
|
7 from mercurial.i18n import _ |
|
8 from mercurial import util |
|
9 |
|
10 def rpairs(name): |
|
11 e = len(name) |
|
12 while e != -1: |
|
13 yield name[:e], name[e+1:] |
|
14 e = name.rfind('/', 0, e) |
|
15 |
|
16 class filemapper(object): |
|
17 '''Map and filter filenames when importing. |
|
18 A name can be mapped to itself, a new name, or None (omit from new |
|
19 repository).''' |
|
20 |
|
21 def __init__(self, ui, path=None): |
|
22 self.ui = ui |
|
23 self.include = {} |
|
24 self.exclude = {} |
|
25 self.rename = {} |
|
26 if path: |
|
27 if self.parse(path): |
|
28 raise util.Abort(_('errors in filemap')) |
|
29 |
|
30 def parse(self, path): |
|
31 errs = 0 |
|
32 def check(name, mapping, listname): |
|
33 if name in mapping: |
|
34 self.ui.warn(_('%s:%d: %r already in %s list\n') % |
|
35 (lex.infile, lex.lineno, name, listname)) |
|
36 return 1 |
|
37 return 0 |
|
38 lex = shlex.shlex(open(path), path, True) |
|
39 lex.wordchars += '!@#$%^&*()-=+[]{}|;:,./<>?' |
|
40 cmd = lex.get_token() |
|
41 while cmd: |
|
42 if cmd == 'include': |
|
43 name = lex.get_token() |
|
44 errs += check(name, self.exclude, 'exclude') |
|
45 self.include[name] = name |
|
46 elif cmd == 'exclude': |
|
47 name = lex.get_token() |
|
48 errs += check(name, self.include, 'include') |
|
49 errs += check(name, self.rename, 'rename') |
|
50 self.exclude[name] = name |
|
51 elif cmd == 'rename': |
|
52 src = lex.get_token() |
|
53 dest = lex.get_token() |
|
54 errs += check(src, self.exclude, 'exclude') |
|
55 self.rename[src] = dest |
|
56 elif cmd == 'source': |
|
57 errs += self.parse(lex.get_token()) |
|
58 else: |
|
59 self.ui.warn(_('%s:%d: unknown directive %r\n') % |
|
60 (lex.infile, lex.lineno, cmd)) |
|
61 errs += 1 |
|
62 cmd = lex.get_token() |
|
63 return errs |
|
64 |
|
65 def lookup(self, name, mapping): |
|
66 for pre, suf in rpairs(name): |
|
67 try: |
|
68 return mapping[pre], pre, suf |
|
69 except KeyError, err: |
|
70 pass |
|
71 return '', name, '' |
|
72 |
|
73 def __call__(self, name): |
|
74 if self.include: |
|
75 inc = self.lookup(name, self.include)[0] |
|
76 else: |
|
77 inc = name |
|
78 if self.exclude: |
|
79 exc = self.lookup(name, self.exclude)[0] |
|
80 else: |
|
81 exc = '' |
|
82 if not inc or exc: |
|
83 return None |
|
84 newpre, pre, suf = self.lookup(name, self.rename) |
|
85 if newpre: |
|
86 if newpre == '.': |
|
87 return suf |
|
88 if suf: |
|
89 return newpre + '/' + suf |
|
90 return newpre |
|
91 return name |
|
92 |
|
93 def active(self): |
|
94 return bool(self.include or self.exclude or self.rename) |