hgkw/keyword.py
branch0.9.2compat
changeset 417 e089672ef9b4
parent 414 13043607c6ae
child 420 25f2d4cedd4c
equal deleted inserted replaced
414:13043607c6ae 417:e089672ef9b4
   106     '''Returns hgdate in cvs-like UTC format.'''
   106     '''Returns hgdate in cvs-like UTC format.'''
   107     return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0]))
   107     return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0]))
   108 
   108 
   109 
   109 
   110 # make keyword tools accessible
   110 # make keyword tools accessible
   111 kwx = { 'templater': None, 'hgcmd': None }
   111 kwtools = {'templater': None, 'hgcmd': None}
   112 
   112 
   113 # monkeypatches and backwards compatibility hacks
   113 # monkeypatches and backwards compatibility hacks
   114 
   114 
   115 try:
   115 try:
   116     # cmdutil.parse moves to dispatch._parse in 18a9fbb5cd78
   116     # cmdutil.parse moves to dispatch._parse in 18a9fbb5cd78
   124         _dispatch_parse = commands.parse
   124         _dispatch_parse = commands.parse
   125 
   125 
   126 def _kwdispatch_parse(ui, args):
   126 def _kwdispatch_parse(ui, args):
   127     '''Monkeypatch dispatch._parse to obtain running hg command.'''
   127     '''Monkeypatch dispatch._parse to obtain running hg command.'''
   128     cmd, func, args, options, cmdoptions = _dispatch_parse(ui, args)
   128     cmd, func, args, options, cmdoptions = _dispatch_parse(ui, args)
   129     kwx['hgcmd'] = cmd
   129     kwtools['hgcmd'] = cmd
   130     return cmd, func, args, options, cmdoptions
   130     return cmd, func, args, options, cmdoptions
   131 
   131 
   132 try:
   132 try:
   133     setattr(dispatch, '_parse', _kwdispatch_parse)
   133     setattr(dispatch, '_parse', _kwdispatch_parse)
   134 except (NameError, ImportError):
   134 except (NameError, ImportError):
   148         try:
   148         try:
   149             _patchfile_init(self, ui, fname, missing=missing)
   149             _patchfile_init(self, ui, fname, missing=missing)
   150         except TypeError:
   150         except TypeError:
   151             # "missing" arg added in e90e72c6b4c7
   151             # "missing" arg added in e90e72c6b4c7
   152             _patchfile_init(self, ui, fname)
   152             _patchfile_init(self, ui, fname)
   153         self.lines = kwx['templater'].shrinklines(self.fname, self.lines)
   153         self.lines = kwtools['templater'].shrinklines(self.fname, self.lines)
   154 except AttributeError:
   154 except AttributeError:
   155     pass
   155     pass
   156 
   156 
   157 _patch_diff = patch.diff
   157 _patch_diff = patch.diff
   158 def _kw_diff(repo, node1=None, node2=None, files=None, match=util.always,
   158 def _kw_diff(repo, node1=None, node2=None, files=None, match=util.always,
   159              fp=None, changes=None, opts=None):
   159              fp=None, changes=None, opts=None):
   160     # only expand if comparing against working dir
   160     # only expand if comparing against working dir
   161     if node2 is not None:
   161     if node2 is not None:
   162         kwx['templater'].matcher = util.never
   162         kwtools['templater'].matcher = util.never
   163     elif node1 is not None and node1 != repo.changectx().node():
   163     elif node1 is not None and node1 != repo.changectx().node():
   164         kwx['templater'].restrict = True
   164         kwtools['templater'].restrict = True
   165     _patch_diff(repo, node1=node1, node2=node2, files=files, match=match,
   165     _patch_diff(repo, node1=node1, node2=node2, files=files, match=match,
   166                 fp=fp, changes=changes, opts=opts)
   166                 fp=fp, changes=changes, opts=opts)
   167 
   167 
   168 try:
   168 try:
   169     from mercurial.hgweb import webcommands
   169     from mercurial.hgweb import webcommands
   170 
   170 
   171     def _kwweb_changeset(web, req, tmpl):
   171     def _kwweb_changeset(web, req, tmpl):
   172         '''Wraps webcommands.changeset turning off keyword expansion.'''
   172         '''Wraps webcommands.changeset turning off keyword expansion.'''
   173         if kwx['templater']:
   173         if kwtools['templater']:
   174             kwx['templater'].matcher = util.never
   174             kwtools['templater'].matcher = util.never
   175         return web.changeset(tmpl, web.changectx(req))
   175         return web.changeset(tmpl, web.changectx(req))
   176 
   176 
   177     def _kwweb_filediff(web, req, tmpl):
   177     def _kwweb_filediff(web, req, tmpl):
   178         '''Wraps webcommands.filediff turning off keyword expansion.'''
   178         '''Wraps webcommands.filediff turning off keyword expansion.'''
   179         if kwx['templater']:
   179         if kwtools['templater']:
   180             kwx['templater'].matcher = util.never
   180             kwtools['templater'].matcher = util.never
   181         return web.filediff(tmpl, web.filectx(req))
   181         return web.filediff(tmpl, web.filectx(req))
   182 
   182 
   183     webcommands.changeset = webcommands.rev = _kwweb_changeset
   183     webcommands.changeset = webcommands.rev = _kwweb_changeset
   184     webcommands.filediff = webcommands.diff = _kwweb_filediff
   184     webcommands.filediff = webcommands.diff = _kwweb_filediff
   185 
   185 
   186 except ImportError:
   186 except ImportError:
   187     from mercurial.hgweb.hgweb_mod import hgweb
   187     from mercurial.hgweb.hgweb_mod import hgweb
   188 
   188 
   189     def _kwweb_do_changeset(self, req):
   189     def _kwweb_do_changeset(self, req):
   190         if kwx['templater']:
   190         if kwtools['templater']:
   191             kwx['templater'].matcher = util.never
   191             kwtools['templater'].matcher = util.never
   192         req.write(self.changeset(self.changectx(req)))
   192         req.write(self.changeset(self.changectx(req)))
   193 
   193 
   194     def _kwweb_do_filediff(self, req):
   194     def _kwweb_do_filediff(self, req):
   195         if kwx['templater']:
   195         if kwtools['templater']:
   196             kwx['templater'].matcher = util.never
   196             kwtools['templater'].matcher = util.never
   197         req.write(self.filediff(self.filectx(req)))
   197         req.write(self.filediff(self.filectx(req)))
   198 
   198 
   199     hgweb.do_changeset = hgweb.do_rev = _kwweb_do_changeset
   199     hgweb.do_changeset = hgweb.do_rev = _kwweb_do_changeset
   200     hgweb.do_filediff = hgweb.do_diff = _kwweb_do_filediff
   200     hgweb.do_filediff = hgweb.do_diff = _kwweb_do_filediff
   201 
   201 
   309 
   309 
   310     def __init__(self, ui, repo, inc, exc):
   310     def __init__(self, ui, repo, inc, exc):
   311         self.ui = ui
   311         self.ui = ui
   312         self.repo = repo
   312         self.repo = repo
   313         self.matcher = util.matcher(repo.root, inc=inc, exc=exc)[1]
   313         self.matcher = util.matcher(repo.root, inc=inc, exc=exc)[1]
   314         self.restrict = kwx['hgcmd'] in restricted.split()
   314         self.restrict = kwtools['hgcmd'] in restricted.split()
   315 
   315 
   316         kwmaps = self.ui.configitems('keywordmaps')
   316         kwmaps = self.ui.configitems('keywordmaps')
   317         if kwmaps: # override default templates
   317         if kwmaps: # override default templates
   318             kwmaps = [(k, templater.parsestring(v, quoted=False))
   318             kwmaps = [(k, templater.parsestring(v, quoted=False))
   319                       for (k, v) in kwmaps]
   319                       for (k, v) in kwmaps]
   334         except TypeError:
   334         except TypeError:
   335             return cmdutil.changeset_templater(self.ui, self.repo,
   335             return cmdutil.changeset_templater(self.ui, self.repo,
   336                                                False, None, '', False)
   336                                                False, None, '', False)
   337 
   337 
   338     def getnode(self, path, fnode):
   338     def getnode(self, path, fnode):
   339         '''Derives changenode from file context.'''
   339         '''Derives changenode from file path and filenode.'''
       
   340         # used by kwfilelog.read and kwexpand
   340         c = context.filectx(self.repo, path, fileid=fnode)
   341         c = context.filectx(self.repo, path, fileid=fnode)
   341         return c.node()
   342         return c.node()
   342 
   343 
   343     def substitute(self, data, path, node, subfunc):
   344     def substitute(self, data, path, node, subfunc):
   344         '''Replaces keywords in data with expanded template.'''
   345         '''Replaces keywords in data with expanded template.'''
   424     Subclass of filelog to hook into its read, add, cmp methods.
   425     Subclass of filelog to hook into its read, add, cmp methods.
   425     Keywords are "stored" unexpanded, and processed on reading.
   426     Keywords are "stored" unexpanded, and processed on reading.
   426     '''
   427     '''
   427     def __init__(self, opener, path):
   428     def __init__(self, opener, path):
   428         super(kwfilelog, self).__init__(opener, path)
   429         super(kwfilelog, self).__init__(opener, path)
   429         self.kwt = kwx['templater']
   430         self.kwt = kwtools['templater']
   430         self.path = path
   431         self.path = path
   431 
   432 
   432     def read(self, node):
   433     def read(self, node):
   433         '''Expands keywords when reading filelog.'''
   434         '''Expands keywords when reading filelog.'''
   434         data = super(kwfilelog, self).read(node)
   435         data = super(kwfilelog, self).read(node)
   457         raise util.Abort(_('[keyword] patterns cannot match'))
   458         raise util.Abort(_('[keyword] patterns cannot match'))
   458     raise util.Abort(_('no [keyword] patterns configured'))
   459     raise util.Abort(_('no [keyword] patterns configured'))
   459 
   460 
   460 def _kwfwrite(ui, repo, expand, *pats, **opts):
   461 def _kwfwrite(ui, repo, expand, *pats, **opts):
   461     '''Selects files and passes them to kwtemplater.overwrite.'''
   462     '''Selects files and passes them to kwtemplater.overwrite.'''
   462     kwt = kwx['templater']
   463     kwt = kwtools['templater']
   463     status = _status(ui, repo, kwt, *pats, **opts)
   464     status = _status(ui, repo, kwt, *pats, **opts)
   464     modified, added, removed, deleted, unknown, ignored, clean = status
   465     modified, added, removed, deleted, unknown, ignored, clean = status
   465     if modified or added or removed or deleted:
   466     if modified or added or removed or deleted:
   466         raise util.Abort(_('outstanding uncommitted changes in given files'))
   467         raise util.Abort(_('outstanding uncommitted changes in given files'))
   467     wlock = lock = None
   468     wlock = lock = None
   568 
   569 
   569     Crosscheck which files in working directory are potential targets for
   570     Crosscheck which files in working directory are potential targets for
   570     keyword expansion.
   571     keyword expansion.
   571     That is, files matched by [keyword] config patterns but not symlinks.
   572     That is, files matched by [keyword] config patterns but not symlinks.
   572     '''
   573     '''
   573     kwt = kwx['templater']
   574     kwt = kwtools['templater']
   574     status = _status(ui, repo, kwt, *pats, **opts)
   575     status = _status(ui, repo, kwt, *pats, **opts)
   575     modified, added, removed, deleted, unknown, ignored, clean = status
   576     modified, added, removed, deleted, unknown, ignored, clean = status
   576     files = modified + added + clean
   577     files = modified + added + clean
   577     if opts.get('untracked'):
   578     if opts.get('untracked'):
   578         files += unknown
   579         files += unknown
   613     keyword substitutions.
   614     keyword substitutions.
   614     This is done for local repos only, and only if there are
   615     This is done for local repos only, and only if there are
   615     files configured at all for keyword substitution.'''
   616     files configured at all for keyword substitution.'''
   616 
   617 
   617     try:
   618     try:
   618         if (not repo.local() or kwx['hgcmd'] in nokwcommands.split()
   619         if (not repo.local() or kwtools['hgcmd'] in nokwcommands.split()
   619             or '.hg' in repo.root.split(os.sep)
   620             or '.hg' in repo.root.split(os.sep)
   620             or repo._url.startswith('bundle:')):
   621             or repo._url.startswith('bundle:')):
   621             return
   622             return
   622     except AttributeError:
   623     except AttributeError:
   623         pass
   624         pass
   629         else:
   630         else:
   630             exc.append(pat)
   631             exc.append(pat)
   631     if not inc:
   632     if not inc:
   632         return
   633         return
   633 
   634 
   634     kwx['templater'] = kwt = kwtemplater(ui, repo, inc, exc)
   635     kwtools['templater'] = kwt = kwtemplater(ui, repo, inc, exc)
   635 
   636 
   636     class kwrepo(repo.__class__):
   637     class kwrepo(repo.__class__):
   637         def file(self, f):
   638         def file(self, f):
   638             if f[0] == '/':
   639             if f[0] == '/':
   639                 f = f[1:]
   640                 f = f[1:]