aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/coredata.py20
-rwxr-xr-xrun_unittests.py40
-rw-r--r--test cases/unit/84 change option choices/meson.build1
-rw-r--r--test cases/unit/84 change option choices/meson_options.1.txt13
-rw-r--r--test cases/unit/84 change option choices/meson_options.2.txt13
5 files changed, 82 insertions, 5 deletions
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 4be828b..e3b3b01 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -689,14 +689,24 @@ class CoreData:
def get_external_link_args(self, for_machine: MachineChoice, lang):
return self.compiler_options[for_machine][lang]['link_args'].value
- def merge_user_options(self, options: T.Dict[str, T.Union[str, bool, int]]) -> None:
+ def merge_user_options(self, options: T.Dict[str, UserOption[T.Any]]) -> None:
for (name, value) in options.items():
if name not in self.user_options:
self.user_options[name] = value
- else:
- oldval = self.user_options[name]
- if type(oldval) != type(value):
- self.user_options[name] = value
+ continue
+
+ oldval = self.user_options[name]
+ if type(oldval) != type(value):
+ self.user_options[name] = value
+ elif oldval.choices != value.choices:
+ # If the choices have changed, use the new value, but attempt
+ # to keep the old options. If they are not valid keep the new
+ # defaults but warn.
+ self.user_options[name] = value
+ try:
+ value.set_value(oldval.value)
+ except MesonException as e:
+ mlog.warning('Old value(s) of {} are no longer valid, resetting to default ({}).'.format(name, value.value))
def is_cross_build(self, when_building_for: MachineChoice = MachineChoice.HOST) -> bool:
if when_building_for == MachineChoice.BUILD:
diff --git a/run_unittests.py b/run_unittests.py
index 0385404..881b781 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -3325,6 +3325,46 @@ int main(int argc, char **argv) {
self.setconf("-Dfree_array_opt=['a,b', 'c,d']", will_build=False)
self.opt_has('free_array_opt', ['a,b', 'c,d'])
+ def test_options_with_choices_changing(self) -> None:
+ """Detect when options like arrays or combos have their choices change."""
+ testdir = Path(os.path.join(self.unit_test_dir, '84 change option choices'))
+ options1 = str(testdir / 'meson_options.1.txt')
+ options2 = str(testdir / 'meson_options.2.txt')
+
+ # Test that old options are changed to the new defaults if they are not valid
+ real_options = str(testdir / 'meson_options.txt')
+ self.addCleanup(os.unlink, real_options)
+
+ shutil.copy(options1, real_options)
+ self.init(str(testdir))
+ shutil.copy(options2, real_options)
+
+ self.build()
+ opts = self.introspect('--buildoptions')
+ for item in opts:
+ if item['name'] == 'combo':
+ self.assertEqual(item['value'], 'b')
+ self.assertEqual(item['choices'], ['b', 'c', 'd'])
+ elif item['name'] == 'arr':
+ self.assertEqual(item['value'], ['b'])
+ self.assertEqual(item['choices'], ['b', 'c', 'd'])
+
+ self.wipe()
+
+ # When the old options are valid they should remain
+ shutil.copy(options1, real_options)
+ self.init(str(testdir), extra_args=['-Dcombo=c', '-Darray=b,c'])
+ shutil.copy(options2, real_options)
+ self.build()
+ opts = self.introspect('--buildoptions')
+ for item in opts:
+ if item['name'] == 'combo':
+ self.assertEqual(item['value'], 'c')
+ self.assertEqual(item['choices'], ['b', 'c', 'd'])
+ elif item['name'] == 'arr':
+ self.assertEqual(item['value'], ['b', 'c'])
+ self.assertEqual(item['choices'], ['b', 'c', 'd'])
+
def test_subproject_promotion(self):
testdir = os.path.join(self.unit_test_dir, '12 promote')
workdir = os.path.join(self.builddir, 'work')
diff --git a/test cases/unit/84 change option choices/meson.build b/test cases/unit/84 change option choices/meson.build
new file mode 100644
index 0000000..d056d65
--- /dev/null
+++ b/test cases/unit/84 change option choices/meson.build
@@ -0,0 +1 @@
+project('change option choices')
diff --git a/test cases/unit/84 change option choices/meson_options.1.txt b/test cases/unit/84 change option choices/meson_options.1.txt
new file mode 100644
index 0000000..d0326a5
--- /dev/null
+++ b/test cases/unit/84 change option choices/meson_options.1.txt
@@ -0,0 +1,13 @@
+option(
+ 'combo',
+ type : 'combo',
+ choices : ['a', 'b', 'c'],
+ value : 'a',
+)
+
+option(
+ 'array',
+ type : 'array',
+ choices : ['a', 'b', 'c'],
+ value : ['a'],
+)
diff --git a/test cases/unit/84 change option choices/meson_options.2.txt b/test cases/unit/84 change option choices/meson_options.2.txt
new file mode 100644
index 0000000..4684673
--- /dev/null
+++ b/test cases/unit/84 change option choices/meson_options.2.txt
@@ -0,0 +1,13 @@
+option(
+ 'combo',
+ type : 'combo',
+ choices : ['b', 'c', 'd'],
+ value : 'b',
+)
+
+option(
+ 'array',
+ type : 'array',
+ choices : ['b', 'c', 'd'],
+ value : ['b'],
+)