Bug 1520718 - In python configure, fix `when` in `option`. r=nalexander
authorMike Hommey <mh+mozilla@glandium.org>
Thu, 17 Jan 2019 17:04:06 +0000
changeset 511456 6f0ec77a2d7e09b3900308e30f0770ef1cb3bc9a
parent 511455 dc41aecedaac40fa9d7850f7a2bec5631ca5cea6
child 511457 9eb9e58dc4bc3840d7b6b0a414ea4888822356b6
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnalexander
bugs1520718
milestone66.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 1520718 - In python configure, fix `when` in `option`. r=nalexander Make option(..., when='--foo') equivalent to option(..., when=depends('--foo')(lambda x: x)). Differential Revision: https://phabricator.services.mozilla.com/D16795
python/mozbuild/mozbuild/configure/__init__.py
python/mozbuild/mozbuild/test/configure/test_configure.py
--- a/python/mozbuild/mozbuild/configure/__init__.py
+++ b/python/mozbuild/mozbuild/configure/__init__.py
@@ -556,25 +556,28 @@ class ConfigureSandbox(dict):
             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
 
         when = self._conditions.get(option)
-        if (when and not self._value_for(when) and
-            value is not None and value.origin != 'default'):
-            if value.origin == 'environment':
-                # The value we return doesn't really matter, because of the
-                # requirement for @depends to have the same when.
-                return None
-            raise InvalidOptionError(
-                '%s is not available in this configuration'
-                % option_string.split('=', 1)[0])
+        # If `when` resolves to a false-ish value, we always return None.
+        # This makes option(..., when='--foo') equivalent to
+        # option(..., when=depends('--foo')(lambda x: x)).
+        if when and not self._value_for(when) and value is not None:
+            # If the option was passed explicitly, we throw an error that
+            # the option is not available. Except when the option was passed
+            # from the environment, because that would be too cumbersome.
+            if value.origin not in ('default', 'environment'):
+                raise InvalidOptionError(
+                    '%s is not available in this configuration'
+                    % option_string.split('=', 1)[0])
+            return None
 
         return value
 
     def _dependency(self, arg, callee_name, arg_name=None):
         if isinstance(arg, types.StringTypes):
             prefix, name, values = Option.split_option(arg)
             if values != ():
                 raise ConfigureError("Option must not contain an '='")
--- a/python/mozbuild/mozbuild/test/configure/test_configure.py
+++ b/python/mozbuild/mozbuild/test/configure/test_configure.py
@@ -886,16 +886,41 @@ class TestConfigure(unittest.TestCase):
                 include(depends('--with-foo', when=always)(lambda x: x))
                 # The sandbox should figure that the `when` here is
                 # appropriate. Bad behavior in CombinedDependsFunction.__eq__
                 # made this fail in the past.
                 set_config('FOO', depends('--with-foo', when=always)(lambda x: x))
         '''):
             self.get_config()
 
+        with self.moz_configure('''
+            option('--with-foo', help='foo')
+            option('--without-bar', help='bar', when='--with-foo')
+            option('--with-qux', help='qux', when='--with-bar')
+            set_config('QUX', True, when='--with-qux')
+        '''):
+            # These are valid:
+            self.get_config(['--with-foo'])
+            self.get_config(['--with-foo', '--with-bar'])
+            self.get_config(['--with-foo', '--without-bar'])
+            self.get_config(['--with-foo', '--with-bar', '--with-qux'])
+            self.get_config(['--with-foo', '--with-bar', '--without-qux'])
+            with self.assertRaises(InvalidOptionError) as e:
+                self.get_config(['--with-bar'])
+            with self.assertRaises(InvalidOptionError) as e:
+                self.get_config(['--without-bar'])
+            with self.assertRaises(InvalidOptionError) as e:
+                self.get_config(['--with-qux'])
+            with self.assertRaises(InvalidOptionError) as e:
+                self.get_config(['--without-qux'])
+            with self.assertRaises(InvalidOptionError) as e:
+                self.get_config(['--with-foo', '--without-bar', '--with-qux'])
+            with self.assertRaises(InvalidOptionError) as e:
+                self.get_config(['--with-foo', '--without-bar', '--without-qux'])
+
     def test_include_failures(self):
         with self.assertRaises(ConfigureError) as e:
             with self.moz_configure('include("../foo.configure")'):
                 self.get_config()
 
         self.assertEquals(
             e.exception.message,
             'Cannot include `%s` because it is not in a subdirectory of `%s`'