Bug 1257326 - Provide reasons for implied options when the caller provides an immediate value.
MozReview-Commit-ID: A8IDPuwPqiP
--- a/python/mozbuild/mozbuild/configure/__init__.py
+++ b/python/mozbuild/mozbuild/configure/__init__.py
@@ -340,18 +340,19 @@ class ConfigureSandbox(dict):
opt = value.format(implied_option.option)
self._helper.add(opt, 'implied')
implied[opt] = implied_option
try:
value, option_string = self._helper.handle(option)
except ConflictingOptionError as e:
reason = implied[e.arg].reason
- reason = self._raw_options.get(reason) or reason.option
- reason = reason.split('=', 1)[0]
+ if not isinstance(reason, types.StringTypes):
+ reason = self._raw_options.get(reason) or reason.option
+ reason = reason.split('=', 1)[0]
raise InvalidOptionError(
"'%s' implied by '%s' conflicts with '%s' from the %s"
% (e.arg, reason, e.old_arg, e.old_origin))
if option_string:
self._raw_options[option] = option_string
return value
@@ -669,16 +670,22 @@ class ConfigureSandbox(dict):
if self._help:
return
if not reason and isinstance(value, DependsFunction):
deps = self._depends[value][1]
possible_reasons = [d for d in deps if d != self._help_option]
if len(possible_reasons) == 1:
if isinstance(possible_reasons[0], Option):
reason = possible_reasons[0]
+ if not reason and (isinstance(value, (bool, tuple)) or
+ isinstance(value, types.StringTypes)):
+ # A reason can be provided automatically when imply_option
+ # is called with an immediate value.
+ _, filename, line, _, _, _ = inspect.stack()[1]
+ reason = "imply_option at %s:%s" % (filename, line)
if not reason:
raise ConfigureError(
"Cannot infer what implies '%s'. Please add a `reason` to "
"the `imply_option` call."
% option)
prefix, name, values = Option.split_option(option)
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/configure/data/imply_option/imm.configure
@@ -0,0 +1,32 @@
+# -*- 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/.
+
+imply_option('--enable-foo', True)
+
+option('--enable-foo', help='enable foo')
+
+@depends('--enable-foo', '--help')
+def foo(value, help):
+ if value:
+ return True
+
+imply_option('--enable-bar', ('foo', 'bar'))
+
+option('--enable-bar', nargs='*', help='enable bar')
+
+@depends('--enable-bar')
+def bar(value):
+ if value:
+ return value
+
+imply_option('--enable-baz', 'BAZ')
+
+option('--enable-baz', nargs=1, help='enable baz')
+
+@depends('--enable-baz')
+def bar(value):
+ if value:
+ return value
--- a/python/mozbuild/mozbuild/test/configure/test_configure.py
+++ b/python/mozbuild/mozbuild/test/configure/test_configure.py
@@ -575,16 +575,42 @@ class TestConfigure(unittest.TestCase):
with self.assertRaises(ConfigureError) as e:
self.get_config([], configure='imply_option/infer_ko.configure')
self.assertEquals(
e.exception.message,
"Cannot infer what implies '--enable-bar'. Please add a `reason` "
"to the `imply_option` call.")
+ def test_imply_option_immediate_value(self):
+ def get_config(*args):
+ return self.get_config(
+ *args, configure='imply_option/imm.configure')
+
+ config = get_config(['--help'])
+ self.assertEquals(config, {})
+
+ config = get_config([])
+ self.assertEquals(config, {})
+
+ with self.assertRaisesRegexp(InvalidOptionError,
+ "--enable-foo' implied by 'imply_option at .+imm.configure:7'"
+ " conflicts with '--disable-foo' from the command-line"):
+ get_config(['--disable-foo'])
+
+ with self.assertRaisesRegexp(InvalidOptionError,
+ "--enable-bar=foo,bar' implied by 'imply_option at .+imm.configure:16'"
+ " conflicts with '--enable-bar=a,b,c' from the command-line"):
+ get_config(['--enable-bar=a,b,c'])
+
+ with self.assertRaisesRegexp(InvalidOptionError,
+ "--enable-baz=BAZ' implied by 'imply_option at .+imm.configure:25'"
+ " conflicts with '--enable-baz=QUUX' from the command-line"):
+ get_config(['--enable-baz=QUUX'])
+
def test_imply_option_failures(self):
with self.assertRaises(ConfigureError) as e:
with self.moz_configure('''
imply_option('--with-foo', ('a',), 'bar')
'''):
self.get_config()
self.assertEquals(e.exception.message,