Bug 795427 - Part 1: Proper exit codes from mach; r=jhammel
authorGregory Szorc <gps@mozilla.com>
Thu, 04 Oct 2012 17:43:54 -0700
changeset 109265 a7619ca2db7e5e6a51f65a88387786c9b8583048
parent 109264 a119cc1cdf0a728990df7c17dcba3e1ca28ae45d
child 109266 c24a0fd080310af8028084c89cfdf1052a58d38b
push id1145
push userpastithas@mozilla.com
push dateMon, 08 Oct 2012 14:21:16 +0000
treeherderfx-team@e7f2e2c944b7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjhammel
bugs795427
milestone18.0a1
Bug 795427 - Part 1: Proper exit codes from mach; r=jhammel
mach
python/mach/mach/main.py
--- a/mach
+++ b/mach
@@ -40,9 +40,9 @@ try:
 except ImportError:
     SEARCH_PATHS.reverse()
     sys.path[0:0] = [os.path.join(our_dir, path) for path in SEARCH_PATHS]
 
     import mach.main
 
 # All of the code is in a module because EVERYTHING IS A LIBRARY.
 mach = mach.main.Mach(our_dir)
-mach.run(sys.argv[1:])
+sys.exit(mach.run(sys.argv[1:]))
--- a/python/mach/mach/main.py
+++ b/python/mach/mach/main.py
@@ -117,17 +117,21 @@ To see more help for a specific command,
         self.cwd = cwd
         self.log_manager = LoggingManager()
         self.logger = logging.getLogger(__name__)
         self.settings = ConfigSettings()
 
         self.log_manager.register_structured_logger(self.logger)
 
     def run(self, argv):
-        """Runs mach with arguments provided from the command line."""
+        """Runs mach with arguments provided from the command line.
+
+        Returns the integer exit code that should be used. 0 means success. All
+        other values indicate failure.
+        """
 
         # If no encoding is defined, we default to UTF-8 because without this
         # Python 2.7 will assume the default encoding of ASCII. This will blow
         # up with UnicodeEncodeError as soon as it encounters a non-ASCII
         # character in a unicode instance. We simply install a wrapper around
         # the streams and restore once we have finished.
         orig_stdin = sys.stdin
         orig_stdout = sys.stdout
@@ -138,17 +142,17 @@ To see more help for a specific command,
                 sys.stdin = codecs.getreader('utf-8')(sys.stdin)
 
             if sys.stdout.encoding is None:
                 sys.stdout = codecs.getwriter('utf-8')(sys.stdout)
 
             if sys.stderr.encoding is None:
                 sys.stderr = codecs.getwriter('utf-8')(sys.stderr)
 
-            self._run(argv)
+            return self._run(argv)
         finally:
             sys.stdin = orig_stdin
             sys.stdout = orig_stdout
             sys.stderr = orig_stderr
 
     def _run(self, argv):
         parser = self.get_argument_parser()
 
@@ -194,17 +198,24 @@ To see more help for a specific command,
             fn = getattr(instance, getattr(args, 'method'))
 
         # If the command is associated with a function, call it.
         elif hasattr(args, 'func'):
             fn = getattr(args, 'func')
         else:
             raise Exception('Dispatch configuration error in module.')
 
-        fn(**stripped)
+        result = fn(**stripped)
+
+        if not result:
+            result = 0
+
+        assert isinstance(result, int)
+
+        return result
 
     def log(self, level, action, params, format_str):
         """Helper method to record a structured log event."""
         self.logger.log(level, format_str,
             extra={'action': action, 'params': params})
 
     def load_settings(self, args):
         """Determine which settings files apply and load them.