Bug 1257516 - Make check_prog opt-in to the queued debug log messages. r?ted
--- 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!')