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, filelog, localrepo |
83 from mercurial import commands, cmdutil, context, localrepo |
84 from mercurial import patch, revlog, templater, templatefilters, util |
84 from mercurial import patch, revlog, templater, templatefilters, util |
85 from mercurial.node import * |
85 from mercurial.node import * |
86 from mercurial.hgweb import webcommands |
86 from mercurial.hgweb import webcommands |
87 from mercurial.i18n import _ |
87 from mercurial.i18n import _ |
88 import mimetypes, re, shutil, tempfile, time |
88 import mimetypes, re, shutil, tempfile, time |
140 c = context.filectx(self.repo, path, fileid=fnode, filelog=fl) |
140 c = context.filectx(self.repo, path, fileid=fnode, filelog=fl) |
141 node = c.node() |
141 node = c.node() |
142 except revlog.LookupError: |
142 except revlog.LookupError: |
143 # eg: convert |
143 # eg: convert |
144 return subfunc == self.re_kw.sub and data or (data, None) |
144 return subfunc == self.re_kw.sub and data or (data, None) |
145 elif subfunc == self.re_kw.sub: |
|
146 # hg kwcat using kwfilelog.read |
|
147 c = context.filectx(self.repo, path, fileid=node) |
|
148 node = c.node() |
|
149 |
145 |
150 def kwsub(mobj): |
146 def kwsub(mobj): |
151 '''Substitutes keyword using corresponding template.''' |
147 '''Substitutes keyword using corresponding template.''' |
152 kw = mobj.group(1) |
148 kw = mobj.group(1) |
153 self.ct.use_template(self.templates[kw]) |
149 self.ct.use_template(self.templates[kw]) |
178 def shrink(self, data): |
174 def shrink(self, data): |
179 '''Returns text with all keyword substitutions removed.''' |
175 '''Returns text with all keyword substitutions removed.''' |
180 if util.binary(data): |
176 if util.binary(data): |
181 return data |
177 return data |
182 return self.re_kw.sub(r'$\1$', data) |
178 return self.re_kw.sub(r'$\1$', data) |
183 |
|
184 class kwfilelog(filelog.filelog): |
|
185 ''' |
|
186 Subclass of filelog to hook into its read method for kwcat. |
|
187 ''' |
|
188 def __init__(self, opener, path, kwt): |
|
189 super(kwfilelog, self).__init__(opener, path) |
|
190 self._kwt = kwt |
|
191 self._path = path |
|
192 |
|
193 def read(self, node): |
|
194 '''Expands keywords when reading filelog.''' |
|
195 data = super(kwfilelog, self).read(node) |
|
196 return self._kwt.expand(self._path, data, node) |
|
197 |
179 |
198 # store original patch.patchfile.__init__ |
180 # store original patch.patchfile.__init__ |
199 _patchfile_init = patch.patchfile.__init__ |
181 _patchfile_init = patch.patchfile.__init__ |
200 |
182 |
201 |
183 |
261 |
243 |
262 %s basename of file being printed |
244 %s basename of file being printed |
263 %d dirname of file being printed, or '.' if in repo root |
245 %d dirname of file being printed, or '.' if in repo root |
264 %p root-relative path name of file being printed |
246 %p root-relative path name of file being printed |
265 ''' |
247 ''' |
|
248 ctx = repo.changectx(opts['rev']) |
266 try: |
249 try: |
267 repo.file = repo._kwfile |
250 repo._kwt.ctx = ctx |
|
251 kw = True |
268 except AttributeError: |
252 except AttributeError: |
269 pass |
253 kw = False |
270 commands.cat(ui, repo, file1, *pats, **opts) |
254 err = 1 |
|
255 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts, |
|
256 ctx.node()): |
|
257 fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs) |
|
258 data = ctx.filectx(abs).data() |
|
259 if kw and repo._kwt.matcher(abs): |
|
260 data = repo._kwt.expand(abs, data, None) |
|
261 fp.write(data) |
|
262 err = 0 |
|
263 return err |
271 |
264 |
272 def demo(ui, repo, *args, **opts): |
265 def demo(ui, repo, *args, **opts): |
273 '''print [keywordmaps] configuration and an expansion example |
266 '''print [keywordmaps] configuration and an expansion example |
274 |
267 |
275 Show current, custom, or default keyword template maps |
268 Show current, custom, or default keyword template maps |
406 exc.append(pat) |
399 exc.append(pat) |
407 if not inc: |
400 if not inc: |
408 return |
401 return |
409 |
402 |
410 class kwrepo(repo.__class__): |
403 class kwrepo(repo.__class__): |
411 def _kwfile(self, f): |
|
412 '''Returns filelog expanding keywords on read (for kwcat).''' |
|
413 if f[0] == '/': |
|
414 f = f[1:] |
|
415 if self._kwt.matcher(f): |
|
416 return kwfilelog(self.sopener, f, self._kwt) |
|
417 return filelog.filelog(self.sopener, f) |
|
418 |
|
419 def _wreadkwct(self, filename, expand, ctx, node): |
404 def _wreadkwct(self, filename, expand, ctx, node): |
420 '''Reads filename and returns tuple of data with keywords |
405 '''Reads filename and returns tuple of data with keywords |
421 expanded/shrunk and count of keywords (for _overwrite).''' |
406 expanded/shrunk and count of keywords (for _overwrite).''' |
422 data = super(kwrepo, self).wread(filename) |
407 data = super(kwrepo, self).wread(filename) |
423 return self._kwt.process(filename, data, expand, ctx, node) |
408 return self._kwt.process(filename, data, expand, ctx, node) |
507 req.respond(webcommands.HTTP_OK, web.ctype) |
492 req.respond(webcommands.HTTP_OK, web.ctype) |
508 return content |
493 return content |
509 path = fctx.path() |
494 path = fctx.path() |
510 text = fctx.data() |
495 text = fctx.data() |
511 if kwt.matcher(path): |
496 if kwt.matcher(path): |
512 text = kwt.expand(path, text, None) |
497 text = kwt.expand(path, text, fctx.node()) |
513 mt = mimetypes.guess_type(path)[0] |
498 mt = mimetypes.guess_type(path)[0] |
514 if mt is None or util.binary(text): |
499 if mt is None or util.binary(text): |
515 mt = mt or 'application/octet-stream' |
500 mt = mt or 'application/octet-stream' |
516 req.respond(webcommands.HTTP_OK, mt, path, len(text)) |
501 req.respond(webcommands.HTTP_OK, mt, path, len(text)) |
517 return [text] |
502 return [text] |