Mercurial > public > mercurial-scm > hg-stable
diff mercurial/dispatch.py @ 16744:1c9f58a6c8f1
dispatch: try and identify third-party extensions as sources of tracebacks
Extension authors should explicitly declare their supported hg
versions and include a buglink attribute in their extension. In the
event that a traceback occurs, we'll identify the
least-recently-tested extensionas the most likely source of the defect
and suggest the user disable that extension.
Packagers should make every effort to ship hg versions from exact
tags, or with as few modifications as possible so that the versioning
can work appropriately.
author | Augie Fackler <raf@durin42.com> |
---|---|
date | Wed, 16 May 2012 16:18:07 -0500 |
parents | c2d9ef43ff6c |
children | 0a0cf3f26938 |
line wrap: on
line diff
--- a/mercurial/dispatch.py Tue May 15 14:37:49 2012 -0500 +++ b/mercurial/dispatch.py Wed May 16 16:18:07 2012 -0500 @@ -205,18 +205,56 @@ except socket.error, inst: ui.warn(_("abort: %s\n") % inst.args[-1]) except: # re-raises - ui.warn(_("** unknown exception encountered," - " please report by visiting\n")) - ui.warn(_("** http://mercurial.selenic.com/wiki/BugTracker\n")) - ui.warn(_("** Python %s\n") % sys.version.replace('\n', '')) - ui.warn(_("** Mercurial Distributed SCM (version %s)\n") - % util.version()) - ui.warn(_("** Extensions loaded: %s\n") - % ", ".join([x[0] for x in extensions.extensions()])) + myver = util.version() + # For compatibility checking, we discard the portion of the hg + # version after the + on the assumption that if a "normal + # user" is running a build with a + in it the packager + # probably built from fairly close to a tag and anyone with a + # 'make local' copy of hg (where the version number can be out + # of date) will be clueful enough to notice the implausible + # version number and try updating. + compare = myver.split('+')[0] + ct = tuplever(compare) + worst = None, ct, '' + for name, mod in extensions.extensions(): + testedwith = getattr(mod, 'testedwith', 'unknown') + report = getattr(mod, 'buglink', _('the extension author.')) + if testedwith == 'unknown': + # We found an untested extension. It's likely the culprit. + worst = name, testedwith, report + break + if compare not in testedwith.split() and testedwith != 'internal': + tested = [tuplever(v) for v in testedwith.split()] + nearest = max([t for t in tested if t < ct]) + if nearest < worst[1]: + worst = name, nearest, report + if worst[0] is not None: + name, testedwith, report = worst + if not isinstance(testedwith, str): + testedwith = '.'.join([str(c) for c in testedwith]) + warning = (_('** Unknown exception encountered with ' + 'possibly-broken third-party extension %s\n' + '** which supports versions %s of Mercurial.\n' + '** Please disable %s and try your action again.\n' + '** If that fixes the bug please report it to %s\n') + % (name, testedwith, name, report)) + else: + warning = (_("** unknown exception encountered, " + "please report by visiting\n") + + _("** http://mercurial.selenic.com/wiki/BugTracker\n")) + warning += ((_("** Python %s\n") % sys.version.replace('\n', '')) + + (_("** Mercurial Distributed SCM (version %s)\n") % myver) + + (_("** Extensions loaded: %s\n") % + ", ".join([x[0] for x in extensions.extensions()]))) + ui.warn(warning) raise return -1 +def tuplever(v): + return tuple([int(i) for i in v.split('.')]) + + def aliasargs(fn, givenargs): args = getattr(fn, 'args', []) if args: