92 findcmd = commands.findcmd |
92 findcmd = commands.findcmd |
93 bail_if_changed = commands.bail_if_changed |
93 bail_if_changed = commands.bail_if_changed |
94 |
94 |
95 commands.optionalrepo += ' kwdemo' |
95 commands.optionalrepo += ' kwdemo' |
96 |
96 |
97 deftemplates = { |
|
98 'Revision': '{node|short}', |
|
99 'Author': '{author|user}', |
|
100 'Date': '{date|utcdate}', |
|
101 'RCSFile': '{file|basename},v', |
|
102 'Source': '{root}/{file},v', |
|
103 'Id': '{file|basename},v {node|short} {date|utcdate} {author|user}', |
|
104 'Header': '{root}/{file},v {node|short} {date|utcdate} {author|user}', |
|
105 } |
|
106 |
|
107 nokwcommands = ('add', 'addremove', 'bundle', 'clone', 'copy', 'export', |
|
108 'incoming', 'outgoing', 'push', 'remove', 'rename', 'rollback') |
|
109 |
|
110 keyword_raw = r'\$(%s)[^$\n\r]*?\$' |
|
111 |
|
112 def utcdate(date): |
97 def utcdate(date): |
113 '''Returns hgdate in cvs-like UTC format.''' |
98 '''Returns hgdate in cvs-like UTC format.''' |
114 return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0])) |
99 return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0])) |
115 |
|
116 def getcmd(ui): |
|
117 '''Returns current hg command.''' |
|
118 # commands.parse(ui, sys.argv[1:])[0] breaks "hg diff -r" |
|
119 try: |
|
120 args = fancyopts.fancyopts(sys.argv[1:], commands.globalopts, {}) |
|
121 except fancyopts.getopt.GetoptError, inst: |
|
122 raise commands.ParseError(None, inst) |
|
123 if args: |
|
124 cmd = args[0] |
|
125 aliases, i = findcmd(ui, cmd) |
|
126 return aliases[0] |
|
127 |
100 |
128 def keywordmatcher(ui, repo): |
101 def keywordmatcher(ui, repo): |
129 '''Collects include/exclude filename patterns for expansion |
102 '''Collects include/exclude filename patterns for expansion |
130 candidates of current configuration. Returns filename matching |
103 candidates of current configuration. Returns filename matching |
131 function if include patterns exist, None otherwise.''' |
104 function if include patterns exist, None otherwise.''' |
142 class kwtemplater(object): |
115 class kwtemplater(object): |
143 ''' |
116 ''' |
144 Sets up keyword templates, corresponding keyword regex, and |
117 Sets up keyword templates, corresponding keyword regex, and |
145 provides keyword substitution functions. |
118 provides keyword substitution functions. |
146 ''' |
119 ''' |
|
120 deftemplates = { |
|
121 'Revision': '{node|short}', |
|
122 'Author': '{author|user}', |
|
123 'Date': '{date|utcdate}', |
|
124 'RCSFile': '{file|basename},v', |
|
125 'Source': '{root}/{file},v', |
|
126 'Id': '{file|basename},v {node|short} {date|utcdate} {author|user}', |
|
127 'Header': '{root}/{file},v {node|short} {date|utcdate} {author|user}', |
|
128 } |
|
129 |
147 def __init__(self, ui, repo, path='', node=None, expand=True): |
130 def __init__(self, ui, repo, path='', node=None, expand=True): |
148 self.ui = ui |
131 self.ui = ui |
149 self.repo = repo |
132 self.repo = repo |
150 self.path = path |
133 self.path = path |
151 self.node = node |
134 self.node = node |
|
135 self.t = expand or None |
|
136 |
152 templates = dict(ui.configitems('keywordmaps')) |
137 templates = dict(ui.configitems('keywordmaps')) |
153 if templates: |
138 if templates: |
154 for k in templates.keys(): |
139 for k in templates.keys(): |
155 templates[k] = templater.parsestring(templates[k], |
140 templates[k] = templater.parsestring(templates[k], |
156 quoted=False) |
141 quoted=False) |
157 self.templates = templates or deftemplates |
142 self.templates = templates or self.deftemplates |
158 escaped = [re.escape(k) for k in self.templates.keys()] |
143 escaped = [re.escape(k) for k in self.templates.keys()] |
159 self.re_kw = re.compile(keyword_raw % '|'.join(escaped)) |
144 rawkeyword = r'\$(%s)[^$\n\r]*?\$' |
160 if expand: |
145 self.re_kw = re.compile(rawkeyword % '|'.join(escaped)) |
|
146 if self.t: |
161 templater.common_filters['utcdate'] = utcdate |
147 templater.common_filters['utcdate'] = utcdate |
162 try: |
148 try: |
163 self.t = cmdutil.changeset_templater(ui, repo, |
149 self.t = cmdutil.changeset_templater(self.ui, self.repo, |
164 False, '', False) |
150 False, '', False) |
165 except TypeError: |
151 except TypeError: |
166 # depending on hg rev changeset_templater has extra "brinfo" arg |
152 # depending on hg rev changeset_templater has extra "brinfo" arg |
167 self.t = cmdutil.changeset_templater(ui, repo, |
153 self.t = cmdutil.changeset_templater(self.ui, self.repo, |
168 False, None, '', False) |
154 False, None, '', False) |
169 else: |
|
170 self.t = None |
|
171 |
155 |
172 def ctxnode(self, node): |
156 def ctxnode(self, node): |
173 '''Obtains missing node from file context.''' |
157 '''Obtains missing node from file context.''' |
174 if not self.node: |
158 if not self.node: |
175 c = context.filectx(self.repo, self.path, fileid=node) |
159 c = context.filectx(self.repo, self.path, fileid=node) |
321 # for backwards compatibility |
305 # for backwards compatibility |
322 ui = _repo.ui |
306 ui = _repo.ui |
323 ui.setconfig('keyword', fn, '') |
307 ui.setconfig('keyword', fn, '') |
324 if opts['default']: |
308 if opts['default']: |
325 kwstatus = 'default' |
309 kwstatus = 'default' |
326 kwmaps = deftemplates |
310 kwmaps = kwtemplater.deftemplates |
327 else: |
311 else: |
328 if args or opts['rcfile']: |
312 if args or opts['rcfile']: |
329 kwstatus = 'custom' |
313 kwstatus = 'custom' |
330 for tmap in args: |
314 for tmap in args: |
331 k, v = tmap.split('=', 1) |
315 k, v = tmap.split('=', 1) |
332 ui.setconfig('keywordmaps', k.strip(), v.strip()) |
316 ui.setconfig('keywordmaps', k.strip(), v.strip()) |
333 if opts['rcfile']: |
317 if opts['rcfile']: |
334 ui.readconfig(opts['rcfile']) |
318 ui.readconfig(opts['rcfile']) |
335 kwmaps = dict(ui.configitems('keywordmaps')) or deftemplates |
319 kwmaps = (dict(ui.configitems('keywordmaps')) or |
|
320 kwtemplater.deftemplates) |
336 if ui.configitems('keywordmaps'): |
321 if ui.configitems('keywordmaps'): |
337 for k, v in kwmaps.items(): |
322 for k, v in kwmaps.items(): |
338 ui.setconfig('keywordmaps', k, v) |
323 ui.setconfig('keywordmaps', k, v) |
339 reposetup(ui, _repo) |
324 reposetup(ui, _repo) |
340 ui.status(_('config with %s keyword template maps:\n') % kwstatus) |
325 ui.status(_('config with %s keyword template maps:\n') % kwstatus) |
363 Wraps commit to overwrite configured files with updated |
348 Wraps commit to overwrite configured files with updated |
364 keyword substitutions. |
349 keyword substitutions. |
365 This is done for local repos only, and only if there are |
350 This is done for local repos only, and only if there are |
366 files configured at all for keyword substitution.''' |
351 files configured at all for keyword substitution.''' |
367 |
352 |
|
353 nokwcommands = ['add', 'addremove', 'bundle', 'clone', 'copy', 'export', |
|
354 'grep', 'identify', 'incoming', 'init', 'outgoing', 'push', |
|
355 'remove', 'rename', 'rollback'] |
|
356 |
368 # for backwards compatibility |
357 # for backwards compatibility |
369 ui = repo.ui |
358 ui = repo.ui |
370 |
359 |
371 if not repo.local() or getcmd(ui) in nokwcommands: |
360 def getcmd(): |
|
361 # cmdutil.parse(ui, sys.argv[1:])[0] doesn't work for "hg diff -r" |
|
362 args = fancyopts.fancyopts(sys.argv[1:], commands.globalopts, {}) |
|
363 if args: |
|
364 cmd = args[0] |
|
365 aliases, i = findcmd(ui, cmd) |
|
366 return aliases[0] |
|
367 |
|
368 if not repo.local() or getcmd() in nokwcommands: |
372 return |
369 return |
373 |
370 |
374 kwfmatcher = keywordmatcher(ui, repo) |
371 kwfmatcher = keywordmatcher(ui, repo) |
375 if kwfmatcher is None: |
372 if kwfmatcher is None: |
376 return |
373 return |
380 if f[0] == '/': |
377 if f[0] == '/': |
381 f = f[1:] |
378 f = f[1:] |
382 if kwfmatcher(f): |
379 if kwfmatcher(f): |
383 kwt = kwtemplater(ui, self, path=f, expand=kwexp) |
380 kwt = kwtemplater(ui, self, path=f, expand=kwexp) |
384 return kwfilelog(self.sopener, f, kwt, kwcnt) |
381 return kwfilelog(self.sopener, f, kwt, kwcnt) |
385 else: |
382 return filelog.filelog(self.sopener, f) |
386 return filelog.filelog(self.sopener, f) |
|
387 |
383 |
388 def commit(self, files=None, text='', user=None, date=None, |
384 def commit(self, files=None, text='', user=None, date=None, |
389 match=util.always, force=False, lock=None, wlock=None, |
385 match=util.always, force=False, lock=None, wlock=None, |
390 force_editor=False, p1=None, p2=None, extra={}): |
386 force_editor=False, p1=None, p2=None, extra={}): |
391 wrelease = False |
387 wrelease = False |