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 109294 a7619ca2db7e5e6a51f65a88387786c9b8583048
parent 109293 a119cc1cdf0a728990df7c17dcba3e1ca28ae45d
child 109295 c24a0fd080310af8028084c89cfdf1052a58d38b
push id15953
push userryanvm@gmail.com
push dateFri, 05 Oct 2012 02:18:14 +0000
treeherdermozilla-inbound@d750568367fe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjhammel
bugs795427
milestone18.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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.