102 '''Returns hgdate in cvs-like UTC format.''' |
102 '''Returns hgdate in cvs-like UTC format.''' |
103 return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0])) |
103 return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0])) |
104 |
104 |
105 |
105 |
106 # make keyword tools accessible |
106 # make keyword tools accessible |
107 kwtools = {'templater': None, 'hgcmd': None} |
107 kwtools = {'templater': None, 'hgcmd': '', 'inc': [], 'exc': ['.hg*']} |
108 |
108 |
109 # store originals of monkeypatches |
109 # store originals of monkeypatches to be done at end of reposetup |
|
110 # that is, only if needed |
110 _patchfile_init = patch.patchfile.__init__ |
111 _patchfile_init = patch.patchfile.__init__ |
111 _patch_diff = patch.diff |
112 _patch_diff = patch.diff |
112 _dispatch_parse = dispatch._parse |
|
113 _webcommands_changeset = webcommands.changeset |
113 _webcommands_changeset = webcommands.changeset |
114 _webcommands_filediff = webcommands.filediff |
114 _webcommands_filediff = webcommands.filediff |
115 |
115 |
116 def _kwpatchfile_init(self, ui, fname, missing=False): |
116 def _kwpatchfile_init(self, ui, fname, missing=False): |
117 '''Monkeypatch/wrap patch.patchfile.__init__ to avoid |
117 '''Monkeypatch/wrap patch.patchfile.__init__ to avoid |
140 def _kwweb_filediff(web, req, tmpl): |
140 def _kwweb_filediff(web, req, tmpl): |
141 '''Wraps webcommands.filediff turning off keyword expansion.''' |
141 '''Wraps webcommands.filediff turning off keyword expansion.''' |
142 kwtools['templater'].matcher = util.never |
142 kwtools['templater'].matcher = util.never |
143 return _webcommands_filediff(web, req, tmpl) |
143 return _webcommands_filediff(web, req, tmpl) |
144 |
144 |
145 def _kwdispatch_parse(ui, args): |
|
146 '''Monkeypatch dispatch._parse to obtain running hg command.''' |
|
147 cmd, func, args, options, cmdoptions = _dispatch_parse(ui, args) |
|
148 kwtools['hgcmd'] = cmd |
|
149 return cmd, func, args, options, cmdoptions |
|
150 |
|
151 # dispatch._parse is run before reposetup, so wrap it here |
|
152 # all other actual monkey patching is done at end of reposetup |
|
153 dispatch._parse = _kwdispatch_parse |
|
154 |
|
155 |
145 |
156 class kwtemplater(object): |
146 class kwtemplater(object): |
157 ''' |
147 ''' |
158 Sets up keyword templates, corresponding keyword regex, and |
148 Sets up keyword templates, corresponding keyword regex, and |
159 provides keyword substitution functions. |
149 provides keyword substitution functions. |
166 'Source': '{root}/{file},v', |
156 'Source': '{root}/{file},v', |
167 'Id': '{file|basename},v {node|short} {date|utcdate} {author|user}', |
157 'Id': '{file|basename},v {node|short} {date|utcdate} {author|user}', |
168 'Header': '{root}/{file},v {node|short} {date|utcdate} {author|user}', |
158 'Header': '{root}/{file},v {node|short} {date|utcdate} {author|user}', |
169 } |
159 } |
170 |
160 |
171 def __init__(self, ui, repo, inc, exc): |
161 def __init__(self, ui, repo): |
172 self.ui = ui |
162 self.ui = ui |
173 self.repo = repo |
163 self.repo = repo |
174 self.matcher = util.matcher(repo.root, inc=inc, exc=exc)[1] |
164 self.matcher = util.matcher(repo.root, |
|
165 inc=kwtools['inc'], exc=kwtools['exc'])[1] |
175 self.restrict = kwtools['hgcmd'] in restricted.split() |
166 self.restrict = kwtools['hgcmd'] in restricted.split() |
176 |
167 |
177 kwmaps = self.ui.configitems('keywordmaps') |
168 kwmaps = self.ui.configitems('keywordmaps') |
178 if kwmaps: # override default templates |
169 if kwmaps: # override default templates |
179 kwmaps = [(k, templater.parsestring(v, quoted=False)) |
170 kwmaps = [(k, templater.parsestring(v, quoted=False)) |
370 fp.writelines(rcmaps) |
361 fp.writelines(rcmaps) |
371 fp.close() |
362 fp.close() |
372 ui.readconfig(repo.join('hgrc')) |
363 ui.readconfig(repo.join('hgrc')) |
373 if not opts.get('default'): |
364 if not opts.get('default'): |
374 kwmaps = dict(ui.configitems('keywordmaps')) or kwtemplater.templates |
365 kwmaps = dict(ui.configitems('keywordmaps')) or kwtemplater.templates |
|
366 uisetup(ui) |
375 reposetup(ui, repo) |
367 reposetup(ui, repo) |
376 for k, v in ui.configitems('extensions'): |
368 for k, v in ui.configitems('extensions'): |
377 if k.endswith('keyword'): |
369 if k.endswith('keyword'): |
378 extension = '%s = %s' % (k, v) |
370 extension = '%s = %s' % (k, v) |
379 break |
371 break |
451 ''' |
443 ''' |
452 # 3rd argument sets expansion to False |
444 # 3rd argument sets expansion to False |
453 _kwfwrite(ui, repo, False, *pats, **opts) |
445 _kwfwrite(ui, repo, False, *pats, **opts) |
454 |
446 |
455 |
447 |
|
448 def uisetup(ui): |
|
449 '''Collects [keyword] config in kwtools. |
|
450 Monkeypatches dispatch._parse if needed.''' |
|
451 |
|
452 for pat, opt in ui.configitems('keyword'): |
|
453 if opt != 'ignore': |
|
454 kwtools['inc'].append(pat) |
|
455 else: |
|
456 kwtools['exc'].append(pat) |
|
457 |
|
458 if kwtools['inc']: |
|
459 def kwdispatch_parse(ui, args): |
|
460 '''Monkeypatch dispatch._parse to obtain running hg command.''' |
|
461 cmd, func, args, options, cmdoptions = dispatch_parse(ui, args) |
|
462 kwtools['hgcmd'] = cmd |
|
463 return cmd, func, args, options, cmdoptions |
|
464 |
|
465 dispatch_parse = dispatch._parse |
|
466 dispatch._parse = kwdispatch_parse |
|
467 |
456 def reposetup(ui, repo): |
468 def reposetup(ui, repo): |
457 '''Sets up repo as kwrepo for keyword substitution. |
469 '''Sets up repo as kwrepo for keyword substitution. |
458 Overrides file method to return kwfilelog instead of filelog |
470 Overrides file method to return kwfilelog instead of filelog |
459 if file matches user configuration. |
471 if file matches user configuration. |
460 Wraps commit to overwrite configured files with updated |
472 Wraps commit to overwrite configured files with updated |
461 keyword substitutions. |
473 keyword substitutions. |
462 This is done for local repos only, and only if there are |
474 This is done for local repos only, and only if there are |
463 files configured at all for keyword substitution.''' |
475 files configured at all for keyword substitution.''' |
464 |
476 |
465 try: |
477 try: |
466 if (not repo.local() or kwtools['hgcmd'] in nokwcommands.split() |
478 if (not repo.local() or not kwtools['inc'] |
|
479 or kwtools['hgcmd'] in nokwcommands.split() |
467 or '.hg' in util.splitpath(repo.root) |
480 or '.hg' in util.splitpath(repo.root) |
468 or repo._url.startswith('bundle:')): |
481 or repo._url.startswith('bundle:')): |
469 return |
482 return |
470 except AttributeError: |
483 except AttributeError: |
471 pass |
484 pass |
472 |
485 |
473 inc, exc = [], ['.hg*'] |
486 kwtools['templater'] = kwt = kwtemplater(ui, repo) |
474 for pat, opt in ui.configitems('keyword'): |
|
475 if opt != 'ignore': |
|
476 inc.append(pat) |
|
477 else: |
|
478 exc.append(pat) |
|
479 if not inc: |
|
480 return |
|
481 |
|
482 kwtools['templater'] = kwt = kwtemplater(ui, repo, inc, exc) |
|
483 |
487 |
484 class kwrepo(repo.__class__): |
488 class kwrepo(repo.__class__): |
485 def file(self, f): |
489 def file(self, f): |
486 if f[0] == '/': |
490 if f[0] == '/': |
487 f = f[1:] |
491 f = f[1:] |