1 # $Hg: kwexpander.py,v$ |
1 # $Hg$ |
2 |
2 |
3 from mercurial.i18n import gettext as _ |
3 from mercurial import demandimport |
4 from mercurial.demandload import demandload |
4 demandimport.enable() |
5 demandload(globals(), 'mercurial:util') |
5 |
6 demandload(globals(), 'os.path re sys') |
6 from mercurial.i18n import _ |
|
7 import mercurial.util, re |
7 |
8 |
8 # name of keyword encode filter: |
9 # name of keyword encode filter: |
9 kwencodefilter = 'hgkwencode' |
10 kwencodefilter = 'hgkwencode' |
|
11 # look for <Dollar>Hg<Dollar> |
|
12 kwtrigger = '%sHg$' % '$' |
10 |
13 |
11 def expandkw(ui, repo, parent1, node, candidates): |
14 def wwritekw(ui, repo, f, text): |
|
15 '''Writes text with kwupdates keywords to f in working directory.''' |
|
16 ui.note(_('expanding keywords in %s\n' % f)) |
|
17 # # backup file (?) |
|
18 # absfile = repo.wjoin(f) |
|
19 # mercurial.util.copyfile(absfile, absfile+'.kwbak') |
|
20 repo.wfile(f, 'w').write(text) |
|
21 |
|
22 def expandkw(ui, repo, node, cid, candidates, update=False): |
12 '''Important: returns False on success, True on failure.''' |
23 '''Important: returns False on success, True on failure.''' |
13 |
24 |
|
25 # only check files that have hgkwencode assigned as encode filter |
14 files = [] |
26 files = [] |
15 for pat, cmd in repo.ui.configitems('encode'): |
27 for pat, cmd in repo.ui.configitems('encode'): |
16 if cmd.endswith(kwencodefilter): |
28 if cmd.endswith(kwencodefilter): |
17 mf = util.matcher(repo.root, '', [pat], [], [])[1] |
29 mf = mercurial.util.matcher(repo.root, '', [pat], [], [])[1] |
18 for candidate in candidates: |
30 for candidate in candidates: |
19 if mf(candidate): |
31 if mf(candidate): |
|
32 # check again that there really are no duplicates |
|
33 # if candidate not in files ??? |
20 files.append(candidate) |
34 files.append(candidate) |
21 |
35 |
22 if not files: # nothing to do |
36 if not files: # nothing to do |
23 return False |
37 return False |
24 |
38 |
25 user, date = repo.changelog.read(parent1)[1:3] |
39 user, date = repo.changelog.read(node)[1:3] |
26 user = util.shortuser(user) |
40 user = mercurial.util.shortuser(user) |
27 date = util.datestr(date=date, format=util.defaultdateformats[2]) |
41 date = mercurial.util.datestr(date=date, |
28 # %Y-%m-%d %H:%M |
42 format=mercurial.util.defaultdateformats[2]) |
29 re_kwcheck = re.compile(r'[$]Hg: (.*?),v.*?\$') |
43 # %Y-%m-%d %H:%M |
30 |
44 |
31 for fn in files: |
45 # collect filenames that were changed by hg update |
|
46 kwupdates = [] |
32 |
47 |
33 data = repo.wopener(fn, 'rb').read() |
48 for f in files: |
34 bn = os.path.basename(fn) |
|
35 |
49 |
36 # check for keywords with incorrect basename |
50 text = repo.wfile(f).read() |
37 # eg. if you forgot to update basename manually after "hg mv" |
51 kwrepl = '%sHg: %s,v %s %s %s $' % ('$', f, cid, date, user) |
38 failures = [m for m in map(str, re_kwcheck.findall(data)) if m != bn] |
|
39 if failures: |
|
40 failures = ['%sHg: %s,v$' % ('$', nobn) for nobn in failures] |
|
41 ui.warn(_('%d incorrect basenames in file %s:\n' |
|
42 '%s\nplease correct to %sHg: %s,v$\n' |
|
43 % (len(failures), fn, ', '.join(failures), '$', bn))) |
|
44 return True |
|
45 |
52 |
46 # substitute <Dollar>(Hg|Id): <basename>,v.*<Dollar> |
53 if update and text.find(kwtrigger) > -1: |
47 re_kw = re.compile(r'([$]Hg: %s,v).*?\$' % bn) |
54 text = text.replace(kwtrigger, kwrepl) |
48 data, kwct = re_kw.subn(r'\1 %s %s %s $' % (node, date, user), data) |
55 wwritekw(ui, repo, f, text) |
|
56 kwupdates.append(f) |
|
57 |
|
58 elif not update: |
|
59 re_kw = re.compile(r'[$]Hg(: %s,v [a-z0-9]{12} [^$]+? )?\$' % f) |
|
60 text, kwct = re_kw.subn(kwrepl, text) |
|
61 if kwct: |
|
62 wwritekw(ui, repo, f, text) |
49 |
63 |
50 if kwct: |
64 if kwupdates: |
51 # backup file and write with expanded keyword |
65 # cheat hg to believe that updated files were not modified |
52 ui.note(_('expanding keywords in %s\n' % fn)) |
66 repo.dirstate.update(kwupdates, 'n') |
53 util.copyfile(fn, fn+'~') |
|
54 repo.wopener(fn, 'wb').write(data) |
|
55 |
67 |
56 return False |
68 return False |