##// END OF EJS Templates
getchangegroup: take an 'outgoing' object as argument (API)...
getchangegroup: take an 'outgoing' object as argument (API) There is various version of this function that differ mostly by the way they define the bundled set. The flexibility is now available in the outgoing object itself so we move the complexity into the caller themself. This will allow use to remove a good share of the similar function to obtains a changegroup in the 'changegroup.py' module. An important side effect is that we stop calling 'computeoutgoing' in 'getchangegroup'. This is fine as code that needs such argument processing is actually going through the 'exchange' module which already all this function itself.

File last commit:

r29794:4891f3b9 default
r29807:d4e02634 default
Show More
formatter.py
279 lines | 9.5 KiB | text/x-python | PythonLexer
Matt Mackall
formatter: add basic formatters
r16134 # formatter.py - generic output formatting for mercurial
#
# Copyright 2012 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
Gregory Szorc
formatter: use absolute_import
r25950 from __future__ import absolute_import
Matt Mackall
formatter: move most of template option helper to formatter...
r25511 import os
Matt Mackall
formatter: add json formatter
r22428
Gregory Szorc
formatter: use absolute_import
r25950 from .i18n import _
from .node import (
hex,
short,
)
from . import (
encoding,
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 error,
Yuya Nishihara
formatter: add function to convert list to appropriate format (issue5217)...
r29676 templatekw,
Gregory Szorc
formatter: use absolute_import
r25950 templater,
Pulkit Goyal
py3: conditionalize cPickle import by adding in util...
r29324 util,
Gregory Szorc
formatter: use absolute_import
r25950 )
Pulkit Goyal
py3: conditionalize cPickle import by adding in util...
r29324 pickle = util.pickle
Matt Mackall
formatter: add basic formatters
r16134 class baseformatter(object):
def __init__(self, ui, topic, opts):
self._ui = ui
self._topic = topic
self._style = opts.get("style")
self._template = opts.get("template")
self._item = None
Yuya Nishihara
formatter: add general way to switch hex/short functions...
r22701 # function to convert node to string suitable for this output
self.hexfunc = hex
Yuya Nishihara
formatter: correct bool testing which should be __nonzero__ in Python 2
r22447 def __nonzero__(self):
Matt Mackall
formatter: add basic formatters
r16134 '''return False if we're not doing real templating so we can
skip extra work'''
return True
def _showitem(self):
'''show a formatted item once all data is collected'''
pass
def startitem(self):
'''begin an item in the format list'''
if self._item is not None:
self._showitem()
self._item = {}
Yuya Nishihara
formatter: add function to convert list to appropriate format (issue5217)...
r29676 @staticmethod
Yuya Nishihara
formatter: add function to convert date tuple to appropriate format
r29678 def formatdate(date, fmt='%a %b %d %H:%M:%S %Y %1%2'):
'''convert date tuple to appropriate format'''
return date
@staticmethod
Yuya Nishihara
formatter: add function to convert dict to appropriate format...
r29794 def formatdict(data, key='key', value='value', fmt='%s=%s', sep=' '):
'''convert dict or key-value pairs to appropriate dict format'''
# use plain dict instead of util.sortdict so that data can be
# serialized as a builtin dict in pickle output
return dict(data)
@staticmethod
Yuya Nishihara
formatter: add function to convert list to appropriate format (issue5217)...
r29676 def formatlist(data, name, fmt='%s', sep=' '):
'''convert iterable to appropriate list format'''
return list(data)
Matt Mackall
formatter: add basic formatters
r16134 def data(self, **data):
'''insert data into item that's not shown in default output'''
David M. Carr
formatter: improve implementation of data method...
r17630 self._item.update(data)
Matt Mackall
formatter: add basic formatters
r16134 def write(self, fields, deftext, *fielddata, **opts):
'''do default text output while assigning data to item'''
Yuya Nishihara
formatter: verify number of arguments passed to write functions...
r26372 fieldkeys = fields.split()
assert len(fieldkeys) == len(fielddata)
Yuya Nishihara
formatter: use dict.update() to set arguments passed to write functions...
r26373 self._item.update(zip(fieldkeys, fielddata))
Matt Mackall
formatter: add condwrite method...
r17909 def condwrite(self, cond, fields, deftext, *fielddata, **opts):
'''do conditional write (primarily for plain formatter)'''
Yuya Nishihara
formatter: verify number of arguments passed to write functions...
r26372 fieldkeys = fields.split()
assert len(fieldkeys) == len(fielddata)
Yuya Nishihara
formatter: use dict.update() to set arguments passed to write functions...
r26373 self._item.update(zip(fieldkeys, fielddata))
Matt Mackall
formatter: add basic formatters
r16134 def plain(self, text, **opts):
'''show raw text for non-templated mode'''
pass
def end(self):
'''end output for the formatter'''
if self._item is not None:
self._showitem()
Yuya Nishihara
formatter: add function to convert dict to appropriate format...
r29794 def _iteritems(data):
'''iterate key-value pairs in stable order'''
if isinstance(data, dict):
return sorted(data.iteritems())
return data
Matt Mackall
formatter: add basic formatters
r16134 class plainformatter(baseformatter):
'''the default text output scheme'''
def __init__(self, ui, topic, opts):
baseformatter.__init__(self, ui, topic, opts)
Yuya Nishihara
formatter: add general way to switch hex/short functions...
r22701 if ui.debugflag:
self.hexfunc = hex
else:
self.hexfunc = short
Yuya Nishihara
formatter: correct bool testing which should be __nonzero__ in Python 2
r22447 def __nonzero__(self):
Matt Mackall
formatter: add basic formatters
r16134 return False
def startitem(self):
pass
Yuya Nishihara
formatter: add function to convert list to appropriate format (issue5217)...
r29676 @staticmethod
Yuya Nishihara
formatter: add function to convert date tuple to appropriate format
r29678 def formatdate(date, fmt='%a %b %d %H:%M:%S %Y %1%2'):
'''stringify date tuple in the given format'''
return util.datestr(date, fmt)
@staticmethod
Yuya Nishihara
formatter: add function to convert dict to appropriate format...
r29794 def formatdict(data, key='key', value='value', fmt='%s=%s', sep=' '):
'''stringify key-value pairs separated by sep'''
return sep.join(fmt % (k, v) for k, v in _iteritems(data))
@staticmethod
Yuya Nishihara
formatter: add function to convert list to appropriate format (issue5217)...
r29676 def formatlist(data, name, fmt='%s', sep=' '):
'''stringify iterable separated by sep'''
return sep.join(fmt % e for e in data)
Matt Mackall
formatter: add basic formatters
r16134 def data(self, **data):
pass
def write(self, fields, deftext, *fielddata, **opts):
self._ui.write(deftext % fielddata, **opts)
Matt Mackall
formatter: add condwrite method...
r17909 def condwrite(self, cond, fields, deftext, *fielddata, **opts):
'''do conditional write'''
if cond:
self._ui.write(deftext % fielddata, **opts)
Matt Mackall
formatter: add basic formatters
r16134 def plain(self, text, **opts):
self._ui.write(text, **opts)
def end(self):
pass
class debugformatter(baseformatter):
def __init__(self, ui, topic, opts):
baseformatter.__init__(self, ui, topic, opts)
Matt Mackall
formatter: make debug style match Python syntax
r22424 self._ui.write("%s = [\n" % self._topic)
Matt Mackall
formatter: add basic formatters
r16134 def _showitem(self):
self._ui.write(" " + repr(self._item) + ",\n")
def end(self):
baseformatter.end(self)
Matt Mackall
formatter: make debug style match Python syntax
r22424 self._ui.write("]\n")
Matt Mackall
formatter: add basic formatters
r16134
Matt Mackall
formatter: add pickle format...
r22430 class pickleformatter(baseformatter):
def __init__(self, ui, topic, opts):
baseformatter.__init__(self, ui, topic, opts)
self._data = []
def _showitem(self):
self._data.append(self._item)
def end(self):
baseformatter.end(self)
Pulkit Goyal
py3: conditionalize cPickle import by adding in util...
r29324 self._ui.write(pickle.dumps(self._data))
Matt Mackall
formatter: add pickle format...
r22430
Yuya Nishihara
formatter: extract function that encode values to json string...
r22474 def _jsonifyobj(v):
Yuya Nishihara
formatter: add function to convert dict to appropriate format...
r29794 if isinstance(v, dict):
xs = ['"%s": %s' % (encoding.jsonescape(k), _jsonifyobj(u))
for k, u in sorted(v.iteritems())]
return '{' + ', '.join(xs) + '}'
elif isinstance(v, (list, tuple)):
Yuya Nishihara
formatter: have jsonformatter accept tuple as value...
r22475 return '[' + ', '.join(_jsonifyobj(e) for e in v) + ']'
Yuya Nishihara
formatter: convert None to json null...
r24321 elif v is None:
return 'null'
Yuya Nishihara
formatter: convert booleans to json...
r22674 elif v is True:
return 'true'
elif v is False:
return 'false'
Yuya Nishihara
formatter: convert float value to json...
r22476 elif isinstance(v, (int, float)):
return str(v)
Yuya Nishihara
formatter: extract function that encode values to json string...
r22474 else:
return '"%s"' % encoding.jsonescape(v)
Matt Mackall
formatter: add json formatter
r22428 class jsonformatter(baseformatter):
def __init__(self, ui, topic, opts):
baseformatter.__init__(self, ui, topic, opts)
self._ui.write("[")
self._ui._first = True
def _showitem(self):
if self._ui._first:
self._ui._first = False
else:
self._ui.write(",")
self._ui.write("\n {\n")
first = True
for k, v in sorted(self._item.items()):
if first:
first = False
else:
self._ui.write(",\n")
Yuya Nishihara
formatter: extract function that encode values to json string...
r22474 self._ui.write(' "%s": %s' % (k, _jsonifyobj(v)))
Matt Mackall
formatter: add json formatter
r22428 self._ui.write("\n }")
def end(self):
baseformatter.end(self)
self._ui.write("\n]\n")
Matt Mackall
formatter: add template support...
r25513 class templateformatter(baseformatter):
def __init__(self, ui, topic, opts):
baseformatter.__init__(self, ui, topic, opts)
self._topic = topic
self._t = gettemplater(ui, topic, opts.get('template', ''))
def _showitem(self):
Kostia Balytskyi
formatter: make labels work with templated output...
r28384 g = self._t(self._topic, ui=self._ui, **self._item)
Matt Mackall
formatter: add template support...
r25513 self._ui.write(templater.stringify(g))
Yuya Nishihara
formatter: add function to convert list to appropriate format (issue5217)...
r29676 @staticmethod
Yuya Nishihara
formatter: add function to convert dict to appropriate format...
r29794 def formatdict(data, key='key', value='value', fmt='%s=%s', sep=' '):
'''build object that can be evaluated as either plain string or dict'''
data = util.sortdict(_iteritems(data))
def f():
yield plainformatter.formatdict(data, key, value, fmt, sep)
return templatekw._hybrid(f(), data, lambda k: {key: k, value: data[k]},
lambda d: fmt % (d[key], d[value]))
@staticmethod
Yuya Nishihara
formatter: add function to convert list to appropriate format (issue5217)...
r29676 def formatlist(data, name, fmt='%s', sep=' '):
'''build object that can be evaluated as either plain string or list'''
# name is mandatory argument for now, but it could be optional if
# we have default template keyword, e.g. {item}
data = list(data)
def f():
yield plainformatter.formatlist(data, name, fmt, sep)
return templatekw._hybrid(f(), data, lambda x: {name: x},
lambda d: fmt % d[name])
Matt Mackall
formatter: add template support...
r25513
Matt Mackall
formatter: move most of template option helper to formatter...
r25511 def lookuptemplate(ui, topic, tmpl):
# looks like a literal template?
if '{' in tmpl:
return tmpl, None
# perhaps a stock style?
if not os.path.split(tmpl)[0]:
mapname = (templater.templatepath('map-cmdline.' + tmpl)
or templater.templatepath(tmpl))
if mapname and os.path.isfile(mapname):
return None, mapname
# perhaps it's a reference to [templates]
t = ui.config('templates', tmpl)
if t:
Yuya Nishihara
templater: relax unquotestring() to fall back to bare string...
r28630 return templater.unquotestring(t), None
Matt Mackall
formatter: move most of template option helper to formatter...
r25511
if tmpl == 'list':
ui.write(_("available styles: %s\n") % templater.stylelist())
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("specify a template"))
Matt Mackall
formatter: move most of template option helper to formatter...
r25511
# perhaps it's a path to a map or a template
if ('/' in tmpl or '\\' in tmpl) and os.path.isfile(tmpl):
# is it a mapfile for a style?
if os.path.basename(tmpl).startswith("map-"):
return None, os.path.realpath(tmpl)
tmpl = open(tmpl).read()
return tmpl, None
# constant string?
return tmpl, None
Matt Mackall
formatter: add a method to build a full templater from a -T option
r25512 def gettemplater(ui, topic, spec):
tmpl, mapfile = lookuptemplate(ui, topic, spec)
Yuya Nishihara
templater: separate function to create templater from map file (API)...
r28954 assert not (tmpl and mapfile)
if mapfile:
return templater.templater.frommapfile(mapfile)
Yuya Nishihara
templater: factor out function that creates templater from string template...
r28955 return maketemplater(ui, topic, tmpl)
def maketemplater(ui, topic, tmpl, filters=None, cache=None):
"""Create a templater from a string template 'tmpl'"""
Yuya Nishihara
templater: load and expand aliases by template engine (API) (issue4842)...
r28957 aliases = ui.configitems('templatealias')
t = templater.templater(filters=filters, cache=cache, aliases=aliases)
Matt Mackall
formatter: add a method to build a full templater from a -T option
r25512 if tmpl:
t.cache[topic] = tmpl
return t
Matt Mackall
formatter: add basic formatters
r16134 def formatter(ui, topic, opts):
Matt Mackall
formatter: add json formatter
r22428 template = opts.get("template", "")
if template == "json":
return jsonformatter(ui, topic, opts)
Matt Mackall
formatter: add pickle format...
r22430 elif template == "pickle":
return pickleformatter(ui, topic, opts)
Matt Mackall
formatter: add json formatter
r22428 elif template == "debug":
Matt Mackall
formatter: add basic formatters
r16134 return debugformatter(ui, topic, opts)
Matt Mackall
formatter: add json formatter
r22428 elif template != "":
Matt Mackall
formatter: add template support...
r25513 return templateformatter(ui, topic, opts)
Matt Mackall
formatter: mark developer options
r25838 # developer config: ui.formatdebug
Matt Mackall
formatter: add json formatter
r22428 elif ui.configbool('ui', 'formatdebug'):
return debugformatter(ui, topic, opts)
Matt Mackall
formatter: mark developer options
r25838 # deprecated config: ui.formatjson
Matt Mackall
formatter: add json formatter
r22428 elif ui.configbool('ui', 'formatjson'):
return jsonformatter(ui, topic, opts)
Matt Mackall
formatter: add basic formatters
r16134 return plainformatter(ui, topic, opts)