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 514338 6f0ec77a2d7e
parent 514337 dc41aecedaac
child 514339 9eb9e58dc4bc
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [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`'