hgkw/keyword.py
branchkwmap-templates
changeset 160 e45d804d28dd
parent 159 28fd5b5eb3ad
child 161 aac10ec0a8cd
equal deleted inserted replaced
159:28fd5b5eb3ad 160:e45d804d28dd
   119 class kwtemplater(object):
   119 class kwtemplater(object):
   120     '''
   120     '''
   121     Sets up keyword templates, corresponding keyword regex, and
   121     Sets up keyword templates, corresponding keyword regex, and
   122     provides keyword substitution functions.
   122     provides keyword substitution functions.
   123     '''
   123     '''
   124     def __init__(self, ui, repo):
   124     def __init__(self, ui, repo, path='', node=None):
   125         self.ui = ui
   125         self.ui = ui
   126         self.repo = repo
   126         self.repo = repo
       
   127         self.path = path
       
   128         self.node = node
   127         templates = dict(ui.configitems('keywordmaps'))
   129         templates = dict(ui.configitems('keywordmaps'))
   128         if templates:
   130         if templates:
   129             # parse templates here for less overhead in kwsub matchfunc
   131             # parse templates here for less overhead in kwsub matchfunc
   130             for k in templates.keys():
   132             for k in templates.keys():
   131                 templates[k] = templater.parsestring(templates[k],
   133                 templates[k] = templater.parsestring(templates[k],
   140         except TypeError:
   142         except TypeError:
   141             # depending on hg rev changeset_templater has extra "brinfo" arg
   143             # depending on hg rev changeset_templater has extra "brinfo" arg
   142             self.t = cmdutil.changeset_templater(ui, repo,
   144             self.t = cmdutil.changeset_templater(ui, repo,
   143                     False, None, '', False)
   145                     False, None, '', False)
   144 
   146 
   145     def kwsub(self, mobj, path, node):
   147     def kwsub(self, mobj):
   146         '''Substitutes keyword using corresponding template.'''
   148         '''Substitutes keyword using corresponding template.'''
   147         kw = mobj.group(1)
   149         kw = mobj.group(1)
   148         self.t.use_template(self.templates[kw])
   150         self.t.use_template(self.templates[kw])
   149         self.ui.pushbuffer()
   151         self.ui.pushbuffer()
   150         self.t.show(changenode=node, root=self.repo.root, file=path)
   152         self.t.show(changenode=self.node, root=self.repo.root, file=self.path)
   151         keywordsub = templater.firstline(self.ui.popbuffer())
   153         keywordsub = templater.firstline(self.ui.popbuffer())
   152         return '$%s: %s $' % (kw, keywordsub)
   154         return '$%s: %s $' % (kw, keywordsub)
   153 
   155 
   154     def expand(self, path, node, filelog, data):
   156     def expand(self, node, flog, data):
   155         '''Returns data with expanded keywords.'''
   157         '''Returns data with expanded keywords.'''
   156         if util.binary(data):
   158         if util.binary(data):
   157             return data
   159             return data
   158         c = context.filectx(self.repo, path, fileid=node, filelog=filelog)
   160         c = context.filectx(self.repo, self.path, fileid=node, filelog=flog)
   159         cnode = c.node()
   161         self.node = c.node()
   160         return self.re_kw.sub(lambda m: self.kwsub(m, path, cnode), data)
   162         return self.re_kw.sub(self.kwsub, data)
   161 
   163 
   162     def shrink(self, text):
   164     def shrink(self, text):
   163         '''Returns text with all keyword substitutions removed.'''
   165         '''Returns text with all keyword substitutions removed.'''
   164         if util.binary(text):
   166         if util.binary(text):
   165             return text
   167             return text
   166         return self.re_kw.sub(r'$\1$', text)
   168         return self.re_kw.sub(r'$\1$', text)
   167 
   169 
   168     def overwrite(self, candidates, node):
   170     def overwrite(self, candidates):
   169         '''Overwrites candidates in working dir expanding keywords.'''
   171         '''Overwrites candidates in working dir expanding keywords.'''
   170         files = []
   172         files = []
   171         for f in candidates:
   173         for f in candidates:
   172             data = self.repo.wfile(f).read()
   174             data = self.repo.wfile(f).read()
   173             if not util.binary(data):
   175             if not util.binary(data):
   174                 data, kwct = self.re_kw.subn(lambda m:
   176                 self.path = f
   175                         self.kwsub(m, f, node), data)
   177                 data, kwct = self.re_kw.subn(self.kwsub, data)
   176                 if kwct:
   178                 if kwct:
   177                     self.ui.debug(_('overwriting %s expanding keywords\n') % f)
   179                     self.ui.debug(_('overwriting %s expanding keywords\n') % f)
   178                     self.repo.wfile(f, 'w').write(data)
   180                     self.repo.wfile(f, 'w').write(data)
   179                     files.append(f)
   181                     files.append(f)
   180         if files:
   182         if files:
   191         self.kwtemplater = kwtemplater
   193         self.kwtemplater = kwtemplater
   192 
   194 
   193     def read(self, node):
   195     def read(self, node):
   194         '''Substitutes keywords when reading filelog.'''
   196         '''Substitutes keywords when reading filelog.'''
   195         data = super(kwfilelog, self).read(node)
   197         data = super(kwfilelog, self).read(node)
   196         return self.kwtemplater.expand(self.path, node, self, data)
   198         return self.kwtemplater.expand(node, self, data)
   197 
   199 
   198     def add(self, text, meta, tr, link, p1=None, p2=None):
   200     def add(self, text, meta, tr, link, p1=None, p2=None):
   199         '''Removes keyword substitutions when adding to filelog.'''
   201         '''Removes keyword substitutions when adding to filelog.'''
   200         text = self.kwtemplater.shrink(text)
   202         text = self.kwtemplater.shrink(text)
   201         return super(kwfilelog, self).add(text,
   203         return super(kwfilelog, self).add(text,
   242         def file(self, f):
   244         def file(self, f):
   243             if f[0] == '/':
   245             if f[0] == '/':
   244                 f = f[1:]
   246                 f = f[1:]
   245             # only use kwfilelog when needed
   247             # only use kwfilelog when needed
   246             if self.kwfmatcher(f):
   248             if self.kwfmatcher(f):
   247                 kwt = kwtemplater(self.ui, self)
   249                 kwt = kwtemplater(self.ui, self, path=f)
   248                 return kwfilelog(self.sopener, f, kwt)
   250                 return kwfilelog(self.sopener, f, kwt)
   249             else:
   251             else:
   250                 return filelog.filelog(self.sopener, f)
   252                 return filelog.filelog(self.sopener, f)
   251 
   253 
   252         def commit(self, files=None, text="", user=None, date=None,
   254         def commit(self, files=None, text="", user=None, date=None,
   273                         and f not in removed
   275                         and f not in removed
   274                         and not os.path.islink(self.wjoin(f))]
   276                         and not os.path.islink(self.wjoin(f))]
   275                 if not candidates:
   277                 if not candidates:
   276                     return node
   278                     return node
   277 
   279 
   278                 kwt = kwtemplater(self.ui, self)
   280                 kwt = kwtemplater(self.ui, self, node=node)
   279                 kwt.overwrite(candidates, node)
   281                 kwt.overwrite(candidates)
   280                 return node
   282                 return node
   281             finally:
   283             finally:
   282                 if wrelease:
   284                 if wrelease:
   283                     wlock.release()
   285                     wlock.release()
   284 
   286