diff -r 7bc92583f344 -r 987648c1ff69 hgkw/keyword.py --- a/hgkw/keyword.py Mon Mar 31 10:50:10 2008 +0200 +++ b/hgkw/keyword.py Wed Apr 09 13:40:16 2008 +0200 @@ -106,23 +106,17 @@ '''Returns hgdate in cvs-like UTC format.''' return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0])) +def textsafe(s): + '''Safe version of util.binary with reversed logic. + Note: argument may not be None, which is allowed for util.binary.''' + return '\0' not in s # make keyword tools accessible kwtools = {'templater': None, 'hgcmd': None} -# monkeypatches and backwards compatibility hacks - -try: - # cmdutil.parse moves to dispatch._parse in 18a9fbb5cd78 - from mercurial import dispatch - _dispatch_parse = dispatch._parse -except ImportError: - try: - # commands.parse moves to cmdutil.parse in 0c61124ad877 - _dispatch_parse = cmdutil.parse - except AttributeError: - _dispatch_parse = commands.parse - +# monkeypatch argument parsing +# due to backwards compatibility this can't be done in uisetup +# uisetup introduced with extensions module in 930ed513c864 def _kwdispatch_parse(ui, args): '''Monkeypatch dispatch._parse to obtain running hg command.''' cmd, func, args, options, cmdoptions = _dispatch_parse(ui, args) @@ -130,74 +124,20 @@ return cmd, func, args, options, cmdoptions try: - setattr(dispatch, '_parse', _kwdispatch_parse) -except (NameError, ImportError): - # 0.9.4 needs ImportError - if hasattr(cmdutil, 'parse'): + # cmdutil.parse moves to dispatch._parse in 18a9fbb5cd78 + from mercurial import dispatch + _dispatch_parse = dispatch._parse + dispatch._parse = _kwdispatch_parse +except ImportError: + try: + # commands.parse moves to cmdutil.parse in 0c61124ad877 + _dispatch_parse = cmdutil.parse cmdutil.parse = _kwdispatch_parse - else: + except AttributeError: + _dispatch_parse = commands.parse commands.parse = _kwdispatch_parse try: - # avoid spurious rejects if patchfile is available - _patchfile_init = patch.patchfile.__init__ - - def _kwpatchfile_init(self, ui, fname, missing=False): - '''Monkeypatch/wrap patch.patchfile.__init__ to avoid - rejects or conflicts due to expanded keywords in working dir.''' - try: - _patchfile_init(self, ui, fname, missing=missing) - except TypeError: - # "missing" arg added in e90e72c6b4c7 - _patchfile_init(self, ui, fname) - self.lines = kwtools['templater'].shrinklines(self.fname, self.lines) -except AttributeError: - pass - -_patch_diff = patch.diff -def _kw_diff(repo, node1=None, node2=None, files=None, match=util.always, - fp=None, changes=None, opts=None): - # only expand if comparing against working dir - if node2 is not None: - kwtools['templater'].matcher = util.never - elif node1 is not None and node1 != repo.changectx().node(): - kwtools['templater'].restrict = True - _patch_diff(repo, node1=node1, node2=node2, files=files, match=match, - fp=fp, changes=changes, opts=opts) - -try: - from mercurial.hgweb import webcommands - _webcommands_changeset = webcommands.changeset - _webcommands_filediff = webcommands.filediff - - def _kwweb_changeset(web, req, tmpl): - '''Wraps webcommands.changeset turning off keyword expansion.''' - kwtools['templater'].matcher = util.never - return _webcommands_changeset(web, req, tmpl) - - def _kwweb_filediff(web, req, tmpl): - '''Wraps webcommands.filediff turning off keyword expansion.''' - kwtools['templater'].matcher = util.never - return _webcommands_filediff(web, req, tmpl) - - webcommands.changeset = webcommands.rev = _kwweb_changeset - webcommands.filediff = webcommands.diff = _kwweb_filediff - -except ImportError: - from mercurial.hgweb.hgweb_mod import hgweb - - def _kwweb_do_changeset(self, req): - kwtools['templater'].matcher = util.never - req.write(self.changeset(self.changectx(req))) - - def _kwweb_do_filediff(self, req): - kwtools['templater'].matcher = util.never - req.write(self.filediff(self.filectx(req))) - - hgweb.do_changeset = hgweb.do_rev = _kwweb_do_changeset - hgweb.do_filediff = hgweb.do_diff = _kwweb_do_filediff - -try: # templatefilters module introduced in 9f1e6ab76069 from mercurial import templatefilters template_filters = templatefilters.filters @@ -313,7 +253,7 @@ kwmaps = self.ui.configitems('keywordmaps') if kwmaps: # override default templates - kwmaps = [(k, templater.parsestring(v, quoted=False)) + kwmaps = [(k, templater.parsestring(v, False)) for (k, v) in kwmaps] self.templates = dict(kwmaps) escaped = map(re.escape, self.templates.keys()) @@ -351,7 +291,7 @@ def expand(self, path, node, data): '''Returns data with keywords expanded.''' - if not self.restrict and self.matcher(path) and not util.binary(data): + if not self.restrict and self.matcher(path) and textsafe(data): changenode = self.getnode(path, node) return self.substitute(data, path, changenode, self.re_kw.sub) return data @@ -362,7 +302,7 @@ Caveat: localrepository._link fails on Windows.''' return self.matcher(path) and not islink(path) - def overwrite(self, node=None, expand=True, files=None): + def overwrite(self, node, expand, files): '''Overwrites selected files expanding/shrinking keywords.''' ctx = self.repo.changectx(node) mf = ctx.manifest() @@ -380,7 +320,7 @@ for f in candidates: fp = self.repo.file(f) data = fp.read(mf[f]) - if util.binary(data): + if not textsafe(data): continue if expand: changenode = node or self.getnode(f, mf[f]) @@ -401,7 +341,7 @@ def shrink(self, fname, text): '''Returns text with all keyword substitutions removed.''' - if self.matcher(fname) and not util.binary(text): + if self.matcher(fname) and textsafe(text): return self.shrinktext(text) return text @@ -409,7 +349,7 @@ '''Returns lines with keyword substitutions removed.''' if self.matcher(fname): text = ''.join(lines) - if not util.binary(text): + if textsafe(text): return self.shrinktext(text).splitlines(True) return lines @@ -423,9 +363,9 @@ Subclass of filelog to hook into its read, add, cmp methods. Keywords are "stored" unexpanded, and processed on reading. ''' - def __init__(self, opener, path): + def __init__(self, opener, kwt, path): super(kwfilelog, self).__init__(opener, path) - self.kwt = kwtools['templater'] + self.kwt = kwt self.path = path def read(self, node): @@ -436,7 +376,7 @@ def add(self, text, meta, tr, link, p1=None, p2=None): '''Removes keyword substitutions when adding to filelog.''' text = self.kwt.shrink(self.path, text) - return super(kwfilelog, self).add(text, meta, tr, link, p1=p1, p2=p2) + return super(kwfilelog, self).add(text, meta, tr, link, p1, p2) def cmp(self, node, text): '''Removes keyword substitutions for comparison.''' @@ -467,7 +407,7 @@ try: wlock = repo.wlock() lock = repo.lock() - kwt.overwrite(expand=expand, files=clean) + kwt.overwrite(None, expand, clean) finally: del wlock, lock @@ -497,7 +437,7 @@ branchname = 'demobranch' tmpdir = tempfile.mkdtemp('', 'kwdemo.') ui.note(_('creating temporary repo at %s\n') % tmpdir) - repo = localrepo.localrepository(ui, path=tmpdir, create=True) + repo = localrepo.localrepository(ui, tmpdir, True) ui.setconfig('keyword', fn, '') if args or opts.get('rcfile'): kwstatus = 'custom' @@ -636,7 +576,7 @@ def file(self, f): if f[0] == '/': f = f[1:] - return kwfilelog(self.sopener, f) + return kwfilelog(self.sopener, kwt, f) def wread(self, filename): data = super(kwrepo, self).wread(filename) @@ -646,27 +586,25 @@ force_editor, p1, p2, extra, empty_ok): '''Private commit wrapper for backwards compatibility.''' try: - return super(kwrepo, self).commit(files=files, text=text, - user=user, date=date, - match=match, force=force, + return super(kwrepo, self).commit(files, text, user, date, + match, force, lock=lock, wlock=wlock, force_editor=force_editor, p1=p1, p2=p2, extra=extra) except TypeError: try: - return super(kwrepo, self).commit(files=files, text=text, - user=user, date=date, - match=match, force=force, - force_editor=force_editor, - p1=p1, p2=p2, - extra=extra, - empty_ok=empty_ok) + return super(kwrepo, + self).commit(files, text, user, date, + match, force, + force_editor=force_editor, + p1=p1, p2=p2, extra=extra, + empty_ok=empty_ok) except TypeError: - return super(kwrepo, self).commit(files=files, text=text, - user=user, date=date, - match=match, force=force, - force_editor=force_editor, - p1=p1, p2=p2, extra=extra) + return super(kwrepo, + self).commit(files, text, user, date, + match, force, + force_editor=force_editor, + p1=p1, p2=p2, extra=extra) def commit(self, files=None, text='', user=None, date=None, match=util.always, force=False, lock=None, wlock=None, @@ -702,24 +640,82 @@ else: _p2 = hex(_p2) - node = self._commit(files, text, user, date, match, force, - _lock, _wlock, force_editor, p1, p2, extra, - empty_ok) + n = self._commit(files, text, user, date, match, force, _lock, + _wlock, force_editor, p1, p2, extra, empty_ok) # restore commit hooks for name, cmd in commithooks.iteritems(): ui.setconfig('hooks', name, cmd) - if node is not None: - kwt.overwrite(node=node) - repo.hook('commit', node=node, parent1=_p1, parent2=_p2) - return node + if n is not None: + kwt.overwrite(n, True, None) + repo.hook('commit', node=n, parent1=_p1, parent2=_p2) + return n finally: del _wlock, _lock repo.__class__ = kwrepo - patch.diff = _kw_diff - if hasattr(patch, 'patchfile'): - patch.patchfile.__init__ = _kwpatchfile_init + + # monkeypatches + try: + # avoid spurious rejects if patchfile is available + def kwpatchfile_init(self, ui, fname, missing=False): + '''Monkeypatch/wrap patch.patchfile.__init__ to avoid + rejects or conflicts due to expanded keywords in working dir.''' + try: + patchfile_init(self, ui, fname, missing) + except TypeError: + # "missing" arg added in e90e72c6b4c7 + patchfile_init(self, ui, fname) + self.lines = kwt.shrinklines(self.fname, self.lines) + + patchfile_init = patch.patchfile.__init__ + patch.patchfile.__init__ = kwpatchfile_init + except AttributeError: + pass + + def kw_diff(repo, node1=None, node2=None, files=None, match=util.always, + fp=None, changes=None, opts=None): + # only expand if comparing against working dir + if node2 is not None: + kwt.matcher = util.never + elif node1 is not None and node1 != repo.changectx().node(): + kwt.restrict = True + patch_diff(repo, node1, node2, files, match, fp, changes, opts) + + patch_diff = patch.diff + patch.diff = kw_diff + + try: + from mercurial.hgweb import webcommands + def kwweb_changeset(web, req, tmpl): + '''Wraps webcommands.changeset turning off keyword expansion.''' + kwt.matcher = util.never + return webcommands_changeset(web, req, tmpl) + + def kwweb_filediff(web, req, tmpl): + '''Wraps webcommands.filediff turning off keyword expansion.''' + kwt.matcher = util.never + return webcommands_filediff(web, req, tmpl) + + webcommands_changeset = webcommands.changeset + webcommands_filediff = webcommands.filediff + webcommands.changeset = webcommands.rev = kwweb_changeset + webcommands.filediff = webcommands.diff = kwweb_filediff + + except ImportError: + from mercurial.hgweb.hgweb_mod import hgweb + def kwweb_do_changeset(self, req): + kwt.matcher = util.never + hgweb_do_changeset(self, req) + + def kwweb_do_filediff(self, req): + kwt.matcher = util.never + hgweb_do_filediff(self, req) + + hgweb_do_changeset = hgweb.do_changeset + hgweb_do_filediff = hgweb.do_filediff + hgweb.do_changeset = hgweb.do_rev = kwweb_do_changeset + hgweb.do_filediff = hgweb.do_diff = kwweb_do_filediff cmdtable = {