changeset 2057:fef2d653beaf

Never exit directly from commands.dispatch(), but pass return code to caller. Usually the caller is commands.run(). Some extensions still use sys.exit(), this is catched, too. Fixed wrong return statement in commands.recover() yielding a zero exit code.
author Thomas Arendsen Hein <thomas@intevation.de>
date Tue, 11 Apr 2006 08:42:07 +0200
parents 1f6d520557ec
children 7e0dd64b0718
files mercurial/commands.py tests/test-clone-failure.out
diffstat 2 files changed, 28 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/commands.py	Tue Apr 11 07:08:16 2006 +0200
+++ b/mercurial/commands.py	Tue Apr 11 08:42:07 2006 +0200
@@ -2258,7 +2258,7 @@
     """
     if repo.recover():
         return repo.verify()
-    return False
+    return 1
 
 def remove(ui, repo, pat, *pats, **opts):
     """remove the specified files on the next commit
@@ -3258,38 +3258,32 @@
         u = ui.ui()
     except util.Abort, inst:
         sys.stderr.write(_("abort: %s\n") % inst)
-        sys.exit(1)
+        return -1
 
     external = []
     for x in u.extensions():
-        def on_exception(exc, inst):
-            u.warn(_("*** failed to import extension %s: %s\n") % (x[0], inst))
-            if "--traceback" in sys.argv[1:]:
-                traceback.print_exc()
-                sys.exit(0)
-        if x[1]:
-            try:
+        try:
+            if x[1]:
                 mod = imp.load_source(x[0], x[1])
-            except Exception, inst:
-                on_exception(Exception, inst)
-                continue
-        else:
-            def importh(name):
-                mod = __import__(name)
-                components = name.split('.')
-                for comp in components[1:]:
-                    mod = getattr(mod, comp)
-                return mod
-            try:
+            else:
+                def importh(name):
+                    mod = __import__(name)
+                    components = name.split('.')
+                    for comp in components[1:]:
+                        mod = getattr(mod, comp)
+                    return mod
                 try:
                     mod = importh("hgext." + x[0])
                 except ImportError:
                     mod = importh(x[0])
-            except Exception, inst:
-                on_exception(Exception, inst)
-                continue
-
-        external.append(mod)
+            external.append(mod)
+        except Exception, inst:
+            u.warn(_("*** failed to import extension %s: %s\n") % (x[0], inst))
+            if "--traceback" in sys.argv[1:]:
+                traceback.print_exc()
+                return 1
+            continue
+
     for x in external:
         cmdtable = getattr(x, 'cmdtable', {})
         for t in cmdtable:
@@ -3331,14 +3325,11 @@
             repo = path and hg.repository(u, path=path) or None
 
             if options['help']:
-                help_(u, cmd, options['version'])
-                sys.exit(0)
+                return help_(u, cmd, options['version'])
             elif options['version']:
-                show_version(u)
-                sys.exit(0)
+                return show_version(u)
             elif not cmd:
-                help_(u, 'shortlist')
-                sys.exit(0)
+                return help_(u, 'shortlist')
 
             if cmd not in norepo.split():
                 try:
@@ -3393,15 +3384,12 @@
         else:
             u.warn(_("hg: %s\n") % inst.args[1])
             help_(u, 'shortlist')
-        sys.exit(-1)
     except AmbiguousCommand, inst:
         u.warn(_("hg: command '%s' is ambiguous:\n    %s\n") %
                 (inst.args[0], " ".join(inst.args[1])))
-        sys.exit(1)
     except UnknownCommand, inst:
         u.warn(_("hg: unknown command '%s'\n") % inst.args[0])
         help_(u, 'shortlist')
-        sys.exit(1)
     except hg.RepoError, inst:
         u.warn(_("abort: "), inst, "!\n")
     except lock.LockHeld, inst:
@@ -3448,7 +3436,6 @@
             u.warn(_("abort: %s\n") % inst.strerror)
     except util.Abort, inst:
         u.warn(_('abort: '), inst.args[0] % inst.args[1:], '\n')
-        sys.exit(1)
     except TypeError, inst:
         # was this an argument error?
         tb = traceback.extract_tb(sys.exc_info()[2])
@@ -3457,9 +3444,10 @@
         u.debug(inst, "\n")
         u.warn(_("%s: invalid arguments\n") % cmd)
         help_(u, cmd)
-    except SystemExit:
-        # don't catch this in the catch-all below
-        raise
+    except SystemExit, inst:
+        # Commands shouldn't sys.exit directly, but give a return code.
+        # Just in case catch this and and pass exit code to caller.
+        return inst.code
     except:
         u.warn(_("** unknown exception encountered, details follow\n"))
         u.warn(_("** report bug details to mercurial@selenic.com\n"))
@@ -3467,4 +3455,4 @@
                % version.get_version())
         raise
 
-    sys.exit(-1)
+    return -1
--- a/tests/test-clone-failure.out	Tue Apr 11 07:08:16 2006 +0200
+++ b/tests/test-clone-failure.out	Tue Apr 11 08:42:07 2006 +0200
@@ -6,7 +6,7 @@
 abort: repository a not found!
 255
 abort: destination '../a' already exists
-1
+255
 abort: repository a not found!
 255
 abort: destination 'q' already exists