coredata: Add an object to abstract builtins

Currently the builtins are stored as lists, then there are a mess of
functions which take said lists, check what the type of the first
thing is, and then extract data from various points in the list based
on that.

This is stupid. This is what structs/classes are for.
pull/4931/head
Dylan Baker 6 years ago
parent b1aa54bb29
commit d778a371ac
  1. 115
      mesonbuild/coredata.py

@ -26,6 +26,7 @@ from .wrap import WrapMode
import ast import ast
import argparse import argparse
import configparser import configparser
from typing import Optional, Any, TypeVar, Generic, Type
version = '0.50.999' version = '0.50.999'
backendlist = ['ninja', 'vs', 'vs2010', 'vs2015', 'vs2017', 'xcode'] backendlist = ['ninja', 'vs', 'vs2010', 'vs2015', 'vs2017', 'xcode']
@ -335,11 +336,8 @@ class CoreData:
def init_builtins(self): def init_builtins(self):
# Create builtin options with default values # Create builtin options with default values
self.builtins = {} self.builtins = {}
prefix = get_builtin_option_default('prefix') for key, opt in builtin_options.items():
for key in get_builtin_options(): self.builtins[key] = opt.init_option(key)
value = get_builtin_option_default(key, prefix)
args = [key] + builtin_options[key][1:-1] + [value]
self.builtins[key] = builtin_options[key][0](*args)
def init_backend_options(self, backend_name): def init_backend_options(self, backend_name):
if backend_name == 'ninja': if backend_name == 'ninja':
@ -664,25 +662,24 @@ def is_builtin_option(optname):
def get_builtin_option_choices(optname): def get_builtin_option_choices(optname):
if is_builtin_option(optname): if is_builtin_option(optname):
if builtin_options[optname][0] == UserComboOption: b = builtin_options[optname]
return builtin_options[optname][2] if b.opt_type is UserBooleanOption:
elif builtin_options[optname][0] == UserBooleanOption:
return [True, False] return [True, False]
elif builtin_options[optname][0] == UserFeatureOption: elif b.opt_type is UserFeatureOption:
return UserFeatureOption.static_choices return UserFeatureOption.static_choices
else: else:
return None return b.choices
else: else:
raise RuntimeError('Tried to get the supported values for an unknown builtin option \'%s\'.' % optname) raise RuntimeError('Tried to get the supported values for an unknown builtin option \'%s\'.' % optname)
def get_builtin_option_description(optname): def get_builtin_option_description(optname):
if is_builtin_option(optname): if is_builtin_option(optname):
return builtin_options[optname][1] return builtin_options[optname].description
else: else:
raise RuntimeError('Tried to get the description for an unknown builtin option \'%s\'.' % optname) raise RuntimeError('Tried to get the description for an unknown builtin option \'%s\'.' % optname)
def get_builtin_option_action(optname): def get_builtin_option_action(optname):
default = builtin_options[optname][2] default = builtin_options[optname].default
if default is True: if default is True:
return 'store_false' return 'store_false'
elif default is False: elif default is False:
@ -692,15 +689,13 @@ def get_builtin_option_action(optname):
def get_builtin_option_default(optname, prefix=''): def get_builtin_option_default(optname, prefix=''):
if is_builtin_option(optname): if is_builtin_option(optname):
o = builtin_options[optname] o = builtin_options[optname]
if o[0] == UserComboOption: if o.opt_type in [UserComboOption, UserIntegerOption]:
return o[3] return o.default
if o[0] == UserIntegerOption:
return o[4]
try: try:
return builtin_dir_noprefix_options[optname][prefix] return builtin_dir_noprefix_options[optname][prefix]
except KeyError: except KeyError:
pass pass
return o[2] return o.default
else: else:
raise RuntimeError('Tried to get the default value for an unknown builtin option \'%s\'.' % optname) raise RuntimeError('Tried to get the default value for an unknown builtin option \'%s\'.' % optname)
@ -757,38 +752,62 @@ def parse_cmd_line_options(args):
args.cmd_line_options[name] = value args.cmd_line_options[name] = value
delattr(args, name) delattr(args, name)
_U = TypeVar('_U', bound=UserOption)
class BuiltinOption(Generic[_U]):
"""Class for a builtin option type.
Currently doesn't support UserIntegerOption, or a few other cases.
"""
def __init__(self, opt_type: Type[_U], description: str, default: Any, yielding: Optional[bool] = None, *,
choices: Any = None):
self.opt_type = opt_type
self.description = description
self.default = default
self.choices = choices
self.yielding = yielding
def init_option(self, name: str) -> _U:
"""Create an instance of opt_type and return it."""
keywords = {'yielding': self.yielding, 'value': self.default}
if self.choices:
keywords['choices'] = self.choices
return self.opt_type(name, self.description, **keywords)
builtin_options = { builtin_options = {
'buildtype': [UserComboOption, 'Build type to use', ['plain', 'debug', 'debugoptimized', 'release', 'minsize', 'custom'], 'debug'], 'buildtype': BuiltinOption(UserComboOption, 'Build type to use', 'debug',
'strip': [UserBooleanOption, 'Strip targets on install', False], choices=['plain', 'debug', 'debugoptimized', 'release', 'minsize', 'custom']),
'unity': [UserComboOption, 'Unity build', ['on', 'off', 'subprojects'], 'off'], 'strip': BuiltinOption(UserBooleanOption, 'Strip targets on install', False),
'prefix': [UserStringOption, 'Installation prefix', default_prefix()], 'unity': BuiltinOption(UserComboOption, 'Unity build', 'off', choices=['on', 'off', 'subprojects']),
'libdir': [UserStringOption, 'Library directory', default_libdir()], 'prefix': BuiltinOption(UserStringOption, 'Installation prefix', default_prefix()),
'libexecdir': [UserStringOption, 'Library executable directory', default_libexecdir()], 'libdir': BuiltinOption(UserStringOption, 'Library directory', default_libdir()),
'bindir': [UserStringOption, 'Executable directory', 'bin'], 'libexecdir': BuiltinOption(UserStringOption, 'Library executable directory', default_libexecdir()),
'sbindir': [UserStringOption, 'System executable directory', 'sbin'], 'bindir': BuiltinOption(UserStringOption, 'Executable directory', 'bin'),
'includedir': [UserStringOption, 'Header file directory', 'include'], 'sbindir': BuiltinOption(UserStringOption, 'System executable directory', 'sbin'),
'datadir': [UserStringOption, 'Data file directory', 'share'], 'includedir': BuiltinOption(UserStringOption, 'Header file directory', 'include'),
'mandir': [UserStringOption, 'Manual page directory', 'share/man'], 'datadir': BuiltinOption(UserStringOption, 'Data file directory', 'share'),
'infodir': [UserStringOption, 'Info page directory', 'share/info'], 'mandir': BuiltinOption(UserStringOption, 'Manual page directory', 'share/man'),
'localedir': [UserStringOption, 'Locale data directory', 'share/locale'], 'infodir': BuiltinOption(UserStringOption, 'Info page directory', 'share/info'),
'sysconfdir': [UserStringOption, 'Sysconf data directory', 'etc'], 'localedir': BuiltinOption(UserStringOption, 'Locale data directory', 'share/locale'),
'localstatedir': [UserStringOption, 'Localstate data directory', 'var'], 'sysconfdir': BuiltinOption(UserStringOption, 'Sysconf data directory', 'etc'),
'sharedstatedir': [UserStringOption, 'Architecture-independent data directory', 'com'], 'localstatedir': BuiltinOption(UserStringOption, 'Localstate data directory', 'var'),
'werror': [UserBooleanOption, 'Treat warnings as errors', False], 'sharedstatedir': BuiltinOption(UserStringOption, 'Architecture-independent data directory', 'com'),
'warning_level': [UserComboOption, 'Compiler warning level to use', ['0', '1', '2', '3'], '1'], 'werror': BuiltinOption(UserBooleanOption, 'Treat warnings as errors', False),
'layout': [UserComboOption, 'Build directory layout', ['mirror', 'flat'], 'mirror'], 'warning_level': BuiltinOption(UserComboOption, 'Compiler warning level to use', '1', choices=['0', '1', '2', '3']),
'default_library': [UserComboOption, 'Default library type', ['shared', 'static', 'both'], 'shared'], 'layout': BuiltinOption(UserComboOption, 'Build directory layout', 'mirror', choices=['mirror', 'flat']),
'backend': [UserComboOption, 'Backend to use', backendlist, 'ninja'], 'default_library': BuiltinOption(UserComboOption, 'Default library type', 'shared', choices=['shared', 'static', 'both']),
'stdsplit': [UserBooleanOption, 'Split stdout and stderr in test logs', True], 'backend': BuiltinOption(UserComboOption, 'Backend to use', 'ninja', choices=backendlist),
'errorlogs': [UserBooleanOption, "Whether to print the logs from failing tests", True], 'stdsplit': BuiltinOption(UserBooleanOption, 'Split stdout and stderr in test logs', True),
'install_umask': [UserUmaskOption, 'Default umask to apply on permissions of installed files', '022'], 'errorlogs': BuiltinOption(UserBooleanOption, "Whether to print the logs from failing tests", True),
'auto_features': [UserFeatureOption, "Override value of all 'auto' features", 'auto'], 'install_umask': BuiltinOption(UserUmaskOption, 'Default umask to apply on permissions of installed files', '022'),
'optimization': [UserComboOption, 'Optimization level', ['0', 'g', '1', '2', '3', 's'], '0'], 'auto_features': BuiltinOption(UserFeatureOption, "Override value of all 'auto' features", 'auto'),
'debug': [UserBooleanOption, 'Debug', True], 'optimization': BuiltinOption(UserComboOption, 'Optimization level', '0', choices=['0', 'g', '1', '2', '3', 's']),
'wrap_mode': [UserComboOption, 'Wrap mode', ['default', 'debug': BuiltinOption(UserBooleanOption, 'Debug', True),
'nofallback', 'wrap_mode': BuiltinOption(UserComboOption, 'Wrap mode', 'default', choices=['default', 'nofallback', 'nodownload', 'forcefallback']),
'nodownload',
'forcefallback'], 'default'],
} }
# Special prefix-dependent defaults for installation directories that reside in # Special prefix-dependent defaults for installation directories that reside in

Loading…
Cancel
Save