78 Expansions spanning more than one line and incremental expansions, |
78 Expansions spanning more than one line and incremental expansions, |
79 like CVS' $Log$, are not supported. A keyword template map |
79 like CVS' $Log$, are not supported. A keyword template map |
80 "Log = {desc}" expands to the first line of the changeset description. |
80 "Log = {desc}" expands to the first line of the changeset description. |
81 ''' |
81 ''' |
82 |
82 |
83 from mercurial import commands, cmdutil, context, localrepo |
83 from mercurial import commands, cmdutil, context, filelog, localrepo |
84 from mercurial import patch, revlog, templater, util |
84 from mercurial import patch, revlog, templater, util |
85 from mercurial.node import * |
85 from mercurial.node import * |
86 from mercurial.i18n import _ |
86 from mercurial.i18n import _ |
87 import re, shutil, tempfile, time |
87 import re, shutil, tempfile, time |
88 |
88 |
135 self.ctx = self.repo.changectx() |
135 self.ctx = self.repo.changectx() |
136 fnode = self.ctx.filenode(path) |
136 fnode = self.ctx.filenode(path) |
137 fl = self.repo.file(path) |
137 fl = self.repo.file(path) |
138 c = context.filectx(self.repo, path, fileid=fnode, filelog=fl) |
138 c = context.filectx(self.repo, path, fileid=fnode, filelog=fl) |
139 node = c.node() |
139 node = c.node() |
|
140 elif subfunc == self.re_kw.sub: |
|
141 # hg kwcat using kwfilelog.read |
|
142 c = context.filectx(self.repo, path, fileid=node) |
|
143 node = c.node() |
140 |
144 |
141 def kwsub(mobj): |
145 def kwsub(mobj): |
142 '''Substitutes keyword using corresponding template.''' |
146 '''Substitutes keyword using corresponding template.''' |
143 kw = mobj.group(1) |
147 kw = mobj.group(1) |
144 self.ct.use_template(self.templates[kw]) |
148 self.ct.use_template(self.templates[kw]) |
146 self.ct.show(changenode=node, root=self.repo.root, file=path) |
150 self.ct.show(changenode=node, root=self.repo.root, file=path) |
147 return '$%s: %s $' % (kw, templater.firstline(self.ui.popbuffer())) |
151 return '$%s: %s $' % (kw, templater.firstline(self.ui.popbuffer())) |
148 |
152 |
149 return subfunc(kwsub, data) |
153 return subfunc(kwsub, data) |
150 |
154 |
151 def expand(self, path, data): |
155 def expand(self, path, data, node): |
152 '''Returns data with keywords expanded.''' |
156 '''Returns data with keywords expanded.''' |
153 if util.binary(data): |
157 if util.binary(data): |
154 return data |
158 return data |
155 return self.substitute(path, data, None, self.re_kw.sub) |
159 return self.substitute(path, data, node, self.re_kw.sub) |
156 |
160 |
157 def process(self, path, data, expand, ctx, node): |
161 def process(self, path, data, expand, ctx, node): |
158 '''Returns a tuple: data, count. |
162 '''Returns a tuple: data, count. |
159 Count is number of keywords/keyword substitutions, |
163 Count is number of keywords/keyword substitutions, |
160 telling caller whether to act on file containing data.''' |
164 telling caller whether to act on file containing data.''' |
168 def shrink(self, data): |
172 def shrink(self, data): |
169 '''Returns text with all keyword substitutions removed.''' |
173 '''Returns text with all keyword substitutions removed.''' |
170 if util.binary(data): |
174 if util.binary(data): |
171 return data |
175 return data |
172 return self.re_kw.sub(r'$\1$', data) |
176 return self.re_kw.sub(r'$\1$', data) |
|
177 |
|
178 class kwfilelog(filelog.filelog): |
|
179 ''' |
|
180 Subclass of filelog to hook into its read method for kwcat. |
|
181 ''' |
|
182 def __init__(self, opener, path, kwt): |
|
183 super(kwfilelog, self).__init__(opener, path) |
|
184 self._kwt = kwt |
|
185 self._path = path |
|
186 |
|
187 def read(self, node): |
|
188 '''Expands keywords when reading filelog.''' |
|
189 data = super(kwfilelog, self).read(node) |
|
190 return self._kwt.expand(self._path, data, node) |
173 |
191 |
174 # store original patch.patchfile.__init__ |
192 # store original patch.patchfile.__init__ |
175 _patchfile_init = patch.patchfile.__init__ |
193 _patchfile_init = patch.patchfile.__init__ |
176 |
194 |
177 |
195 |
222 lock = repo.lock() |
240 lock = repo.lock() |
223 _overwrite(ui, repo, expand=expand, files=clean) |
241 _overwrite(ui, repo, expand=expand, files=clean) |
224 finally: |
242 finally: |
225 del wlock, lock |
243 del wlock, lock |
226 |
244 |
|
245 def cat(ui, repo, file1, *pats, **opts): |
|
246 '''output the current or given revision of files expanding keywords |
|
247 |
|
248 Print the specified files as they were at the given revision. |
|
249 If no revision is given, the parent of the working directory is used, |
|
250 or tip if no revision is checked out. |
|
251 |
|
252 Output may be to a file, in which case the name of the file is |
|
253 given using a format string. The formatting rules are the same as |
|
254 for the export command, with the following additions: |
|
255 |
|
256 %s basename of file being printed |
|
257 %d dirname of file being printed, or '.' if in repo root |
|
258 %p root-relative path name of file being printed |
|
259 ''' |
|
260 try: |
|
261 repo.file = repo._kwfile |
|
262 except AttributeError: |
|
263 pass |
|
264 commands.cat(ui, repo, file1, *pats, **opts) |
227 |
265 |
228 def demo(ui, repo, *args, **opts): |
266 def demo(ui, repo, *args, **opts): |
229 '''print [keywordmaps] configuration and an expansion example |
267 '''print [keywordmaps] configuration and an expansion example |
230 |
268 |
231 Show current, custom, or default keyword template maps |
269 Show current, custom, or default keyword template maps |
362 exc.append(pat) |
400 exc.append(pat) |
363 if not inc: |
401 if not inc: |
364 return |
402 return |
365 |
403 |
366 class kwrepo(repo.__class__): |
404 class kwrepo(repo.__class__): |
|
405 def _kwfile(self, f): |
|
406 '''Returns filelog expanding keywords on read (for kwcat).''' |
|
407 if f[0] == '/': |
|
408 f = f[1:] |
|
409 if self._kwt.matcher(f): |
|
410 return kwfilelog(self.sopener, f, self._kwt) |
|
411 return filelog.filelog(self.sopener, f) |
|
412 |
367 def _wreadkwct(self, filename, expand, ctx, node): |
413 def _wreadkwct(self, filename, expand, ctx, node): |
368 '''Reads filename and returns tuple of data with keywords |
414 '''Reads filename and returns tuple of data with keywords |
369 expanded/shrunk and count of keywords (for _overwrite).''' |
415 expanded/shrunk and count of keywords (for _overwrite).''' |
370 data = super(kwrepo, self).wread(filename) |
416 data = super(kwrepo, self).wread(filename) |
371 return self._kwt.process(filename, data, expand, ctx, node) |
417 return self._kwt.process(filename, data, expand, ctx, node) |
376 return self._kwt.shrink(data) |
422 return self._kwt.shrink(data) |
377 return data |
423 return data |
378 |
424 |
379 def wwrite(self, filename, data, flags, overwrite=False): |
425 def wwrite(self, filename, data, flags, overwrite=False): |
380 if not overwrite and self._kwt.matcher(filename): |
426 if not overwrite and self._kwt.matcher(filename): |
381 data = self._kwt.expand(filename, data) |
427 data = self._kwt.expand(filename, data, None) |
382 super(kwrepo, self).wwrite(filename, data, flags) |
428 super(kwrepo, self).wwrite(filename, data, flags) |
383 |
429 |
384 def wwritedata(self, filename, data): |
430 def wwritedata(self, filename, data): |
385 if self._kwt.matcher(filename): |
431 if self._kwt.matcher(filename): |
386 data = self._kwt.expand(filename, data) |
432 data = self._kwt.expand(filename, data, None) |
387 return super(kwrepo, self).wwritedata(filename, data) |
433 return super(kwrepo, self).wwritedata(filename, data) |
388 |
434 |
389 def commit(self, files=None, text='', user=None, date=None, |
435 def commit(self, files=None, text='', user=None, date=None, |
390 match=util.always, force=False, force_editor=False, |
436 match=util.always, force=False, force_editor=False, |
391 p1=None, p2=None, extra={}): |
437 p1=None, p2=None, extra={}): |
443 repo.__class__ = kwrepo |
489 repo.__class__ = kwrepo |
444 patch.patchfile.__init__ = kwpatchfile_init |
490 patch.patchfile.__init__ = kwpatchfile_init |
445 |
491 |
446 |
492 |
447 cmdtable = { |
493 cmdtable = { |
|
494 'kwcat': |
|
495 (cat, commands.table['cat'][1], |
|
496 _('hg kwcat [OPTION]... FILE...')), |
448 'kwdemo': |
497 'kwdemo': |
449 (demo, |
498 (demo, |
450 [('d', 'default', None, _('show default keyword template maps')), |
499 [('d', 'default', None, _('show default keyword template maps')), |
451 ('f', 'rcfile', [], _('read maps from rcfile'))], |
500 ('f', 'rcfile', [], _('read maps from rcfile'))], |
452 _('hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]...')), |
501 _('hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]...')), |