hgkw/keyword.py
changeset 314 d9f84b36de26
parent 310 574128f982a2
child 315 c1ec4ffd1279
equal deleted inserted replaced
313:40b7f2866500 314:d9f84b36de26
   172 class kwfilelog(filelog.filelog):
   172 class kwfilelog(filelog.filelog):
   173     '''
   173     '''
   174     Subclass of filelog to hook into its read, add, cmp methods.
   174     Subclass of filelog to hook into its read, add, cmp methods.
   175     Keywords are "stored" unexpanded, and processed on reading.
   175     Keywords are "stored" unexpanded, and processed on reading.
   176     '''
   176     '''
   177     def __init__(self, opener, path, kwtemplater):
   177     def __init__(self, opener, path):
   178         super(kwfilelog, self).__init__(opener, path)
   178         super(kwfilelog, self).__init__(opener, path)
   179         self.kwtemplater = kwtemplater
   179         _kwtemplater.path = path
   180         self.kwtemplater.path = path
       
   181 
   180 
   182     def kwctread(self, node, expand):
   181     def kwctread(self, node, expand):
   183         '''Reads expanding and counting keywords
   182         '''Reads expanding and counting keywords
   184         (only called from kwtemplater.overwrite).'''
   183         (only called from kwtemplater.overwrite).'''
   185         data = super(kwfilelog, self).read(node)
   184         data = super(kwfilelog, self).read(node)
   186         return self.kwtemplater.process(node, data, expand)
   185         return _kwtemplater.process(node, data, expand)
   187 
   186 
   188     def read(self, node):
   187     def read(self, node):
   189         '''Expands keywords when reading filelog.'''
   188         '''Expands keywords when reading filelog.'''
   190         data = super(kwfilelog, self).read(node)
   189         data = super(kwfilelog, self).read(node)
   191         return self.kwtemplater.expand(node, data)
   190         return _kwtemplater.expand(node, data)
   192 
   191 
   193     def add(self, text, meta, tr, link, p1=None, p2=None):
   192     def add(self, text, meta, tr, link, p1=None, p2=None):
   194         '''Removes keyword substitutions when adding to filelog.'''
   193         '''Removes keyword substitutions when adding to filelog.'''
   195         text = self.kwtemplater.shrink(text)
   194         text = _kwtemplater.shrink(text)
   196         return super(kwfilelog, self).add(text, meta, tr, link, p1=p1, p2=p2)
   195         return super(kwfilelog, self).add(text, meta, tr, link, p1=p1, p2=p2)
   197 
   196 
   198     def cmp(self, node, text):
   197     def cmp(self, node, text):
   199         '''Removes keyword substitutions for comparison.'''
   198         '''Removes keyword substitutions for comparison.'''
   200         text = self.kwtemplater.shrink(text)
   199         text = _kwtemplater.shrink(text)
   201         if self.renamed(node):
   200         if self.renamed(node):
   202             t2 = super(kwfilelog, self).read(node)
   201             t2 = super(kwfilelog, self).read(node)
   203             return t2 != text
   202             return t2 != text
   204         return revlog.revlog.cmp(self, node, text)
   203         return revlog.revlog.cmp(self, node, text)
   205 
   204 
   206 def _iskwfile(f, kwtemplater, link):
   205 def _iskwfile(f, link):
   207     return not link(f) and kwtemplater.matcher(f)
   206     return not link(f) and _kwtemplater.matcher(f)
   208 
   207 
   209 def _status(ui, repo, kwtemplater, *pats, **opts):
   208 def _status(ui, repo, *pats, **opts):
   210     '''Bails out if [keyword] configuration is not active.
   209     '''Bails out if [keyword] configuration is not active.
   211     Returns status of working directory.'''
   210     Returns status of working directory.'''
   212     if kwtemplater:
   211     if _kwtemplater:
   213         files, match, anypats = cmdutil.matchpats(repo, pats, opts)
   212         files, match, anypats = cmdutil.matchpats(repo, pats, opts)
   214         return repo.status(files=files, match=match, list_clean=True)
   213         return repo.status(files=files, match=match, list_clean=True)
   215     if ui.configitems('keyword'):
   214     if ui.configitems('keyword'):
   216         raise util.Abort(_('[keyword] patterns cannot match'))
   215         raise util.Abort(_('[keyword] patterns cannot match'))
   217     raise util.Abort(_('no [keyword] patterns configured'))
   216     raise util.Abort(_('no [keyword] patterns configured'))
   218 
   217 
   219 def _overwrite(ui, repo, kwtemplater, node=None, expand=True, files=None):
   218 def _overwrite(ui, repo, node=None, expand=True, files=None):
   220     '''Overwrites selected files expanding/shrinking keywords.'''
   219     '''Overwrites selected files expanding/shrinking keywords.'''
   221     ctx = repo.changectx(node)
   220     ctx = repo.changectx(node)
   222     mf = ctx.manifest()
   221     mf = ctx.manifest()
   223     if files is None:
   222     if files is None:
   224         notify = ui.debug # commit
   223         notify = ui.debug # commit
   225         files = [f for f in ctx.files() if mf.has_key(f)]
   224         files = [f for f in ctx.files() if mf.has_key(f)]
   226     else:
   225     else:
   227         notify = ui.note  # kwexpand/kwshrink
   226         notify = ui.note  # kwexpand/kwshrink
   228     candidates = [f for f in files if _iskwfile(f, kwtemplater, mf.linkf)]
   227     candidates = [f for f in files if _iskwfile(f, mf.linkf)]
   229     if candidates:
   228     if candidates:
   230         candidates.sort()
   229         candidates.sort()
   231         action = expand and 'expanding' or 'shrinking'
   230         action = expand and 'expanding' or 'shrinking'
   232         kwtemplater.node = node or ctx.node()
   231         _kwtemplater.node = node or ctx.node()
   233         for f in candidates:
   232         for f in candidates:
   234             fp = repo.file(f, kwmatch=True)
   233             fp = repo.file(f, kwmatch=True)
   235             data, kwfound = fp.kwctread(mf[f], expand)
   234             data, kwfound = fp.kwctread(mf[f], expand)
   236             if kwfound:
   235             if kwfound:
   237                 notify(_('overwriting %s %s keywords\n') % (f, action))
   236                 notify(_('overwriting %s %s keywords\n') % (f, action))
   238                 repo.wwrite(f, data, mf.flags(f))
   237                 repo.wwrite(f, data, mf.flags(f))
   239                 repo.dirstate.normal(f)
   238                 repo.dirstate.normal(f)
   240 
   239 
   241 def _kwfwrite(ui, repo, expand, *pats, **opts):
   240 def _kwfwrite(ui, repo, expand, *pats, **opts):
   242     '''Selects files and passes them to _overwrite.'''
   241     '''Selects files and passes them to _overwrite.'''
   243     global _kwtemplater
   242     status = _status(ui, repo, *pats, **opts)
   244     status = _status(ui, repo, _kwtemplater, *pats, **opts)
       
   245     modified, added, removed, deleted, unknown, ignored, clean = status
   243     modified, added, removed, deleted, unknown, ignored, clean = status
   246     if modified or added or removed or deleted:
   244     if modified or added or removed or deleted:
   247         raise util.Abort(_('outstanding uncommitted changes in given files'))
   245         raise util.Abort(_('outstanding uncommitted changes in given files'))
   248     wlock = lock = None
   246     wlock = lock = None
   249     try:
   247     try:
   250         wlock = repo.wlock()
   248         wlock = repo.wlock()
   251         lock = repo.lock()
   249         lock = repo.lock()
   252         _overwrite(ui, repo, _kwtemplater, expand=expand, files=clean)
   250         _overwrite(ui, repo, expand=expand, files=clean)
   253     finally:
   251     finally:
   254         del wlock, lock
   252         del wlock, lock
   255 
   253 
   256 
   254 
   257 def demo(ui, repo, *args, **opts):
   255 def demo(ui, repo, *args, **opts):
   350 
   348 
   351     Crosscheck which files in working directory are potential targets for
   349     Crosscheck which files in working directory are potential targets for
   352     keyword expansion.
   350     keyword expansion.
   353     That is, files matched by [keyword] config patterns but not symlinks.
   351     That is, files matched by [keyword] config patterns but not symlinks.
   354     '''
   352     '''
   355     global _kwtemplater
   353     status = _status(ui, repo, *pats, **opts)
   356     status = _status(ui, repo, _kwtemplater, *pats, **opts)
       
   357     modified, added, removed, deleted, unknown, ignored, clean = status
   354     modified, added, removed, deleted, unknown, ignored, clean = status
   358     if opts['untracked']:
   355     if opts['untracked']:
   359         files = modified + added + unknown + clean
   356         files = modified + added + unknown + clean
   360     else:
   357     else:
   361         files = modified + added + clean
   358         files = modified + added + clean
   362     files.sort()
   359     files.sort()
   363     kwfiles = [f for f in files if _iskwfile(f, _kwtemplater, repo._link)]
   360     kwfiles = [f for f in files if _iskwfile(f, repo._link)]
   364     cwd = pats and repo.getcwd() or ''
   361     cwd = pats and repo.getcwd() or ''
   365     allf = opts['all']
   362     allf = opts['all']
   366     ignore = opts['ignore']
   363     ignore = opts['ignore']
   367     if ignore:
   364     if ignore:
   368         kwfstats = ()
   365         kwfstats = ()
   425     class kwrepo(repo.__class__):
   422     class kwrepo(repo.__class__):
   426         def file(self, f, kwmatch=False):
   423         def file(self, f, kwmatch=False):
   427             if f[0] == '/':
   424             if f[0] == '/':
   428                 f = f[1:]
   425                 f = f[1:]
   429             if kwmatch or _kwtemplater.matcher(f):
   426             if kwmatch or _kwtemplater.matcher(f):
   430                 return kwfilelog(self.sopener, f, _kwtemplater)
   427                 return kwfilelog(self.sopener, f)
   431             return filelog.filelog(self.sopener, f)
   428             return filelog.filelog(self.sopener, f)
   432 
   429 
   433         def commit(self, files=None, text='', user=None, date=None,
   430         def commit(self, files=None, text='', user=None, date=None,
   434                    match=util.always, force=False, force_editor=False,
   431                    match=util.always, force=False, force_editor=False,
   435                    p1=None, p2=None, extra={}):
   432                    p1=None, p2=None, extra={}):
   464 
   461 
   465                 # restore commit hooks
   462                 # restore commit hooks
   466                 for name, cmd in commithooks:
   463                 for name, cmd in commithooks:
   467                     ui.setconfig('hooks', name, cmd)
   464                     ui.setconfig('hooks', name, cmd)
   468                 if node is not None:
   465                 if node is not None:
   469                     _overwrite(ui, self, _kwtemplater, node=node)
   466                     _overwrite(ui, self, node=node)
   470                     repo.hook('commit', node=node, parent1=_p1, parent2=_p2)
   467                     repo.hook('commit', node=node, parent1=_p1, parent2=_p2)
   471                 return node
   468                 return node
   472             finally:
   469             finally:
   473                 del wlock, lock
   470                 del wlock, lock
   474 
   471