##// END OF EJS Templates
merge with crew.
merge with crew.

File last commit:

r2206:c74e91e8 default
r2279:51bfa0fd merge default
Show More
ui.py
281 lines | 10.0 KiB | text/x-python | PythonLexer
mpm@selenic.com
Move ui class to its own module...
r207 # ui.py - user interface bits for mercurial
#
# Copyright 2005 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
Vadim Gelfer
inherit hgrc so "%" interpolation works.
r1866 import ConfigParser
Benoit Boissinot
i18n first part: make '_' available for files who need it
r1400 from i18n import gettext as _
Bryan O'Sullivan
Demand-load most modules in the commands and ui modules....
r613 from demandload import *
Vadim Gelfer
move mail sending code into core, so extensions can share it....
r2200 demandload(globals(), "errno os re smtplib socket sys tempfile util")
mpm@selenic.com
Move ui class to its own module...
r207
Eric Hopper
Convert all classes to new-style classes by deriving them from object.
r1559 class ui(object):
mpm@selenic.com
Move ui class to its own module...
r207 def __init__(self, verbose=False, debug=False, quiet=False,
Vadim Gelfer
do not check sys.argv from localrepo when running hooks....
r2166 interactive=True, traceback=False, parentui=None):
mpm@selenic.com
Add ui.setconfig overlay...
r960 self.overlay = {}
Thomas Arendsen Hein
Create local ui object per repository, so .hg/hgrc don't get mixed....
r1839 if parentui is None:
Thomas Arendsen Hein
Inherit config from real parentui and don't use ConfigParser internals....
r1874 # this is the parent of all ui children
self.parentui = None
self.cdata = ConfigParser.SafeConfigParser()
Vadim Gelfer
add HGRCPATH env var, list of places to look for hgrc files....
r1951 self.readconfig(util.rcpath())
mpm@selenic.com
ui: add configuration file support...
r285
Thomas Arendsen Hein
Create local ui object per repository, so .hg/hgrc don't get mixed....
r1839 self.quiet = self.configbool("ui", "quiet")
self.verbose = self.configbool("ui", "verbose")
self.debugflag = self.configbool("ui", "debug")
self.interactive = self.configbool("ui", "interactive", True)
Vadim Gelfer
do not check sys.argv from localrepo when running hooks....
r2166 self.traceback = traceback
mpm@selenic.com
ui: add configuration file support...
r285
Thomas Arendsen Hein
Create local ui object per repository, so .hg/hgrc don't get mixed....
r1839 self.updateopts(verbose, debug, quiet, interactive)
self.diffcache = None
Thomas Arendsen Hein
Group changes done by the same developer on the same with --style=changelog...
r2033 self.header = []
self.prev_header = []
mason@suse.com
Implement revlogng....
r2072 self.revlogopts = self.configrevlog()
Vadim Gelfer
inherit hgrc so "%" interpolation works.
r1866 else:
Thomas Arendsen Hein
Inherit config from real parentui and don't use ConfigParser internals....
r1874 # parentui may point to an ui object which is already a child
self.parentui = parentui.parentui or parentui
parent_cdata = self.parentui.cdata
self.cdata = ConfigParser.SafeConfigParser(parent_cdata.defaults())
# make interpolation work
for section in parent_cdata.sections():
self.cdata.add_section(section)
for name, value in parent_cdata.items(section, raw=True):
self.cdata.set(section, name, value)
Thomas Arendsen Hein
Create local ui object per repository, so .hg/hgrc don't get mixed....
r1839
def __getattr__(self, key):
return getattr(self.parentui, key)
mason@suse.com
Add support for extension modules...
r1071
def updateopts(self, verbose=False, debug=False, quiet=False,
Vadim Gelfer
do not check sys.argv from localrepo when running hooks....
r2166 interactive=True, traceback=False):
mpm@selenic.com
ui: add configuration file support...
r285 self.quiet = (self.quiet or quiet) and not verbose and not debug
self.verbose = (self.verbose or verbose) or debug
self.debugflag = (self.debugflag or debug)
self.interactive = (self.interactive and interactive)
Vadim Gelfer
do not check sys.argv from localrepo when running hooks....
r2166 self.traceback = self.traceback or traceback
mpm@selenic.com
ui: add configuration file support...
r285
Thomas Arendsen Hein
Read paths specified in .hg/hgrc relative to repo root, otherwise to home dir.
r1893 def readconfig(self, fn, root=None):
Soh Tk-r28629
Fix traceback on bad system hgrc files
r1483 if isinstance(fn, basestring):
fn = [fn]
for f in fn:
try:
self.cdata.read(f)
except ConfigParser.ParsingError, inst:
raise util.Abort(_("Failed to parse %s\n%s") % (f, inst))
Thomas Arendsen Hein
Read paths specified in .hg/hgrc relative to repo root, otherwise to home dir.
r1893 # translate paths relative to root (or home) into absolute paths
if root is None:
root = os.path.expanduser('~')
for name, path in self.configitems("paths"):
Thomas Arendsen Hein
Don't expand empty [paths] so later interpolation can do the right thing....
r1921 if path and path.find("://") == -1 and not os.path.isabs(path):
Thomas Arendsen Hein
Read paths specified in .hg/hgrc relative to repo root, otherwise to home dir.
r1893 self.cdata.set("paths", name, os.path.join(root, path))
mpm@selenic.com
Add support for .hg/hgrc file...
r337
mpm@selenic.com
Add ui.setconfig overlay...
r960 def setconfig(self, section, name, val):
self.overlay[(section, name)] = val
def config(self, section, name, default=None):
if self.overlay.has_key((section, name)):
return self.overlay[(section, name)]
if self.cdata.has_option(section, name):
Thomas Arendsen Hein
Catch hgrc interpolation errors nicely.
r1876 try:
return self.cdata.get(section, name)
except ConfigParser.InterpolationError, inst:
raise util.Abort(_("Error in configuration:\n%s") % inst)
Thomas Arendsen Hein
Create local ui object per repository, so .hg/hgrc don't get mixed....
r1839 if self.parentui is None:
return default
else:
return self.parentui.config(section, name, default)
mpm@selenic.com
ui: add configuration file support...
r285
mpm@selenic.com
Add ui.setconfig overlay...
r960 def configbool(self, section, name, default=False):
if self.overlay.has_key((section, name)):
return self.overlay[(section, name)]
if self.cdata.has_option(section, name):
Thomas Arendsen Hein
Catch hgrc interpolation errors nicely.
r1876 try:
return self.cdata.getboolean(section, name)
except ConfigParser.InterpolationError, inst:
raise util.Abort(_("Error in configuration:\n%s") % inst)
Thomas Arendsen Hein
Create local ui object per repository, so .hg/hgrc don't get mixed....
r1839 if self.parentui is None:
return default
else:
return self.parentui.configbool(section, name, default)
mpm@selenic.com
ui: add configuration file support...
r285
def configitems(self, section):
Thomas Arendsen Hein
Create local ui object per repository, so .hg/hgrc don't get mixed....
r1839 items = {}
if self.parentui is not None:
items = dict(self.parentui.configitems(section))
mpm@selenic.com
ui: add configuration file support...
r285 if self.cdata.has_section(section):
Thomas Arendsen Hein
Catch hgrc interpolation errors nicely.
r1876 try:
items.update(dict(self.cdata.items(section)))
except ConfigParser.InterpolationError, inst:
raise util.Abort(_("Error in configuration:\n%s") % inst)
Thomas Arendsen Hein
Create local ui object per repository, so .hg/hgrc don't get mixed....
r1839 x = items.items()
x.sort()
return x
mpm@selenic.com
ui: add configuration file support...
r285
Thomas Arendsen Hein
Create local ui object per repository, so .hg/hgrc don't get mixed....
r1839 def walkconfig(self, seen=None):
if seen is None:
seen = {}
Bryan O'Sullivan
Add commands.debugconfig....
r1028 for (section, name), value in self.overlay.iteritems():
yield section, name, value
seen[section, name] = 1
for section in self.cdata.sections():
for name, value in self.cdata.items(section):
if (section, name) in seen: continue
yield section, name, value.replace('\n', '\\n')
seen[section, name] = 1
Thomas Arendsen Hein
Create local ui object per repository, so .hg/hgrc don't get mixed....
r1839 if self.parentui is not None:
for parent in self.parentui.walkconfig(seen):
yield parent
Bryan O'Sullivan
Add commands.debugconfig....
r1028
mason@suse.com
Add support for extension modules...
r1071 def extensions(self):
return self.configitems("extensions")
mcmillen@cs.cmu.edu
Implementation of per-user .hgignore....
r2003 def hgignorefiles(self):
result = []
cfgitems = self.configitems("ui")
for key, value in cfgitems:
if key == 'ignore' or key.startswith('ignore.'):
path = os.path.expanduser(value)
result.append(path)
return result
mason@suse.com
Implement revlogng....
r2072 def configrevlog(self):
ret = {}
for x in self.configitems("revlog"):
k = x[0].lower()
ret[k] = x[1]
return ret
mason@suse.com
Add new bdiff based unidiff generation.
r1637 def diffopts(self):
if self.diffcache:
return self.diffcache
ret = { 'showfunc' : True, 'ignorews' : False}
for x in self.configitems("diff"):
k = x[0].lower()
v = x[1]
if v:
v = v.lower()
if v == 'true':
value = True
else:
value = False
ret[k] = value
self.diffcache = ret
return ret
Matt Mackall
Add username/merge/editor to .hgrc...
r608 def username(self):
Thomas Arendsen Hein
Adapted behaviour of ui.username() to documentation and mention it explicitly:...
r1985 """Return default username to be used in commits.
Searched in this order: $HGUSER, [ui] section of hgrcs, $EMAIL
and stop searching if one of these is set.
Abort if found username is an empty string to force specifying
the commit user elsewhere, e.g. with line option or repo hgrc.
If not found, use $LOGNAME or $USERNAME +"@full.hostname".
"""
user = os.environ.get("HGUSER")
if user is None:
user = self.config("ui", "username")
if user is None:
user = os.environ.get("EMAIL")
if user is None:
user = os.environ.get("LOGNAME") or os.environ.get("USERNAME")
if user:
user = "%s@%s" % (user, socket.getfqdn())
if not user:
raise util.Abort(_("Please specify a username."))
return user
Matt Mackall
Add username/merge/editor to .hgrc...
r608
Thomas Arendsen Hein
Move generating short username to display in hg/hgweb annotate to ui module.
r1129 def shortuser(self, user):
"""Return a short representation of a user name or email address."""
Vadim Gelfer
move shortuser into util module.
r1903 if not self.verbose: user = util.shortuser(user)
Thomas Arendsen Hein
Move generating short username to display in hg/hgweb annotate to ui module.
r1129 return user
Thomas Arendsen Hein
Read paths specified in .hg/hgrc relative to repo root, otherwise to home dir.
r1893 def expandpath(self, loc):
Thomas Arendsen Hein
Directory names take precedence over symbolic names consistently....
r1892 """Return repository location relative to cwd or from [paths]"""
Thomas Arendsen Hein
Read paths specified in .hg/hgrc relative to repo root, otherwise to home dir.
r1893 if loc.find("://") != -1 or os.path.exists(loc):
Thomas Arendsen Hein
Directory names take precedence over symbolic names consistently....
r1892 return loc
Thomas Arendsen Hein
Read paths specified in .hg/hgrc relative to repo root, otherwise to home dir.
r1893 return self.config("paths", loc, loc)
mpm@selenic.com
[PATCH] Add ui.expandpath command...
r506
mpm@selenic.com
Move ui class to its own module...
r207 def write(self, *args):
Thomas Arendsen Hein
Group changes done by the same developer on the same with --style=changelog...
r2033 if self.header:
if self.header != self.prev_header:
self.prev_header = self.header
self.write(*self.header)
self.header = []
mpm@selenic.com
Move ui class to its own module...
r207 for a in args:
sys.stdout.write(str(a))
mpm@selenic.com
[PATCH] Make ui.warn write to stderr...
r565
Thomas Arendsen Hein
Group changes done by the same developer on the same with --style=changelog...
r2033 def write_header(self, *args):
for a in args:
self.header.append(str(a))
mpm@selenic.com
[PATCH] Make ui.warn write to stderr...
r565 def write_err(self, *args):
Benoit Boissinot
ignore EPIPE in ui.err_write...
r1989 try:
if not sys.stdout.closed: sys.stdout.flush()
for a in args:
sys.stderr.write(str(a))
except IOError, inst:
if inst.errno != errno.EPIPE:
raise
mpm@selenic.com
[PATCH] Make ui.warn write to stderr...
r565
Vadim Gelfer
make ui flush output. this makes error happen if printing to /dev/full....
r1837 def flush(self):
Eung-Ju Park
Fix error on Windows if "hg log | more" exits.
r2013 try: sys.stdout.flush()
except: pass
try: sys.stderr.flush()
except: pass
Vadim Gelfer
make ui flush output. this makes error happen if printing to /dev/full....
r1837
mpm@selenic.com
Move ui class to its own module...
r207 def readline(self):
return sys.stdin.readline()[:-1]
benoit.boissinot@ens-lyon.fr
pep-0008 cleanup...
r1062 def prompt(self, msg, pat, default="y"):
mpm@selenic.com
Move ui class to its own module...
r207 if not self.interactive: return default
while 1:
self.write(msg, " ")
r = self.readline()
if re.match(pat, r):
return r
else:
Benoit Boissinot
i18n part2: use '_' for all strings who are part of the user interface
r1402 self.write(_("unrecognized response\n"))
mpm@selenic.com
Move ui class to its own module...
r207 def status(self, *msg):
if not self.quiet: self.write(*msg)
Thomas Arendsen Hein
ui.warn can use more than one argument like the other ui methods.
r234 def warn(self, *msg):
mpm@selenic.com
[PATCH] Make ui.warn write to stderr...
r565 self.write_err(*msg)
mpm@selenic.com
Move ui class to its own module...
r207 def note(self, *msg):
if self.verbose: self.write(*msg)
def debug(self, *msg):
if self.debugflag: self.write(*msg)
Thomas Arendsen Hein
Pass correct username as $HGUSER to hgeditor if "commit -u" is used....
r1983 def edit(self, text, user):
Stephen Darnell
Use text rather than binary mode for editing commit messages
r2206 (fd, name) = tempfile.mkstemp(prefix="hg-editor-", suffix=".txt",
text=True)
Thomas Arendsen Hein
Improved ui.edit():...
r1984 try:
f = os.fdopen(fd, "w")
f.write(text)
f.close()
editor = (os.environ.get("HGEDITOR") or
self.config("ui", "editor") or
os.environ.get("EDITOR", "vi"))
mpm@selenic.com
Move ui class to its own module...
r207
Thomas Arendsen Hein
Improved ui.edit():...
r1984 util.system("%s \"%s\"" % (editor, name),
environ={'HGUSER': user},
onerr=util.Abort, errprefix=_("edit failed"))
Matt Mackall
Add username/merge/editor to .hgrc...
r608
Thomas Arendsen Hein
Improved ui.edit():...
r1984 f = open(name)
t = f.read()
f.close()
t = re.sub("(?m)^HG:.*\n", "", t)
finally:
os.unlink(name)
Radoslaw "AstralStorm" Szkodzinski
Pass username to hgeditor, remove temporary file...
r662
mpm@selenic.com
Move ui class to its own module...
r207 return t
Vadim Gelfer
move mail sending code into core, so extensions can share it....
r2200
def sendmail(self):
s = smtplib.SMTP()
s.connect(host = self.config('smtp', 'host', 'mail'),
port = int(self.config('smtp', 'port', 25)))
if self.configbool('smtp', 'tls'):
s.ehlo()
s.starttls()
s.ehlo()
username = self.config('smtp', 'username')
password = self.config('smtp', 'password')
if username and password:
s.login(username, password)
return s