1 from mercurial import hg, filelog, revlog, context, util |
1 from mercurial.i18n import _ |
2 import os.path, re |
2 from mercurial import commands, cmdutil, context, filelog, revlog, util |
|
3 import os.path, re, sys |
3 |
4 |
|
5 # supported keywords for use in regexes |
4 hgkeywords = 'Id|Header|Author|Date|Revision|RCSFile|Source' |
6 hgkeywords = 'Id|Header|Author|Date|Revision|RCSFile|Source' |
|
7 |
|
8 def kwexpand(matchobj, repo, Revision, f, date, Author): |
|
9 '''Called by kwfilelog.read and pretxnkw. |
|
10 Sets supported keywords as local variables and evaluates them to |
|
11 their expansion if matchobj is equal to string representation.''' |
|
12 |
|
13 RCSFile = os.path.basename(f)+',v' |
|
14 Source = os.path.join(repo.root, f)+',v' |
|
15 Date = util.datestr(date=date) |
|
16 revdateauth = '%s %s %s' % (Revision, # %Y-%m-%d %H:%M:%S |
|
17 util.datestr(date=date, format=util.defaultdateformats[0]), |
|
18 util.shortuser(Author)) |
|
19 Header = '%s %s' % (Source, revdateauth) |
|
20 Id = '%s %s' % (RCSFile, revdateauth) |
|
21 |
|
22 return '$%s: %s $' % (matchobj.group(1), eval(matchobj.group(1))) |
|
23 |
5 |
24 |
6 def reposetup(ui, repo): |
25 def reposetup(ui, repo): |
7 if not repo.local(): |
26 if not repo.local(): |
8 return |
27 return |
9 |
28 |
34 for pat, opt in self._repo.ui.configitems('keyword'): |
53 for pat, opt in self._repo.ui.configitems('keyword'): |
35 if opt == 'expand': |
54 if opt == 'expand': |
36 mf = util.matcher(self._repo.root, |
55 mf = util.matcher(self._repo.root, |
37 '', [pat], [], [])[1] |
56 '', [pat], [], [])[1] |
38 if mf(f): |
57 if mf(f): |
|
58 |
|
59 def kwexpander(matchobj): |
|
60 return kwexpand(matchobj, |
|
61 self._repo, c.changectx(), f, |
|
62 c.date(), c.user()) |
|
63 |
39 re_kw = re.compile(r'\$(%s)\$' % hgkeywords) |
64 re_kw = re.compile(r'\$(%s)\$' % hgkeywords) |
40 |
65 return re_kw.sub(kwexpander, data) |
41 def kwexpand(matchobj): |
|
42 RCSFile = os.path.basename(f)+',v' |
|
43 Source = os.path.join(self._repo.root, f)+',v' |
|
44 Revision = c.changectx() |
|
45 Date = util.datestr(date=c.date()) |
|
46 Author = c.user() |
|
47 revdateauth = '%s %s %s' % ( |
|
48 Revision, |
|
49 util.datestr(date=c.date(), |
|
50 format=util.defaultdateformats[0]), |
|
51 util.shortuser(Author)) |
|
52 Header = '%s %s' % (Source, revdateauth) |
|
53 Id = '%s %s' % (RCSFile, revdateauth) |
|
54 return '$%s: %s $' % ( |
|
55 matchobj.group(1), eval(matchobj.group(1))) |
|
56 |
|
57 return re_kw.sub(kwexpand, data) |
|
58 return data |
66 return data |
59 |
67 |
60 def add(self, text, meta, tr, link, p1=None, p2=None): |
68 def add(self, text, meta, tr, link, p1=None, p2=None): |
61 if (not util.binary(text) and |
69 if (not util.binary(text) and |
62 self._repo.ui.config('keyword', 'remove', True)): |
70 self._repo.ui.config('keyword', 'remove', True)): |
64 text = re_kw.sub(r'$\1$', text) |
72 text = re_kw.sub(r'$\1$', text) |
65 return super(kwfilelog, self).add(text, meta, tr, link, p1, p2) |
73 return super(kwfilelog, self).add(text, meta, tr, link, p1, p2) |
66 |
74 |
67 filelog.filelog = kwfilelog |
75 filelog.filelog = kwfilelog |
68 repo.__class__ = kwrepo |
76 repo.__class__ = kwrepo |
|
77 |
|
78 |
|
79 def pretxnkw(ui, repo, hooktype, **args): |
|
80 '''pretxncommit hook that collects candidates for keyword expansion |
|
81 on commit and expands keywords in working dir.''' |
|
82 |
|
83 if hooktype != 'pretxncommit': # bail out with error |
|
84 return True |
|
85 |
|
86 # reparse args, opts again as pretxncommit hook is silent about them |
|
87 cmd, sysargs, globalopts, cmdopts = commands.parse(ui, sys.argv[1:])[1:] |
|
88 # exclude tag and import |
|
89 if repr(cmd).split()[1] in ('tag', 'import_'): |
|
90 return False |
|
91 |
|
92 files, match, anypats = cmdutil.matchpats(repo, sysargs, cmdopts) |
|
93 # validity checks should have been done already |
|
94 modified, added = repo.status(files=files, match=match)[:2] |
|
95 candidates = [f for f in modified + added if not f.startswith('.hg')] |
|
96 |
|
97 if not candidates: |
|
98 return False |
|
99 |
|
100 # only check files that are configured in keyword section |
|
101 files = [] |
|
102 # python2.4: files = set() |
|
103 for pat, opt in repo.ui.configitems('keyword'): |
|
104 if opt == 'expand': |
|
105 mf = util.matcher(repo.root, '', [pat], [], [])[1] |
|
106 for candidate in candidates: |
|
107 if mf(candidate) and candidate not in files: |
|
108 files.append(candidate) |
|
109 # python2.4: |
|
110 # if mf(candidate): files.add(candidate) |
|
111 |
|
112 if not files: |
|
113 return False |
|
114 |
|
115 user, date = repo.changelog.read(repo.changelog.tip())[1:3] |
|
116 # expand both expanded and unexpanded keywords |
|
117 re_kw = re.compile(r'\$(%s)(: [^$]+? )?\$' % hgkeywords) |
|
118 |
|
119 for f in files: |
|
120 data = repo.wfile(f).read() |
|
121 if not util.binary(data): |
|
122 |
|
123 def kwexpander(matchobj): |
|
124 return kwexpand(matchobj, |
|
125 repo, args['node'][:12], f, date, user) |
|
126 |
|
127 data, kwct = re_kw.subn(kwexpander, data) |
|
128 if kwct: |
|
129 ui.note(_('expanding keywords in %s\n' % f)) |
|
130 # backup file? |
|
131 repo.wfile(f, 'w').write(data) |