Mercurial > hg
changeset 3351:04fa31a43b93
merge with crew
author | Benoit Boissinot <benoit.boissinot@ens-lyon.org> |
---|---|
date | Wed, 11 Oct 2006 23:31:05 +0200 |
parents | ab900698b832 (diff) b02e60097bbe (current diff) |
children | 69fe021cc23e 2edf53386d86 |
files | |
diffstat | 7 files changed, 233 insertions(+), 97 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/commands.py Wed Oct 11 13:56:35 2006 -0700 +++ b/mercurial/commands.py Wed Oct 11 23:31:05 2006 +0200 @@ -2463,7 +2463,7 @@ " accesslog errorlog webdir_conf") for o in optlist.split(): if opts[o]: - ui.setconfig("web", o, opts[o]) + ui.setconfig("web", o, str(opts[o])) if repo is None and not ui.config("web", "webdir_conf"): raise hg.RepoError(_("There is no Mercurial repository here" @@ -3275,6 +3275,20 @@ ui.warn(_("module %s overrides %s\n") % (name, t)) table.update(cmdtable) +def parseconfig(config): + """parse the --config options from the command line""" + parsed = [] + for cfg in config: + try: + name, value = cfg.split('=', 1) + section, name = name.split('.', 1) + if not section or not name: + raise IndexError + parsed.append((section, name, value)) + except (IndexError, ValueError): + raise util.Abort(_('malformed --config option: %s') % cfg) + return parsed + def dispatch(args): for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM': num = getattr(signal, name, None) @@ -3304,10 +3318,6 @@ (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3])) atexit.register(print_time) - u.updateopts(options["verbose"], options["debug"], options["quiet"], - not options["noninteractive"], options["traceback"], - options["config"]) - # enter the debugger before command execution if options['debugger']: pdb.set_trace() @@ -3320,6 +3330,10 @@ raise util.Abort('%s: %s' % (options['cwd'], inst.strerror)) + u.updateopts(options["verbose"], options["debug"], options["quiet"], + not options["noninteractive"], options["traceback"], + parseconfig(options["config"])) + path = u.expandpath(options["repository"]) or "" repo = path and hg.repository(u, path=path) or None if repo and not repo.local(): @@ -3349,11 +3363,6 @@ else: d = lambda: func(u, *args, **cmdoptions) - # reupdate the options, repo/.hg/hgrc may have changed them - u.updateopts(options["verbose"], options["debug"], options["quiet"], - not options["noninteractive"], options["traceback"], - options["config"]) - try: if options['profile']: import hotshot, hotshot.stats
--- a/mercurial/localrepo.py Wed Oct 11 13:56:35 2006 -0700 +++ b/mercurial/localrepo.py Wed Oct 11 23:31:05 2006 +0200 @@ -54,7 +54,7 @@ except IOError: pass - v = self.ui.revlogopts + v = self.ui.configrevlog() self.revlogversion = int(v.get('format', revlog.REVLOG_DEFAULT_FORMAT)) self.revlogv1 = self.revlogversion != revlog.REVLOGV0 fl = v.get('flags', None)
--- a/mercurial/ui.py Wed Oct 11 13:56:35 2006 -0700 +++ b/mercurial/ui.py Wed Oct 11 23:31:05 2006 +0200 @@ -10,61 +10,75 @@ demandload(globals(), "errno getpass os re socket sys tempfile") demandload(globals(), "ConfigParser mdiff templater traceback util") +def dupconfig(orig): + new = ConfigParser.SafeConfigParser(orig.defaults()) + updateconfig(orig, new) + return new + +def updateconfig(source, dest): + for section in source.sections(): + if not dest.has_section(section): + dest.add_section(section) + for name, value in source.items(section, raw=True): + dest.set(section, name, value) + class ui(object): def __init__(self, verbose=False, debug=False, quiet=False, interactive=True, traceback=False, parentui=None): - self.overlay = {} + self.overlay = None + self.header = [] + self.prev_header = [] if parentui is None: # this is the parent of all ui children self.parentui = None self.readhooks = [] + self.quiet = quiet + self.verbose = verbose + self.debugflag = debug + self.interactive = interactive + self.traceback = traceback self.cdata = ConfigParser.SafeConfigParser() self.readconfig(util.rcpath()) - - 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) - self.traceback = traceback - self.updateopts(verbose, debug, quiet, interactive) - self.diffcache = None - self.header = [] - self.prev_header = [] - self.revlogopts = self.configrevlog() else: # parentui may point to an ui object which is already a child self.parentui = parentui.parentui or parentui - self.readhooks = parentui.readhooks[:] - 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) + self.readhooks = self.parentui.readhooks[:] + self.cdata = dupconfig(self.parentui.cdata) + if self.parentui.overlay: + self.overlay = dupconfig(self.parentui.overlay) def __getattr__(self, key): return getattr(self.parentui, key) def updateopts(self, verbose=False, debug=False, quiet=False, interactive=True, traceback=False, config=[]): - self.quiet = (self.quiet or quiet) and not verbose and not debug - self.verbose = ((self.verbose or verbose) or debug) and not self.quiet - self.debugflag = (self.debugflag or debug) - self.interactive = (self.interactive and interactive) + for section, name, value in config: + self.setconfig(section, name, value) + + if quiet or verbose or debug: + self.setconfig('ui', 'quiet', str(bool(quiet))) + self.setconfig('ui', 'verbose', str(bool(verbose))) + self.setconfig('ui', 'debug', str(bool(debug))) + + self.verbosity_constraints() + + if not interactive: + self.setconfig('ui', 'interactive', 'False') + self.interactive = False + self.traceback = self.traceback or traceback - for cfg in config: - try: - name, value = cfg.split('=', 1) - section, name = name.split('.', 1) - if not self.cdata.has_section(section): - self.cdata.add_section(section) - if not section or not name: - raise IndexError - self.cdata.set(section, name, value) - except (IndexError, ValueError): - raise util.Abort(_('malformed --config option: %s') % cfg) + + def verbosity_constraints(self): + self.quiet = self.configbool('ui', 'quiet') + self.verbose = self.configbool('ui', 'verbose') + self.debugflag = self.configbool('ui', 'debug') + + if self.debugflag: + self.verbose = True + self.quiet = False + elif self.verbose and self.quiet: + self.quiet = self.verbose = False def readconfig(self, fn, root=None): if isinstance(fn, basestring): @@ -74,35 +88,67 @@ self.cdata.read(f) except ConfigParser.ParsingError, inst: raise util.Abort(_("Failed to parse %s\n%s") % (f, inst)) - # translate paths relative to root (or home) into absolute paths + # override data from config files with data set with ui.setconfig + if self.overlay: + updateconfig(self.overlay, self.cdata) if root is None: root = os.path.expanduser('~') - for name, path in self.configitems("paths"): - if path and "://" not in path and not os.path.isabs(path): - self.cdata.set("paths", name, os.path.join(root, path)) + self.fixconfig(root=root) for hook in self.readhooks: hook(self) def addreadhook(self, hook): self.readhooks.append(hook) - def setconfig(self, section, name, val): - self.overlay[(section, name)] = val + 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 [] + for cdata in self.cdata, self.overlay: + if not cdata: continue + if not items and cdata.has_section('paths'): + pathsitems = cdata.items('paths') + else: + pathsitems = items + for n, path in pathsitems: + if path and "://" not in path and not os.path.isabs(path): + cdata.set("paths", n, os.path.join(root, path)) - def config(self, section, name, default=None): - if self.overlay.has_key((section, name)): - return self.overlay[(section, name)] + # update quiet/verbose/debug and interactive status + if section is None or section == 'ui': + if name is None or name in ('quiet', 'verbose', 'debug'): + self.verbosity_constraints() + + if name is None or name == 'interactive': + self.interactive = self.configbool("ui", "interactive", True) + + def setconfig(self, section, name, value): + if not self.overlay: + self.overlay = ConfigParser.SafeConfigParser() + for cdata in (self.overlay, self.cdata): + if not cdata.has_section(section): + cdata.add_section(section) + cdata.set(section, name, value) + self.fixconfig(section, name, value) + + def _config(self, section, name, default, funcname): if self.cdata.has_option(section, name): try: - return self.cdata.get(section, name) + func = getattr(self.cdata, funcname) + return func(section, name) except ConfigParser.InterpolationError, inst: raise util.Abort(_("Error in configuration section [%s] " "parameter '%s':\n%s") % (section, name, inst)) - if self.parentui is None: - return default - else: - return self.parentui.config(section, name, default) + return default + + def config(self, section, name, default=None): + return self._config(section, name, default, 'get') + + def configbool(self, section, name, default=False): + return self._config(section, name, default, 'getboolean') def configlist(self, section, name, default=None): """Return a list of comma/space separated strings""" @@ -113,29 +159,12 @@ result = result.replace(",", " ").split() return result - 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): - try: - return self.cdata.getboolean(section, name) - except ConfigParser.InterpolationError, inst: - raise util.Abort(_("Error in configuration section [%s] " - "parameter '%s':\n%s") - % (section, name, inst)) - if self.parentui is None: - return default - else: - return self.parentui.configbool(section, name, default) - def has_config(self, section): '''tell whether section exists in config.''' return self.cdata.has_section(section) def configitems(self, section): items = {} - if self.parentui is not None: - items = dict(self.parentui.configitems(section)) if self.cdata.has_section(section): try: items.update(dict(self.cdata.items(section))) @@ -146,24 +175,12 @@ x.sort() return x - def walkconfig(self, seen=None): - if seen is None: - seen = {} - for (section, name), value in self.overlay.iteritems(): - yield section, name, value - seen[section, name] = 1 - for section in self.cdata.sections(): - try: - 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 - except ConfigParser.InterpolationError, inst: - raise util.Abort(_("Error in configuration section [%s]:\n%s") - % (section, inst)) - if self.parentui is not None: - for parent in self.parentui.walkconfig(seen): - yield parent + def walkconfig(self): + sections = self.cdata.sections() + sections.sort() + for section in sections: + for name, value in self.configitems(section): + yield section, name, value.replace('\n', '\\n') def extensions(self): result = self.configitems("extensions")
--- a/tests/test-globalopts.out Wed Oct 11 13:56:35 2006 -0700 +++ b/tests/test-globalopts.out Wed Oct 11 23:31:05 2006 +0200 @@ -105,6 +105,7 @@ %% --traceback +Traceback (most recent call last): %% --time Time: real x.x secs (user x.x+x.x sys x.x+x.x) %% --version
--- a/tests/test-ui-config Wed Oct 11 13:56:35 2006 -0700 +++ b/tests/test-ui-config Wed Oct 11 23:31:05 2006 +0200 @@ -1,9 +1,9 @@ #!/usr/bin/env python -from mercurial import ui, util +from mercurial import ui, util, commands testui = ui.ui() -testui.updateopts(config=[ +parsed = commands.parseconfig([ 'values.string=string value', 'values.bool1=true', 'values.bool2=false', @@ -17,6 +17,7 @@ 'interpolation.value4=%(bad)1', 'interpolation.value5=%bad2', ]) +testui.updateopts(config=parsed) print repr(testui.configitems('values')) print repr(testui.configitems('lists'))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-ui-verbosity Wed Oct 11 23:31:05 2006 +0200 @@ -0,0 +1,42 @@ +#!/usr/bin/env python + +import os +from mercurial import ui + +hgrc = os.environ['HGRCPATH'] + +print ' hgrc settings command line options final result ' +print ' quiet verbo debug quiet verbo debug quiet verbo debug' + +for i in xrange(64): + hgrc_quiet = bool(i & 1<<0) + hgrc_verbose = bool(i & 1<<1) + hgrc_debug = bool(i & 1<<2) + cmd_quiet = bool(i & 1<<3) + cmd_verbose = bool(i & 1<<4) + cmd_debug = bool(i & 1<<5) + + f = open(hgrc, 'w') + f.write('[ui]\n') + if hgrc_quiet: + f.write('quiet = True\n') + if hgrc_verbose: + f.write('verbose = True\n') + if hgrc_debug: + f.write('debug = True\n') + f.close() + + u = ui.ui() + u.updateopts(quiet=cmd_quiet, verbose=cmd_verbose, debug=cmd_debug) + + check = '' + if u.debugflag: + if not u.verbose or u.quiet: + check = ' *' + elif u.verbose and u.quiet: + check = ' +' + + print ('%2d %5s %5s %5s %5s %5s %5s -> %5s %5s %5s%s' + % (i, hgrc_quiet, hgrc_verbose, hgrc_debug, + cmd_quiet, cmd_verbose, cmd_debug, + u.quiet, u.verbose, u.debugflag, check))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-ui-verbosity.out Wed Oct 11 23:31:05 2006 +0200 @@ -0,0 +1,66 @@ + hgrc settings command line options final result + quiet verbo debug quiet verbo debug quiet verbo debug + 0 False False False False False False -> False False False + 1 True False False False False False -> True False False + 2 False True False False False False -> False True False + 3 True True False False False False -> False False False + 4 False False True False False False -> False True True + 5 True False True False False False -> False True True + 6 False True True False False False -> False True True + 7 True True True False False False -> False True True + 8 False False False True False False -> True False False + 9 True False False True False False -> True False False +10 False True False True False False -> True False False +11 True True False True False False -> True False False +12 False False True True False False -> True False False +13 True False True True False False -> True False False +14 False True True True False False -> True False False +15 True True True True False False -> True False False +16 False False False False True False -> False True False +17 True False False False True False -> False True False +18 False True False False True False -> False True False +19 True True False False True False -> False True False +20 False False True False True False -> False True False +21 True False True False True False -> False True False +22 False True True False True False -> False True False +23 True True True False True False -> False True False +24 False False False True True False -> False False False +25 True False False True True False -> False False False +26 False True False True True False -> False False False +27 True True False True True False -> False False False +28 False False True True True False -> False False False +29 True False True True True False -> False False False +30 False True True True True False -> False False False +31 True True True True True False -> False False False +32 False False False False False True -> False True True +33 True False False False False True -> False True True +34 False True False False False True -> False True True +35 True True False False False True -> False True True +36 False False True False False True -> False True True +37 True False True False False True -> False True True +38 False True True False False True -> False True True +39 True True True False False True -> False True True +40 False False False True False True -> False True True +41 True False False True False True -> False True True +42 False True False True False True -> False True True +43 True True False True False True -> False True True +44 False False True True False True -> False True True +45 True False True True False True -> False True True +46 False True True True False True -> False True True +47 True True True True False True -> False True True +48 False False False False True True -> False True True +49 True False False False True True -> False True True +50 False True False False True True -> False True True +51 True True False False True True -> False True True +52 False False True False True True -> False True True +53 True False True False True True -> False True True +54 False True True False True True -> False True True +55 True True True False True True -> False True True +56 False False False True True True -> False True True +57 True False False True True True -> False True True +58 False True False True True True -> False True True +59 True True False True True True -> False True True +60 False False True True True True -> False True True +61 True False True True True True -> False True True +62 False True True True True True -> False True True +63 True True True True True True -> False True True