hgkw/keyword.py
changeset 416 b69dca43ef08
parent 415 d1026365eff6
child 419 2f179ea3a9aa
equal deleted inserted replaced
415:d1026365eff6 416:b69dca43ef08
   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 kwx = { 'templater': None, 'hgcmd': None }
   107 kwtools = {'templater': None, 'hgcmd': None}
   108 
   108 
   109 # store originals of monkeypatches
   109 # store originals of monkeypatches
   110 _patchfile_init = patch.patchfile.__init__
   110 _patchfile_init = patch.patchfile.__init__
   111 _patch_diff = patch.diff
   111 _patch_diff = patch.diff
   112 _dispatch_parse = dispatch._parse
   112 _dispatch_parse = dispatch._parse
   114 def _kwpatchfile_init(self, ui, fname, missing=False):
   114 def _kwpatchfile_init(self, ui, fname, missing=False):
   115     '''Monkeypatch/wrap patch.patchfile.__init__ to avoid
   115     '''Monkeypatch/wrap patch.patchfile.__init__ to avoid
   116     rejects or conflicts due to expanded keywords in working dir.'''
   116     rejects or conflicts due to expanded keywords in working dir.'''
   117     _patchfile_init(self, ui, fname, missing=missing)
   117     _patchfile_init(self, ui, fname, missing=missing)
   118     # shrink keywords read from working dir
   118     # shrink keywords read from working dir
   119     kwt = kwx['templater']
   119     kwt = kwtools['templater']
   120     self.lines = kwt.shrinklines(self.fname, self.lines)
   120     self.lines = kwt.shrinklines(self.fname, self.lines)
   121 
   121 
   122 def _kw_diff(repo, node1=None, node2=None, files=None, match=util.always,
   122 def _kw_diff(repo, node1=None, node2=None, files=None, match=util.always,
   123              fp=None, changes=None, opts=None):
   123              fp=None, changes=None, opts=None):
   124     '''Monkeypatch patch.diff to avoid expansion except when
   124     '''Monkeypatch patch.diff to avoid expansion except when
   125     comparing against working dir.'''
   125     comparing against working dir.'''
   126     if node2 is not None:
   126     if node2 is not None:
   127         kwx['templater'].matcher = util.never
   127         kwtools['templater'].matcher = util.never
   128     elif node1 is not None and node1 != repo.changectx().node():
   128     elif node1 is not None and node1 != repo.changectx().node():
   129         kwx['templater'].restrict = True
   129         kwtools['templater'].restrict = True
   130     _patch_diff(repo, node1=node1, node2=node2, files=files, match=match,
   130     _patch_diff(repo, node1=node1, node2=node2, files=files, match=match,
   131                 fp=fp, changes=changes, opts=opts)
   131                 fp=fp, changes=changes, opts=opts)
   132 
   132 
   133 def _kwweb_changeset(web, req, tmpl):
   133 def _kwweb_changeset(web, req, tmpl):
   134     '''Wraps webcommands.changeset turning off keyword expansion.'''
   134     '''Wraps webcommands.changeset turning off keyword expansion.'''
   135     kwx['templater'].matcher = util.never
   135     kwtools['templater'].matcher = util.never
   136     return web.changeset(tmpl, web.changectx(req))
   136     return web.changeset(tmpl, web.changectx(req))
   137 
   137 
   138 def _kwweb_filediff(web, req, tmpl):
   138 def _kwweb_filediff(web, req, tmpl):
   139     '''Wraps webcommands.filediff turning off keyword expansion.'''
   139     '''Wraps webcommands.filediff turning off keyword expansion.'''
   140     kwx['templater'].matcher = util.never
   140     kwtools['templater'].matcher = util.never
   141     return web.filediff(tmpl, web.filectx(req))
   141     return web.filediff(tmpl, web.filectx(req))
   142 
   142 
   143 def _kwdispatch_parse(ui, args):
   143 def _kwdispatch_parse(ui, args):
   144     '''Monkeypatch dispatch._parse to obtain running hg command.'''
   144     '''Monkeypatch dispatch._parse to obtain running hg command.'''
   145     cmd, func, args, options, cmdoptions = _dispatch_parse(ui, args)
   145     cmd, func, args, options, cmdoptions = _dispatch_parse(ui, args)
   146     kwx['hgcmd'] = cmd
   146     kwtools['hgcmd'] = cmd
   147     return cmd, func, args, options, cmdoptions
   147     return cmd, func, args, options, cmdoptions
   148 
   148 
   149 # dispatch._parse is run before reposetup, so wrap it here
   149 # dispatch._parse is run before reposetup, so wrap it here
   150 dispatch._parse = _kwdispatch_parse
   150 dispatch._parse = _kwdispatch_parse
   151 
   151 
   167 
   167 
   168     def __init__(self, ui, repo, inc, exc):
   168     def __init__(self, ui, repo, inc, exc):
   169         self.ui = ui
   169         self.ui = ui
   170         self.repo = repo
   170         self.repo = repo
   171         self.matcher = util.matcher(repo.root, inc=inc, exc=exc)[1]
   171         self.matcher = util.matcher(repo.root, inc=inc, exc=exc)[1]
   172         self.restrict = kwx['hgcmd'] in restricted.split()
   172         self.restrict = kwtools['hgcmd'] in restricted.split()
   173 
   173 
   174         kwmaps = self.ui.configitems('keywordmaps')
   174         kwmaps = self.ui.configitems('keywordmaps')
   175         if kwmaps: # override default templates
   175         if kwmaps: # override default templates
   176             kwmaps = [(k, templater.parsestring(v, quoted=False))
   176             kwmaps = [(k, templater.parsestring(v, quoted=False))
   177                       for (k, v) in kwmaps]
   177                       for (k, v) in kwmaps]
   273     Subclass of filelog to hook into its read, add, cmp methods.
   273     Subclass of filelog to hook into its read, add, cmp methods.
   274     Keywords are "stored" unexpanded, and processed on reading.
   274     Keywords are "stored" unexpanded, and processed on reading.
   275     '''
   275     '''
   276     def __init__(self, opener, path):
   276     def __init__(self, opener, path):
   277         super(kwfilelog, self).__init__(opener, path)
   277         super(kwfilelog, self).__init__(opener, path)
   278         self.kwt = kwx['templater']
   278         self.kwt = kwtools['templater']
   279         self.path = path
   279         self.path = path
   280 
   280 
   281     def read(self, node):
   281     def read(self, node):
   282         '''Expands keywords when reading filelog.'''
   282         '''Expands keywords when reading filelog.'''
   283         data = super(kwfilelog, self).read(node)
   283         data = super(kwfilelog, self).read(node)
   306         raise util.Abort(_('[keyword] patterns cannot match'))
   306         raise util.Abort(_('[keyword] patterns cannot match'))
   307     raise util.Abort(_('no [keyword] patterns configured'))
   307     raise util.Abort(_('no [keyword] patterns configured'))
   308 
   308 
   309 def _kwfwrite(ui, repo, expand, *pats, **opts):
   309 def _kwfwrite(ui, repo, expand, *pats, **opts):
   310     '''Selects files and passes them to kwtemplater.overwrite.'''
   310     '''Selects files and passes them to kwtemplater.overwrite.'''
   311     kwt = kwx['templater']
   311     kwt = kwtools['templater']
   312     status = _status(ui, repo, kwt, *pats, **opts)
   312     status = _status(ui, repo, kwt, *pats, **opts)
   313     modified, added, removed, deleted, unknown, ignored, clean = status
   313     modified, added, removed, deleted, unknown, ignored, clean = status
   314     if modified or added or removed or deleted:
   314     if modified or added or removed or deleted:
   315         raise util.Abort(_('outstanding uncommitted changes in given files'))
   315         raise util.Abort(_('outstanding uncommitted changes in given files'))
   316     wlock = lock = None
   316     wlock = lock = None
   417 
   417 
   418     Crosscheck which files in working directory are potential targets for
   418     Crosscheck which files in working directory are potential targets for
   419     keyword expansion.
   419     keyword expansion.
   420     That is, files matched by [keyword] config patterns but not symlinks.
   420     That is, files matched by [keyword] config patterns but not symlinks.
   421     '''
   421     '''
   422     kwt = kwx['templater']
   422     kwt = kwtools['templater']
   423     status = _status(ui, repo, kwt, *pats, **opts)
   423     status = _status(ui, repo, kwt, *pats, **opts)
   424     modified, added, removed, deleted, unknown, ignored, clean = status
   424     modified, added, removed, deleted, unknown, ignored, clean = status
   425     files = modified + added + clean
   425     files = modified + added + clean
   426     if opts.get('untracked'):
   426     if opts.get('untracked'):
   427         files += unknown
   427         files += unknown
   458     keyword substitutions.
   458     keyword substitutions.
   459     This is done for local repos only, and only if there are
   459     This is done for local repos only, and only if there are
   460     files configured at all for keyword substitution.'''
   460     files configured at all for keyword substitution.'''
   461 
   461 
   462     try:
   462     try:
   463         if (not repo.local() or kwx['hgcmd'] in nokwcommands.split()
   463         if (not repo.local() or kwtools['hgcmd'] in nokwcommands.split()
   464             or '.hg' in util.splitpath(repo.root)
   464             or '.hg' in util.splitpath(repo.root)
   465             or repo._url.startswith('bundle:')):
   465             or repo._url.startswith('bundle:')):
   466             return
   466             return
   467     except AttributeError:
   467     except AttributeError:
   468         pass
   468         pass
   474         else:
   474         else:
   475             exc.append(pat)
   475             exc.append(pat)
   476     if not inc:
   476     if not inc:
   477         return
   477         return
   478 
   478 
   479     kwx['templater'] = kwt = kwtemplater(ui, repo, inc, exc)
   479     kwtools['templater'] = kwt = kwtemplater(ui, repo, inc, exc)
   480 
   480 
   481     class kwrepo(repo.__class__):
   481     class kwrepo(repo.__class__):
   482         def file(self, f):
   482         def file(self, f):
   483             if f[0] == '/':
   483             if f[0] == '/':
   484                 f = f[1:]
   484                 f = f[1:]