Bug 1257516 - Make check_prog opt-in to the queued debug log messages. r=ted
authorMike Hommey <mh+mozilla@glandium.org>
Fri, 25 Mar 2016 20:03:19 +0900
changeset 290980 7640e60c144a8a954ed06a168d1bc7c2550cf3ef
parent 290979 9bcbc8d381e45de860c4037af1936c4fe4911030
child 290981 23b31c46e2117f80b78e6033fb5f1dee3a222965
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersted
bugs1257516
milestone48.0a1
Bug 1257516 - Make check_prog opt-in to the queued debug log messages. r=ted
build/moz.configure/checks.configure
python/mozbuild/mozbuild/test/configure/test_checks_configure.py
--- a/build/moz.configure/checks.configure
+++ b/build/moz.configure/checks.configure
@@ -1,15 +1,34 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 # Templates implementing some generic checks.
+# ==============================================================
+
+# Declare some exceptions. This is cumbersome, but since we shouldn't need a
+# lot of them, let's stack them all here. When adding a new one, put it in the
+# _declare_exceptions template, and add it to the return statement. Then
+# destructure in the assignment below the function declaration.
+@template
+@advanced
+def _declare_exceptions():
+    class FatalCheckError(Exception):
+        '''An exception to throw from a function decorated with @checking.
+        It will result in calling die() with the given message.
+        Debugging messages emitted from the decorated function will also be
+        printed out.'''
+    return (FatalCheckError,)
+
+(FatalCheckError,) = _declare_exceptions()
+
+del _declare_exceptions
 
 # Helper to display "checking" messages
 #   @checking('for foo')
 #   def foo():
 #       return 'foo'
 # is equivalent to:
 #   def foo():
 #       log.info('checking for foo... ')
@@ -23,25 +42,32 @@
 #       ...
 # An optional callback can be given, that will be used to format the returned
 # value when displaying it.
 @template
 def checking(what, callback=None):
     def decorator(func):
         def wrapped(*args, **kwargs):
             log.info('checking %s... ', what)
-            ret = func(*args, **kwargs)
-            if callback:
-                log.info(callback(ret))
-            elif ret is True:
-                log.info('yes')
-            elif ret is False:
-                log.info('no')
-            else:
-                log.info(ret)
+            with log.queue_debug():
+                error, ret = None, None
+                try:
+                    ret = func(*args, **kwargs)
+                except FatalCheckError as e:
+                    error = e.message
+                if callback:
+                    log.info(callback(ret))
+                elif ret is True:
+                    log.info('yes')
+                elif ret is False:
+                    log.info('no')
+                else:
+                    log.info(ret)
+                if error:
+                    die(error)
             return ret
         return wrapped
     return decorator
 
 
 # Template to check for programs in $PATH.
 #   check('PROG', ('a', 'b'))
 # will look for 'a' or 'b' in $PATH, and set_config PROG to the one
@@ -59,25 +85,23 @@ def check_prog(var, progs, allow_missing
     progs = list(progs)
 
     @depends(var)
     @checking('for %s' % var.lower(), lambda x: quote(x) if x else 'not found')
     def check(value):
         if value:
             progs[:] = value
         for prog in progs:
+            log.debug('%s: Trying %s', var.lower(), quote(prog))
             result = find_program(prog)
             if result:
                 return result
 
-    @depends(check, var)
-    def postcheck(value, raw_value):
-        if value is None and (not allow_missing or raw_value):
-            die('Cannot find %s (tried: %s)', var.lower(),
-                ', '.join(quote(p) for p in progs))
+        if not allow_missing or value:
+            raise FatalCheckError('Cannot find %s' % var.lower())
 
     @depends(check)
     def normalized_for_config(value):
         return ':' if value is None else value
 
     set_config(var, normalized_for_config)
 
     return check
--- a/python/mozbuild/mozbuild/test/configure/test_checks_configure.py
+++ b/python/mozbuild/mozbuild/test/configure/test_checks_configure.py
@@ -87,25 +87,28 @@ class TestChecksConfigure(unittest.TestC
         self.assertEqual(config, {'FOO': '/home/user/bin/known c'})
         self.assertEqual(out, "checking for foo... '/home/user/bin/known c'\n")
 
         config, out, status = self.get_result(
             'check_prog("FOO", ("unknown",))')
         self.assertEqual(status, 1)
         self.assertEqual(config, {})
         self.assertEqual(out, 'checking for foo... not found\n'
-                              'ERROR: Cannot find foo (tried: unknown)\n')
+                              'DEBUG: foo: Trying unknown\n'
+                              'ERROR: Cannot find foo\n')
 
         config, out, status = self.get_result(
             'check_prog("FOO", ("unknown", "unknown-2", "unknown 3"))')
         self.assertEqual(status, 1)
         self.assertEqual(config, {})
         self.assertEqual(out, 'checking for foo... not found\n'
-                              'ERROR: Cannot find foo '
-                              "(tried: unknown, unknown-2, 'unknown 3')\n")
+                              'DEBUG: foo: Trying unknown\n'
+                              'DEBUG: foo: Trying unknown-2\n'
+                              "DEBUG: foo: Trying 'unknown 3'\n"
+                              'ERROR: Cannot find foo\n')
 
         config, out, status = self.get_result(
             'check_prog("FOO", ("unknown", "unknown-2", "unknown 3"), '
             'allow_missing=True)')
         self.assertEqual(status, 0)
         self.assertEqual(config, {'FOO': ':'})
         self.assertEqual(out, 'checking for foo... not found\n')
 
@@ -125,33 +128,34 @@ class TestChecksConfigure(unittest.TestC
         self.assertEqual(out, 'checking for foo... /usr/bin/known-a\n')
 
         config, out, status = self.get_result(
             'check_prog("FOO", ("unknown", "known-b", "known c"))',
             ['FOO=/usr/local/bin/known-a'])
         self.assertEqual(status, 1)
         self.assertEqual(config, {})
         self.assertEqual(out, 'checking for foo... not found\n'
-                              'ERROR: Cannot find foo '
-                              '(tried: /usr/local/bin/known-a)\n')
+                              'DEBUG: foo: Trying /usr/local/bin/known-a\n'
+                              'ERROR: Cannot find foo\n')
 
         config, out, status = self.get_result(
             'check_prog("FOO", ("unknown",))',
             ['FOO=known c'])
         self.assertEqual(status, 0)
         self.assertEqual(config, {'FOO': '/home/user/bin/known c'})
         self.assertEqual(out, "checking for foo... '/home/user/bin/known c'\n")
 
         config, out, status = self.get_result(
             'check_prog("FOO", ("unknown", "unknown-2", "unknown 3"), '
             'allow_missing=True)', ['FOO=unknown'])
         self.assertEqual(status, 1)
         self.assertEqual(config, {})
         self.assertEqual(out, 'checking for foo... not found\n'
-                              'ERROR: Cannot find foo (tried: unknown)\n')
+                              'DEBUG: foo: Trying unknown\n'
+                              'ERROR: Cannot find foo\n')
 
     def test_check_prog_configure_error(self):
         with self.assertRaises(ConfigureError) as e:
             self.get_result('check_prog("FOO", "foo")')
 
         self.assertEqual(e.exception.message,
                          'progs should be a list or tuple!')