42 |
42 |
43 Keywords are only expanded in local repositories and not logged by |
43 Keywords are only expanded in local repositories and not logged by |
44 Mercurial internally. The mechanism can be regarded as a convenience |
44 Mercurial internally. The mechanism can be regarded as a convenience |
45 for the current user and may be turned off anytime. |
45 for the current user and may be turned off anytime. |
46 |
46 |
|
47 An additional date template filter {date|utcdate} is provided. |
|
48 |
47 Caveat: "hg import" might fail if the patches were exported from a |
49 Caveat: "hg import" might fail if the patches were exported from a |
48 repo with a different/no keyword setup, whereas "hg unbundle" is |
50 repo with a different/no keyword setup, whereas "hg unbundle" is |
49 safe. |
51 safe. |
50 |
52 |
51 Configuration is done in the [keyword] and [keywordmaps] sections of |
53 Configuration is done in the [keyword] and [keywordmaps] sections of |
52 hgrc files. |
54 hgrc files. |
53 |
55 |
54 Example: |
56 Example: |
55 [keyword] |
57 [extensions] |
56 # filename patterns for expansion are configured in this section |
58 hgext.keyword = |
57 # files matching patterns with value 'ignore' are ignored |
59 |
58 **.py = ## expand keywords in all python files |
60 [keyword] |
59 x* = ignore ## but ignore files matching "x*" |
61 # expand keywords in every python file, |
60 ... |
62 # except those matching "x*" |
61 [keywordmaps] |
63 **.py = |
62 # custom hg template maps _replace_ the CVS-like default ones |
64 x* = ignore |
63 HGdate = {date|rfc822date} |
65 |
64 lastlog = {desc} ## same as {desc|firstline} in this context |
66 For [keywordmaps] demonstration run "hg kwdemo". |
65 checked in by = {author} |
|
66 ... |
|
67 |
|
68 If no [keywordmaps] are configured the extension falls back on the |
|
69 following defaults: |
|
70 |
|
71 Revision: changeset id |
|
72 Author: username |
|
73 Date: %Y/%m/%d %H:%M:%S ## [UTC] |
|
74 RCSFile: basename,v |
|
75 Source: /path/to/basename,v |
|
76 Id: basename,v csetid %Y/%m/%d %H:%M:%S username |
|
77 Header: /path/to/basename,v csetid %Y/%m/%d %H:%M:%S username |
|
78 ''' |
67 ''' |
79 |
68 |
80 from mercurial.i18n import gettext as _ |
69 from mercurial.i18n import gettext as _ |
81 from mercurial import commands, fancyopts, templater, util |
70 from mercurial import commands, fancyopts, templater, util |
82 from mercurial import cmdutil, context, filelog |
71 from mercurial import cmdutil, context, filelog, localrepo |
83 # findcmd might be in cmdutil or commands |
72 # findcmd might be in cmdutil or commands |
84 # depending on mercurial version |
73 # depending on mercurial version |
85 if hasattr(cmdutil, 'findcmd'): |
74 if hasattr(cmdutil, 'findcmd'): |
86 findcmd = cmdutil.findcmd |
75 findcmd = cmdutil.findcmd |
87 else: |
76 else: |
88 findcmd = commands.findcmd |
77 findcmd = commands.findcmd |
89 import os, re, sys, time |
78 import os, re, shutil, sys, tempfile, time |
90 |
79 |
91 deftemplates = { |
80 deftemplates = { |
92 'Revision': '{node|short}', |
81 'Revision': '{node|short}', |
93 'Author': '{author|user}', |
82 'Author': '{author|user}', |
94 'Date': '{date|utcdate}', |
83 'Date': '{date|utcdate}', |
95 'RCSFile': '{file|basename},v', |
84 'RCSFile': '{file|basename},v', |
96 'Source': '{root}/{file},v', |
85 'Source': '{root}/{file},v', |
97 'Id': '{file|basename},v {node|short} {date|utcdate} {author|user}', |
86 'Id': '{file|basename},v {node|short} {date|utcdate} {author|user}', |
98 'Header': '{root}/{file},v {node|short} {date|utcdate} {author|user}', |
87 'Header': '{root}/{file},v {node|short} {date|utcdate} {author|user}', |
99 } |
88 } |
100 |
89 |
101 nokwcommands = ('add', 'addremove', 'bundle', 'clone', 'copy', 'export', |
90 nokwcommands = ('add', 'addremove', 'bundle', 'clone', 'copy', 'export', |
102 'incoming', 'outgoing', 'push', 'remove', 'rename', 'rollback') |
91 'incoming', 'outgoing', 'push', 'remove', 'rename', 'rollback') |
103 |
92 |
104 def utcdate(date): |
93 def utcdate(date): |
105 '''Returns hgdate in cvs-like UTC format.''' |
94 '''Returns hgdate in cvs-like UTC format.''' |
106 return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0])) |
95 return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0])) |
|
96 |
|
97 def kwdemo(ui, repo, **opts): |
|
98 '''print [keywordmaps] configuration and an expansion example |
|
99 ''' |
|
100 log = 'hg keyword config and expansion example' |
|
101 fn = 'demo.txt' |
|
102 ui.setconfig('keyword', fn, '') |
|
103 if opts['default']: |
|
104 kwstatus = 'default' |
|
105 kwmaps = deftemplates |
|
106 if ui.configitems('keywordmaps'): |
|
107 for k, v in kwmaps.items(): |
|
108 ui.setconfig('keywordmaps', k, v) |
|
109 else: |
|
110 kwstatus = 'current' |
|
111 kwmaps = dict(ui.configitems('keywordmaps')) or deftemplates |
|
112 tmpdir = tempfile.mkdtemp('', 'kwdemo.') |
|
113 if ui.verbose: |
|
114 ui.status(_('creating temporary repo at %s\n') % tmpdir) |
|
115 _repo = localrepo.localrepository(ui, path=tmpdir, create=True) |
|
116 reposetup(ui, _repo) |
|
117 ui.status(_('config with %s keyword maps:\n') % kwstatus) |
|
118 ui.write('[keyword]\n%s =\n[keywordmaps\n' % fn) |
|
119 for k, v in kwmaps.items(): |
|
120 ui.write('%s = %s\n' % (k, v)) |
|
121 path = _repo.wjoin(fn) |
|
122 keywords = '$' + '$\n$'.join(kwmaps.keys()) + '$\n' |
|
123 _repo.wfile(fn, 'w').write(keywords) |
|
124 _repo.add([fn]) |
|
125 if ui.verbose: |
|
126 ui.status(_('\n%s keywords written to %s:\n') % (kwstatus, path)) |
|
127 ui.write(keywords) |
|
128 ui.status(_("\nhg --repository '%s' commit\n") % tmpdir) |
|
129 _repo.commit(text=log) |
|
130 if ui.verbose: |
|
131 ui.status(_('\n%s keywords expanded in %s:\n') % (kwstatus, path)) |
|
132 else: |
|
133 ui.status(_('\n%s keywords expanded:\n') % kwstatus) |
|
134 ui.write(_repo.wread(fn)) |
|
135 ui.debug(_('\nremoving temporary repo\n')) |
|
136 shutil.rmtree(tmpdir) |
107 |
137 |
108 def getcmd(ui): |
138 def getcmd(ui): |
109 '''Returns current hg command.''' |
139 '''Returns current hg command.''' |
110 # commands.parse(ui, sys.argv[1:])[0] breaks "hg diff -r" |
140 # commands.parse(ui, sys.argv[1:])[0] breaks "hg diff -r" |
111 try: |
141 try: |