##// END OF EJS Templates
add cmdutil.remoteui...
add cmdutil.remoteui remoteui sorts out the issues of getting ssh config options from the local repo into the remote one while not copying other options like hooks.

File last commit:

r8187:d2504744 default
r8188:f3abe032 default
Show More
ui.py
359 lines | 13.1 KiB | text/x-python | PythonLexer
mpm@selenic.com
Move ui class to its own module...
r207 # ui.py - user interface bits for mercurial
#
Thomas Arendsen Hein
Updated copyright notices and add "and others" to "hg version"
r4635 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
mpm@selenic.com
Move ui class to its own module...
r207 #
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
Matt Mackall
Simplify i18n imports
r3891 from i18n import _
Matt Mackall
Replace demandload with new demandimport
r3877 import errno, getpass, os, re, socket, sys, tempfile
Matt Mackall
ui: introduce new config parser
r8144 import config, traceback, util, error
mpm@selenic.com
Move ui class to its own module...
r207
Matt Mackall
ui: introduce new config parser
r8144 _booleans = {'1':True, 'yes':True, 'true':True, 'on':True,
'0':False, 'no':False, 'false':False, 'off':False}
Alexis S. L. Carvalho
ui.py: change the overlay from a dict to a SafeConfigParser....
r3344
Eric Hopper
Convert all classes to new-style classes by deriving them from object.
r1559 class ui(object):
Matt Mackall
ui: refactor option setting...
r8136 def __init__(self, parentui=None):
Matt Mackall
add a simple nested buffering scheme to ui
r3737 self.buffers = []
Matt Mackall
ui: refactor option setting...
r8136 self.quiet = self.verbose = self.debugflag = self.traceback = False
self.interactive = self.report_untrusted = True
Matt Mackall
ui: introduce new config parser
r8144 self.overlay = config.config()
self.cdata = config.config()
self.ucdata = config.config()
Matt Mackall
ui: simplify init, kill dupconfig
r8143 self.parentui = None
self.trusted_users = {}
self.trusted_groups = {}
Matt Mackall
ui: refactor option setting...
r8136
Matt Mackall
ui: simplify init, kill dupconfig
r8143 if parentui:
self.parentui = parentui.parentui or parentui
Matt Mackall
ui: less links to parentui
r8187 self.cdata = self.parentui.cdata.copy()
self.ucdata = self.parentui.ucdata.copy()
self.overlay = parentui.overlay.copy()
Matt Mackall
ui: simplify init, kill dupconfig
r8143 self.trusted_users = parentui.trusted_users.copy()
self.trusted_groups = parentui.trusted_groups.copy()
Matt Mackall
ui: less links to parentui
r8187 self.buffers = parentui.buffers
Matt Mackall
ui: simplify init, kill dupconfig
r8143 self.fixconfig()
else:
Alexis S. L. Carvalho
Use a variable to explicitly trust global config files
r3676 # we always trust global config files
Matt Mackall
ui: fold readsections into readconfig...
r8142 for f in util.rcpath():
self.readconfig(f, assumetrusted=True)
Thomas Arendsen Hein
Create local ui object per repository, so .hg/hgrc don't get mixed....
r1839
Matt Mackall
ui: move _isatty near user
r8132 _isatty = None
Bryan O'Sullivan
ui: get readline and prompt to behave better depending on interactivity
r5036 def isatty(self):
if ui._isatty is None:
Matt Mackall
ui: refactor option setting...
r8136 try:
ui._isatty = sys.stdin.isatty()
except AttributeError: # not a real file object
ui._isatty = False
Benjamin Wohlwend
ui.isatty() accesses sys.stdin, causing mod_wsgi to throw IOError.
r8175 except IOError:
# access to stdin is unsafe in a WSGI environment
ui._isatty = False
Bryan O'Sullivan
ui: get readline and prompt to behave better depending on interactivity
r5036 return ui._isatty
Matt Mackall
ui: cleanup _is_trusted a bit
r8141 def _is_trusted(self, fp, f):
Alexis S. L. Carvalho
Avoid looking up usernames if the current user owns the .hgrc file...
r3677 st = util.fstat(fp)
if util.isowner(fp, st):
return True
Matt Mackall
ui: cleanup _is_trusted a bit
r8141
Alexis S. L. Carvalho
Only read .hg/hgrc files from trusted users/groups...
r3551 tusers = self.trusted_users
tgroups = self.trusted_groups
Matt Mackall
ui: cleanup _is_trusted a bit
r8141 if '*' in tusers or '*' in tgroups:
return True
user = util.username(st.st_uid)
group = util.groupname(st.st_gid)
if user in tusers or group in tgroups or user == util.username():
return True
if self.report_untrusted:
self.warn(_('Not trusting file %s from untrusted '
'user %s, group %s\n') % (f, user, group))
return False
Alexis S. L. Carvalho
Only read .hg/hgrc files from trusted users/groups...
r3551
Matt Mackall
ui: fold readsections into readconfig...
r8142 def readconfig(self, filename, root=None, assumetrusted=False,
sections = None):
try:
fp = open(filename)
except IOError:
if not sections: # ignore unless we were looking for something
return
raise
Matt Mackall
ui: always have ucdata...
r8139
Matt Mackall
ui: introduce new config parser
r8144 cdata = config.config()
Matt Mackall
ui: fold readsections into readconfig...
r8142 trusted = sections or assumetrusted or self._is_trusted(fp, filename)
Alexis S. L. Carvalho
save settings from untrusted config files in a separate configparser...
r3552
Matt Mackall
ui: fold readsections into readconfig...
r8142 try:
Matt Mackall
ui: introduce new config parser
r8144 cdata.read(filename, fp)
except error.ConfigError, inst:
Matt Mackall
ui: fold readsections into readconfig...
r8142 if trusted:
Matt Mackall
ui: introduce new config parser
r8144 raise
self.warn(_("Ignored: %s\n") % str(inst))
Alexis S. L. Carvalho
save settings from untrusted config files in a separate configparser...
r3552
Matt Mackall
ui: fold readsections into readconfig...
r8142 if trusted:
Matt Mackall
ui: introduce new config parser
r8144 self.cdata.update(cdata, sections)
self.cdata.update(self.overlay, sections)
self.ucdata.update(cdata, sections)
self.ucdata.update(self.overlay, sections)
Matt Mackall
ui: always have ucdata...
r8139
Alexis S. L. Carvalho
ui.py: normalize settings every time the configuration changes...
r3347 if root is None:
root = os.path.expanduser('~')
self.fixconfig(root=root)
Alexis S. L. Carvalho
load extensions only after the ui object has been completely initialized...
r3014
Alexis S. L. Carvalho
ui.py: normalize settings every time the configuration changes...
r3347 def fixconfig(self, section=None, name=None, value=None, root=None):
# translate paths relative to root (or home) into absolute paths
if section is None or section == 'paths':
if root is None:
root = os.getcwd()
items = section and [(name, value)] or []
Alexis S. L. Carvalho
save settings from untrusted config files in a separate configparser...
r3552 for cdata in self.cdata, self.ucdata, self.overlay:
Matt Mackall
ui: introduce new config parser
r8144 if not items and 'paths' in cdata:
Alexis S. L. Carvalho
ui.py: normalize settings every time the configuration changes...
r3347 pathsitems = cdata.items('paths')
else:
pathsitems = items
for n, path in pathsitems:
if path and "://" not in path and not os.path.isabs(path):
Jesse Glick
Ensure that absolutized paths from hgrc do not contain ../ segments.
r5943 cdata.set("paths", n,
os.path.normpath(os.path.join(root, path)))
Alexis S. L. Carvalho
ui.py: normalize settings every time the configuration changes...
r3347
Matt Mackall
ui: fold verbosity_constraints into fixconfig, simplify
r8138 # update ui options
Alexis S. L. Carvalho
update ui.quiet/verbose/debug/interactive every time the config changes...
r3350 if section is None or section == 'ui':
Matt Mackall
ui: fold verbosity_constraints into fixconfig, simplify
r8138 self.debugflag = self.configbool('ui', 'debug')
self.verbose = self.debugflag or self.configbool('ui', 'verbose')
self.quiet = not self.debugflag and self.configbool('ui', 'quiet')
if self.verbose and self.quiet:
self.quiet = self.verbose = False
self.report_untrusted = self.configbool("ui", "report_untrusted",
True)
self.interactive = self.configbool("ui", "interactive",
self.isatty())
Matt Mackall
ui: refactor option setting...
r8136 self.traceback = self.configbool('ui', 'traceback', False)
Alexis S. L. Carvalho
update ui.quiet/verbose/debug/interactive every time the config changes...
r3350
Alexis S. L. Carvalho
Only read .hg/hgrc files from trusted users/groups...
r3551 # update trust information
Matt Mackall
ui: cleanup _is_trusted a bit
r8141 if section is None or section == 'trusted':
Alexis S. L. Carvalho
Update trusted_users only after we've seen a file not owned by the user
r3678 for user in self.configlist('trusted', 'users'):
Alexis S. L. Carvalho
Only read .hg/hgrc files from trusted users/groups...
r3551 self.trusted_users[user] = 1
Alexis S. L. Carvalho
Update trusted_users only after we've seen a file not owned by the user
r3678 for group in self.configlist('trusted', 'groups'):
self.trusted_groups[group] = 1
Alexis S. L. Carvalho
Only read .hg/hgrc files from trusted users/groups...
r3551
Alexis S. L. Carvalho
ui.py: change the overlay from a dict to a SafeConfigParser....
r3344 def setconfig(self, section, name, value):
Alexis S. L. Carvalho
save settings from untrusted config files in a separate configparser...
r3552 for cdata in (self.overlay, self.cdata, self.ucdata):
Alexis S. L. Carvalho
ui.py: change the overlay from a dict to a SafeConfigParser....
r3344 cdata.set(section, name, value)
Alexis S. L. Carvalho
ui.py: normalize settings every time the configuration changes...
r3347 self.fixconfig(section, name, value)
mpm@selenic.com
Add ui.setconfig overlay...
r960
Alexis S. L. Carvalho
save settings from untrusted config files in a separate configparser...
r3552 def _get_cdata(self, untrusted):
Matt Mackall
ui: always have ucdata...
r8139 if untrusted:
Alexis S. L. Carvalho
save settings from untrusted config files in a separate configparser...
r3552 return self.ucdata
return self.cdata
Matt Mackall
showconfig: show source file and line with --debug
r8182 def configsource(self, section, name, untrusted=False):
return self._get_cdata(untrusted).getsource(section, name) or 'none'
Matt Mackall
ui: introduce new config parser
r8144 def config(self, section, name, default=None, untrusted=False):
value = self._get_cdata(untrusted).get(section, name, default)
Matt Mackall
ui: always have ucdata...
r8139 if self.debugflag and not untrusted:
Matt Mackall
ui: introduce new config parser
r8144 uvalue = self.ucdata.get(section, name)
Alexis S. L. Carvalho
save settings from untrusted config files in a separate configparser...
r3552 if uvalue is not None and uvalue != value:
self.warn(_("Ignoring untrusted configuration option "
"%s.%s = %s\n") % (section, name, uvalue))
return value
Alexis S. L. Carvalho
ui.py: move common code out of config and configbool
r3341
Alexis S. L. Carvalho
save settings from untrusted config files in a separate configparser...
r3552 def configbool(self, section, name, default=False, untrusted=False):
Matt Mackall
ui: introduce new config parser
r8144 v = self.config(section, name, None, untrusted)
if v == None:
return default
if v.lower() not in _booleans:
raise error.ConfigError(_("%s.%s not a boolean ('%s')")
% (section, name, v))
return _booleans[v.lower()]
Alexis S. L. Carvalho
save settings from untrusted config files in a separate configparser...
r3552
def configlist(self, section, name, default=None, untrusted=False):
Thomas Arendsen Hein
Added ui.configlist method to get comma/space separated lists of strings....
r2499 """Return a list of comma/space separated strings"""
Alexis S. L. Carvalho
save settings from untrusted config files in a separate configparser...
r3552 result = self.config(section, name, untrusted=untrusted)
Thomas Arendsen Hein
Added ui.configlist method to get comma/space separated lists of strings....
r2499 if result is None:
Thomas Arendsen Hein
Allow using default values with ui.configlist, too, and add a test for this.
r2502 result = default or []
if isinstance(result, basestring):
result = result.replace(",", " ").split()
return result
Thomas Arendsen Hein
Added ui.configlist method to get comma/space separated lists of strings....
r2499
Bryan O'Sullivan
ui: Rename has_config to has_section.
r4487 def has_section(self, section, untrusted=False):
Vadim Gelfer
add ui.has_config method.
r2343 '''tell whether section exists in config.'''
Matt Mackall
ui: introduce new config parser
r8144 return section in self._get_cdata(untrusted)
Alexis S. L. Carvalho
save settings from untrusted config files in a separate configparser...
r3552
def configitems(self, section, untrusted=False):
Matt Mackall
ui: introduce new config parser
r8144 items = self._get_cdata(untrusted).items(section)
Matt Mackall
ui: always have ucdata...
r8139 if self.debugflag and not untrusted:
Matt Mackall
ui: introduce new config parser
r8144 for k,v in self.ucdata.items(section):
if self.cdata.get(section, k) != v:
Alexis S. L. Carvalho
save settings from untrusted config files in a separate configparser...
r3552 self.warn(_("Ignoring untrusted configuration option "
Matt Mackall
ui: introduce new config parser
r8144 "%s.%s = %s\n") % (section, k, v))
return items
mpm@selenic.com
ui: add configuration file support...
r285
Alexis S. L. Carvalho
save settings from untrusted config files in a separate configparser...
r3552 def walkconfig(self, untrusted=False):
cdata = self._get_cdata(untrusted)
Matt Mackall
ui: introduce new config parser
r8144 for section in cdata.sections():
Alexis S. L. Carvalho
save settings from untrusted config files in a separate configparser...
r3552 for name, value in self.configitems(section, untrusted):
Alexis S. L. Carvalho
Fix hg showconfig traceback with values that aren't strings
r4085 yield section, name, str(value).replace('\n', '\\n')
Bryan O'Sullivan
Add commands.debugconfig....
r1028
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.
Benoit Boissinot
ui: add an option to prompt for the username when it isn't provided...
r6862 If not found and ui.askusername is True, ask the user, else use
($LOGNAME or $USER or $LNAME or $USERNAME) + "@full.hostname".
Thomas Arendsen Hein
Adapted behaviour of ui.username() to documentation and mention it explicitly:...
r1985 """
user = os.environ.get("HGUSER")
if user is None:
user = self.config("ui", "username")
if user is None:
user = os.environ.get("EMAIL")
Benoit Boissinot
ui: add an option to prompt for the username when it isn't provided...
r6862 if user is None and self.configbool("ui", "askusername"):
Martin Geisler
lowercase prompts...
r7600 user = self.prompt(_("enter a commit username:"), default=None)
Thomas Arendsen Hein
Abort on empty username so specifying a username can be forced....
r4044 if user is None:
Benoit Boissinot
only print a warning when no username is specified...
r3721 try:
user = '%s@%s' % (util.getuser(), socket.getfqdn())
Thomas Arendsen Hein
Abort on empty username so specifying a username can be forced....
r4044 self.warn(_("No username found, using '%s' instead\n") % user)
Benoit Boissinot
only print a warning when no username is specified...
r3721 except KeyError:
Thomas Arendsen Hein
Abort on empty username so specifying a username can be forced....
r4044 pass
if not user:
raise util.Abort(_("Please specify a username."))
Matt Mackall
ui: disallow newlines in usernames (issue1034)
r6351 if "\n" in user:
Benoit Boissinot
use repr() instead of backticks
r7470 raise util.Abort(_("username %s contains a newline\n") % repr(user))
Thomas Arendsen Hein
Adapted behaviour of ui.username() to documentation and mention it explicitly:...
r1985 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
Vadim Gelfer
push, outgoing, bundle: fall back to "default" if "default-push" not defined
r2494 def expandpath(self, loc, default=None):
Thomas Arendsen Hein
Directory names take precedence over symbolic names consistently....
r1892 """Return repository location relative to cwd or from [paths]"""
Thomas Arendsen Hein
Only hg repositories override [paths], not simple directories (fixes issue510)
r4216 if "://" in loc or os.path.isdir(os.path.join(loc, '.hg')):
Thomas Arendsen Hein
Directory names take precedence over symbolic names consistently....
r1892 return loc
Vadim Gelfer
make ui.expandpath better with default path.
r2495 path = self.config("paths", loc)
if not path and default is not None:
path = self.config("paths", default)
Thomas Arendsen Hein
Fix ui.expandpath problem and broken test introduced by 4a2a4d988ead.
r2498 return path or loc
mpm@selenic.com
[PATCH] Add ui.expandpath command...
r506
Matt Mackall
add a simple nested buffering scheme to ui
r3737 def pushbuffer(self):
self.buffers.append([])
def popbuffer(self):
return "".join(self.buffers.pop())
mpm@selenic.com
Move ui class to its own module...
r207 def write(self, *args):
Matt Mackall
add a simple nested buffering scheme to ui
r3737 if self.buffers:
self.buffers[-1].extend([str(a) for a in args])
else:
for a in args:
sys.stdout.write(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))
Patrick Mezard
Flush stderr after write....
r4023 # stderr may be buffered under win32 when redirected to files,
# including stdout.
if not sys.stderr.closed: sys.stderr.flush()
Benoit Boissinot
ignore EPIPE in ui.err_write...
r1989 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
Dirkjan Ochtman
Don't try to determine interactivity if ui() called with interactive=False....
r5337 def _readline(self, prompt=''):
Bryan O'Sullivan
ui: get readline and prompt to behave better depending on interactivity
r5036 if self.isatty():
try:
# magically add command line editing support, where
# available
import readline
# force demandimport to really load the module
readline.read_history_file
Brendan Cully
issue1419: catch strange readline import error on windows
r7496 # windows sometimes raises something other than ImportError
except Exception:
Bryan O'Sullivan
ui: get readline and prompt to behave better depending on interactivity
r5036 pass
Steve Borho
workaround for raw_input() on Windows...
r5613 line = raw_input(prompt)
# When stdin is in binary mode on Windows, it can cause
# raw_input() to emit an extra trailing carriage return
if os.linesep == '\r\n' and line and line[-1] == '\r':
line = line[:-1]
return line
Bryan O'Sullivan
ui: get readline and prompt to behave better depending on interactivity
r5036
Kirill Smelkov
prompt: kill matchflags...
r5751 def prompt(self, msg, pat=None, default="y"):
"""Prompt user with msg, read response, and ensure it matches pat
If not interactive -- the default is returned
"""
Peter Arrenbrecht
ui: log non-interactive default response to stdout when verbose...
r7320 if not self.interactive:
self.note(msg, ' ', default, "\n")
return default
Thomas Arendsen Hein
Make ui.prompt repeat on "unrecognized response" again (issue897)...
r5671 while True:
try:
r = self._readline(msg + ' ')
Matt Mackall
ui: allow default when prompting
r5709 if not r:
return default
Kirill Smelkov
prompt: kill matchflags...
r5751 if not pat or re.match(pat, r):
Thomas Arendsen Hein
Make ui.prompt repeat on "unrecognized response" again (issue897)...
r5671 return r
else:
self.write(_("unrecognized response\n"))
except EOFError:
raise util.Abort(_('response expected'))
Bryan O'Sullivan
ui: get readline and prompt to behave better depending on interactivity
r5036
Vadim Gelfer
prompt user for http authentication info...
r2281 def getpass(self, prompt=None, default=None):
if not self.interactive: return default
Steve Borho
catch CTRL-D at password prompt...
r7798 try:
return getpass.getpass(prompt or _('password: '))
except EOFError:
raise util.Abort(_('response expected'))
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()
Osku Salerma
Use VISUAL in addition to EDITOR when choosing the editor to use.
r5660 editor = self.geteditor()
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
Vadim Gelfer
add ui.print_exc(), make all traceback printing central.
r2335 def print_exc(self):
'''print exception traceback if traceback printing enabled.
only to call in exception handler. returns true if traceback
printed.'''
if self.traceback:
traceback.print_exc()
return self.traceback
Osku Salerma
Use VISUAL in addition to EDITOR when choosing the editor to use.
r5660
def geteditor(self):
'''return editor to use'''
return (os.environ.get("HGEDITOR") or
self.config("ui", "editor") or
os.environ.get("VISUAL") or
os.environ.get("EDITOR", "vi"))