Clean keyword arg assignment in kwfilelog.add; rename utc() to utcdate()
# keyword.py - keyword expansion for mercurial# $Id$'''keyword expansion hack against the grain of a DSCMThis extension lets you expand RCS/CVS-like keywords in a Mercurialrepository.There are many good reasons why this is not needed in a distributedSCM, still it may be useful in very small projects based on singlefiles (like LaTeX packages), that are mostly addressed to an audiencenot running a version control system.Supported $keywords$ and their $keyword: substition $ are: Revision: changeset id Author: short username Date: %Y/%m/%d %H:%M:%S [UTC] RCSFile: basename,v Source: /path/to/basename,v Id: basename,v csetid %Y/%m/%d %H:%M:%S shortname Header: /path/to/basename,v csetid %Y/%m/%d %H:%M:%S shortnameSimple setup in hgrc: # enable extension hgext.keyword = # or, if script not in hgext folder: # hgext.keyword = /full/path/to/script # filename patterns for expansion are configured in this section [keyword] **.py = expand ...'''frommercurialimportcontext,utilimportos.path,re,sys,timere_kw=re.compile(r'\$(Id|Header|Author|Date|Revision|RCSFile|Source)[^$]*?\$')defkwexpand(mobj,kwfctx):'''Called by kwfilelog.read and pretxnkw. Expands keywords according to file context.'''return'$%s: %s $'%(mobj.group(1),kwfctx.expand(mobj.group(1)))defkwfmatches(ui,repo,files):'''Selects candidates for keyword substitution configured in keyword section in hgrc.'''files=[fforfinfilesifnotf.startswith('.hg')]ifnotfiles:return[]candidates=[]kwfmatchers=[util.matcher(repo.root,'',[pat],[],[])[1]forpat,optinui.configitems('keyword')ifopt=='expand']forfinfiles:formfinkwfmatchers:ifmf(f):candidates.append(f)breakreturncandidatesdefutcdate(date):'''Returns hgdate in cvs-like UTC format.'''returntime.strftime('%Y/%m/%d %H:%M:%S',time.gmtime(date[0]))classkwfilectx(context.filectx):''' Provides keyword expansion functions based on file context. '''def__init__(self,repo,path,changeid=None,fileid=None,filelog=None):context.filectx.__init__(self,repo,path,changeid,fileid,filelog)defRevision(self):returnstr(self.changectx())defAuthor(self):returnutil.shortuser(self.user())defDate(self):returnutcdate(self.date())defRCSFile(self):returnos.path.basename(self._path)+',v'defSource(self):returnself._repo.wjoin(self._path)+',v'defHeader(self):return' '.join([self.Source(),self.Revision(),self.Date(),self.Author()])defId(self):return' '.join([self.RCSFile(),self.Revision(),self.Date(),self.Author()])defexpand(self,kw):'''Called from kwexpand, evaluates keyword.'''returneval('self.%s()'%kw)defreposetup(ui,repo):frommercurialimportfilelog,revlogifnotrepo.local():returnclasskwrepo(repo.__class__):deffile(self,f):iff[0]=='/':f=f[1:]returnfilelog.filelog(self.sopener,f,self,self.revlogversion)classkwfilelog(filelog.filelog):''' Superclass over filelog to customize it's read, add, cmp methods. Keywords are "stored" unexpanded, and expanded on reading. '''def__init__(self,opener,path,repo,defversion=revlog.REVLOG_DEFAULT_VERSION):super(kwfilelog,self).__init__(opener,path,defversion)self._repo=repoself._path=pathdefiskwcandidate(self,data):'''Decides whether to act on keywords.'''return(kwfmatches(ui,self._repo,[self._path])andnotutil.binary(data))defread(self,node):'''Substitutes keywords when reading filelog.'''data=super(kwfilelog,self).read(node)ifself.iskwcandidate(data):kwfctx=kwfilectx(self._repo,self._path,fileid=node,filelog=self)returnre_kw.sub(lambdam:kwexpand(m,kwfctx),data)returndatadefadd(self,text,meta,tr,link,p1=None,p2=None):'''Removes keyword substitutions when adding to filelog.'''ifself.iskwcandidate(text):text=re_kw.sub(r'$\1$',text)returnsuper(kwfilelog,self).add(text,meta,tr,link,p1=p1,p2=p2)defcmp(self,node,text):'''Removes keyword substitutions for comparison.'''ifself.iskwcandidate(text):text=re_kw.sub(r'$\1$',text)returnsuper(kwfilelog,self).cmp(node,text)filelog.filelog=kwfilelogrepo.__class__=kwrepo# make pretxncommit hook import kwmodule regardless of where it's locatedfork,vinsys.modules.iteritems():ifvisNone:continueifnothasattr(v,'__file__'):continueifv.__file__.startswith(__file__):mod=kbreakelse:sys.path.insert(0,os.path.abspath(os.path.dirname(__file__)))mod=os.path.splitext(os.path.basename(__file__))[0]ui.setconfig('hooks','pretxncommit.keyword','python:%s.pretxnkw'%mod)delmoddefpretxnkw(ui,repo,hooktype,**args):'''pretxncommit hook that collects candidates for keyword expansion on commit and expands keywords in working dir.'''frommercurial.i18nimportgettextas_# above line for backwards compatibility; can be changed to# from mercurial.i18n import _# some dayfrommercurialimportcmdutil,commandsifhooktype!='pretxncommit':returnTruecmd,sysargs,globalopts,cmdopts=commands.parse(ui,sys.argv[1:])[1:]ifrepr(cmd).split()[1]in('tag','import_'):returnFalsefiles,match,anypats=cmdutil.matchpats(repo,sysargs,cmdopts)modified,added=repo.status(files=files,match=match)[:2]forfinkwfmatches(ui,repo,modified+added):data=repo.wfile(f).read()ifnotutil.binary(data):kwfctx=kwfilectx(repo,f,changeid=args['node'])data,kwct=re_kw.subn(lambdam:kwexpand(m,kwfctx),data)ifkwct:ui.debug(_('overwriting %s expanding keywords\n'%f))repo.wfile(f,'w').write(data)