mercurial/commands.py
changeset 2189 e3eba577a0ae
parent 2184 2477a7183a6f
child 2204 eb5fa83ffcfa
equal deleted inserted replaced
2188:62ae3d140185 2189:e3eba577a0ae
   396     user = revcache.get(rev)
   396     user = revcache.get(rev)
   397     if user is None:
   397     if user is None:
   398         user = revcache[rev] = ui.shortuser(name)
   398         user = revcache[rev] = ui.shortuser(name)
   399     return user
   399     return user
   400 
   400 
   401 class changeset_templater(object):
       
   402     '''use templater module to format changeset information.'''
       
   403 
       
   404     def __init__(self, ui, repo, mapfile):
       
   405         self.t = templater.templater(mapfile, templater.common_filters,
       
   406                                      cache={'parent': '{rev}:{node|short} ',
       
   407                                             'manifest': '{rev}:{node|short}'})
       
   408         self.ui = ui
       
   409         self.repo = repo
       
   410 
       
   411     def use_template(self, t):
       
   412         '''set template string to use'''
       
   413         self.t.cache['changeset'] = t
       
   414 
       
   415     def write(self, thing, header=False):
       
   416         '''write expanded template.
       
   417         uses in-order recursive traverse of iterators.'''
       
   418         for t in thing:
       
   419             if hasattr(t, '__iter__'):
       
   420                 self.write(t, header=header)
       
   421             elif header:
       
   422                 self.ui.write_header(t)
       
   423             else:
       
   424                 self.ui.write(t)
       
   425 
       
   426     def write_header(self, thing):
       
   427         self.write(thing, header=True)
       
   428 
       
   429     def show(self, rev=0, changenode=None, brinfo=None):
       
   430         '''show a single changeset or file revision'''
       
   431         log = self.repo.changelog
       
   432         if changenode is None:
       
   433             changenode = log.node(rev)
       
   434         elif not rev:
       
   435             rev = log.rev(changenode)
       
   436 
       
   437         changes = log.read(changenode)
       
   438 
       
   439         def showlist(name, values, plural=None, **args):
       
   440             '''expand set of values.
       
   441             name is name of key in template map.
       
   442             values is list of strings or dicts.
       
   443             plural is plural of name, if not simply name + 's'.
       
   444 
       
   445             expansion works like this, given name 'foo'.
       
   446 
       
   447             if values is empty, expand 'no_foos'.
       
   448 
       
   449             if 'foo' not in template map, return values as a string,
       
   450             joined by space.
       
   451 
       
   452             expand 'start_foos'.
       
   453 
       
   454             for each value, expand 'foo'. if 'last_foo' in template
       
   455             map, expand it instead of 'foo' for last key.
       
   456 
       
   457             expand 'end_foos'.
       
   458             '''
       
   459             if plural: names = plural
       
   460             else: names = name + 's'
       
   461             if not values:
       
   462                 noname = 'no_' + names
       
   463                 if noname in self.t:
       
   464                     yield self.t(noname, **args)
       
   465                 return
       
   466             if name not in self.t:
       
   467                 if isinstance(values[0], str):
       
   468                     yield ' '.join(values)
       
   469                 else:
       
   470                     for v in values:
       
   471                         yield dict(v, **args)
       
   472                 return
       
   473             startname = 'start_' + names
       
   474             if startname in self.t:
       
   475                 yield self.t(startname, **args)
       
   476             vargs = args.copy()
       
   477             def one(v, tag=name):
       
   478                 try:
       
   479                     vargs.update(v)
       
   480                 except (AttributeError, ValueError):
       
   481                     try:
       
   482                         for a, b in v:
       
   483                             vargs[a] = b
       
   484                     except ValueError:
       
   485                         vargs[name] = v
       
   486                 return self.t(tag, **vargs)
       
   487             lastname = 'last_' + name
       
   488             if lastname in self.t:
       
   489                 last = values.pop()
       
   490             else:
       
   491                 last = None
       
   492             for v in values:
       
   493                 yield one(v)
       
   494             if last is not None:
       
   495                 yield one(last, tag=lastname)
       
   496             endname = 'end_' + names
       
   497             if endname in self.t:
       
   498                 yield self.t(endname, **args)
       
   499 
       
   500         if brinfo:
       
   501             def showbranches(**args):
       
   502                 if changenode in brinfo:
       
   503                     for x in showlist('branch', brinfo[changenode],
       
   504                                       plural='branches', **args):
       
   505                         yield x
       
   506         else:
       
   507             showbranches = ''
       
   508 
       
   509         if self.ui.debugflag:
       
   510             def showmanifest(**args):
       
   511                 args = args.copy()
       
   512                 args.update(dict(rev=self.repo.manifest.rev(changes[0]),
       
   513                                  node=hex(changes[0])))
       
   514                 yield self.t('manifest', **args)
       
   515         else:
       
   516             showmanifest = ''
       
   517 
       
   518         def showparents(**args):
       
   519             parents = [[('rev', log.rev(p)), ('node', hex(p))]
       
   520                        for p in log.parents(changenode)
       
   521                        if self.ui.debugflag or p != nullid]
       
   522             if (not self.ui.debugflag and len(parents) == 1 and
       
   523                 parents[0][0][1] == rev - 1):
       
   524                 return
       
   525             for x in showlist('parent', parents, **args):
       
   526                 yield x
       
   527 
       
   528         def showtags(**args):
       
   529             for x in showlist('tag', self.repo.nodetags(changenode), **args):
       
   530                 yield x
       
   531 
       
   532         if self.ui.debugflag:
       
   533             files = self.repo.changes(log.parents(changenode)[0], changenode)
       
   534             def showfiles(**args):
       
   535                 for x in showlist('file', files[0], **args): yield x
       
   536             def showadds(**args):
       
   537                 for x in showlist('file_add', files[1], **args): yield x
       
   538             def showdels(**args):
       
   539                 for x in showlist('file_del', files[2], **args): yield x
       
   540         else:
       
   541             def showfiles(**args):
       
   542                 for x in showlist('file', changes[3], **args): yield x
       
   543             showadds = ''
       
   544             showdels = ''
       
   545 
       
   546         props = {
       
   547             'author': changes[1],
       
   548             'branches': showbranches,
       
   549             'date': changes[2],
       
   550             'desc': changes[4],
       
   551             'file_adds': showadds,
       
   552             'file_dels': showdels,
       
   553             'files': showfiles,
       
   554             'manifest': showmanifest,
       
   555             'node': hex(changenode),
       
   556             'parents': showparents,
       
   557             'rev': rev,
       
   558             'tags': showtags,
       
   559             }
       
   560 
       
   561         try:
       
   562             if self.ui.debugflag and 'header_debug' in self.t:
       
   563                 key = 'header_debug'
       
   564             elif self.ui.quiet and 'header_quiet' in self.t:
       
   565                 key = 'header_quiet'
       
   566             elif self.ui.verbose and 'header_verbose' in self.t:
       
   567                 key = 'header_verbose'
       
   568             elif 'header' in self.t:
       
   569                 key = 'header'
       
   570             else:
       
   571                 key = ''
       
   572             if key:
       
   573                 self.write_header(self.t(key, **props))
       
   574             if self.ui.debugflag and 'changeset_debug' in self.t:
       
   575                 key = 'changeset_debug'
       
   576             elif self.ui.quiet and 'changeset_quiet' in self.t:
       
   577                 key = 'changeset_quiet'
       
   578             elif self.ui.verbose and 'changeset_verbose' in self.t:
       
   579                 key = 'changeset_verbose'
       
   580             else:
       
   581                 key = 'changeset'
       
   582             self.write(self.t(key, **props))
       
   583         except KeyError, inst:
       
   584             raise util.Abort(_("%s: no key named '%s'") % (self.t.mapfile,
       
   585                                                            inst.args[0]))
       
   586         except SyntaxError, inst:
       
   587             raise util.Abort(_('%s: %s') % (self.t.mapfile, inst.args[0]))
       
   588 
       
   589 class changeset_printer(object):
   401 class changeset_printer(object):
   590     '''show changeset information when templating not requested.'''
   402     '''show changeset information when templating not requested.'''
   591 
   403 
   592     def __init__(self, ui, repo):
   404     def __init__(self, ui, repo):
   593         self.ui = ui
   405         self.ui = ui
   670             if not os.path.isfile(mapfile):
   482             if not os.path.isfile(mapfile):
   671                 mapname = templater.templatepath('map-cmdline.' + mapfile)
   483                 mapname = templater.templatepath('map-cmdline.' + mapfile)
   672                 if not mapname: mapname = templater.templatepath(mapfile)
   484                 if not mapname: mapname = templater.templatepath(mapfile)
   673                 if mapname: mapfile = mapname
   485                 if mapname: mapfile = mapname
   674         try:
   486         try:
   675             t = changeset_templater(ui, repo, mapfile)
   487             t = templater.changeset_templater(ui, repo, mapfile)
   676         except SyntaxError, inst:
   488         except SyntaxError, inst:
   677             raise util.Abort(inst.args[0])
   489             raise util.Abort(inst.args[0])
   678         if tmpl: t.use_template(tmpl)
   490         if tmpl: t.use_template(tmpl)
   679         return t
   491         return t
   680     return changeset_printer(ui, repo)
   492     return changeset_printer(ui, repo)