build/interpreter: Split InstallDir to fix layering violation

Currently InstallDir is part of the interpreter, and is an Interpreter
object, which is then put in the Build object. This is a layering
violation, the interperter should have a Holder for build data. This
patch fixes that.
pull/8192/head
Dylan Baker 4 years ago
parent 59328aba29
commit e36aca42d0
  1. 17
      mesonbuild/build.py
  2. 40
      mesonbuild/interpreter.py
  3. 6
      mesonbuild/modules/unstable_external_project.py
  4. 2
      test cases/failing/69 install_data rename bad size/test.json

@ -171,6 +171,21 @@ class Man:
return self.sources return self.sources
class InstallDir:
def __init__(self, src_subdir: str, inst_subdir: str, install_dir: str,
install_mode: T.Optional['FileMode'],
exclude: T.Tuple[T.Set[str], T.Set[str]],
strip_directory: bool, from_source_dir: bool = True):
self.source_subdir = src_subdir
self.installable_subdir = inst_subdir
self.install_dir = install_dir
self.install_mode = install_mode
self.exclude = exclude
self.strip_directory = strip_directory
self.from_source_dir = from_source_dir
class Build: class Build:
"""A class that holds the status of one build including """A class that holds the status of one build including
all dependencies and so on. all dependencies and so on.
@ -198,7 +213,7 @@ class Build:
self.install_scripts = [] self.install_scripts = []
self.postconf_scripts = [] self.postconf_scripts = []
self.dist_scripts = [] self.dist_scripts = []
self.install_dirs = [] self.install_dirs: T.List[InstallDir] = []
self.dep_manifest_name = None self.dep_manifest_name = None
self.dep_manifest = {} self.dep_manifest = {}
self.stdlibs = PerMachine({}, {}) self.stdlibs = PerMachine({}, {})

@ -757,17 +757,11 @@ class DataHolder(InterpreterObject, ObjectHolder):
def get_install_dir(self): def get_install_dir(self):
return self.held_object.install_dir return self.held_object.install_dir
class InstallDir(InterpreterObject): class InstallDirHolder(InterpreterObject, ObjectHolder):
def __init__(self, src_subdir, inst_subdir, install_dir, install_mode,
exclude, strip_directory, from_source_dir=True): def __init__(self, obj: build.InstallDir):
InterpreterObject.__init__(self) InterpreterObject.__init__(self)
self.source_subdir = src_subdir ObjectHolder.__init__(self, obj)
self.installable_subdir = inst_subdir
self.install_dir = install_dir
self.install_mode = install_mode
self.exclude = exclude
self.strip_directory = strip_directory
self.from_source_dir = from_source_dir
class ManHolder(InterpreterObject, ObjectHolder): class ManHolder(InterpreterObject, ObjectHolder):
@ -2591,8 +2585,8 @@ class Interpreter(InterpreterBase):
# FIXME: This is special cased and not ideal: # FIXME: This is special cased and not ideal:
# The first source is our new VapiTarget, the rest are deps # The first source is our new VapiTarget, the rest are deps
self.process_new_values(v.sources[0]) self.process_new_values(v.sources[0])
elif isinstance(v, InstallDir): elif isinstance(v, InstallDirHolder):
self.build.install_dirs.append(v) self.build.install_dirs.append(v.held_object)
elif isinstance(v, Test): elif isinstance(v, Test):
self.build.tests.append(v) self.build.tests.append(v)
elif hasattr(v, 'held_object'): elif hasattr(v, 'held_object'):
@ -4336,43 +4330,45 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
def func_install_subdir(self, node, args, kwargs): def func_install_subdir(self, node, args, kwargs):
if len(args) != 1: if len(args) != 1:
raise InvalidArguments('Install_subdir requires exactly one argument.') raise InvalidArguments('Install_subdir requires exactly one argument.')
subdir = args[0] subdir: str = args[0]
if not isinstance(subdir, str):
raise InvalidArguments('install_subdir positional argument 1 must be a string.')
if 'install_dir' not in kwargs: if 'install_dir' not in kwargs:
raise InvalidArguments('Missing keyword argument install_dir') raise InvalidArguments('Missing keyword argument install_dir')
install_dir = kwargs['install_dir'] install_dir: str = kwargs['install_dir']
if not isinstance(install_dir, str): if not isinstance(install_dir, str):
raise InvalidArguments('Keyword argument install_dir not a string.') raise InvalidArguments('Keyword argument install_dir not a string.')
if 'strip_directory' in kwargs: if 'strip_directory' in kwargs:
if not isinstance(kwargs['strip_directory'], bool): strip_directory: bool = kwargs['strip_directory']
if not isinstance(strip_directory, bool):
raise InterpreterException('"strip_directory" keyword must be a boolean.') raise InterpreterException('"strip_directory" keyword must be a boolean.')
strip_directory = kwargs['strip_directory']
else: else:
strip_directory = False strip_directory = False
if 'exclude_files' in kwargs: if 'exclude_files' in kwargs:
exclude = extract_as_list(kwargs, 'exclude_files') exclude: T.List[str] = extract_as_list(kwargs, 'exclude_files')
for f in exclude: for f in exclude:
if not isinstance(f, str): if not isinstance(f, str):
raise InvalidArguments('Exclude argument not a string.') raise InvalidArguments('Exclude argument not a string.')
elif os.path.isabs(f): elif os.path.isabs(f):
raise InvalidArguments('Exclude argument cannot be absolute.') raise InvalidArguments('Exclude argument cannot be absolute.')
exclude_files = set(exclude) exclude_files: T.Set[str] = set(exclude)
else: else:
exclude_files = set() exclude_files = set()
if 'exclude_directories' in kwargs: if 'exclude_directories' in kwargs:
exclude = extract_as_list(kwargs, 'exclude_directories') exclude: T.List[str] = extract_as_list(kwargs, 'exclude_directories')
for d in exclude: for d in exclude:
if not isinstance(d, str): if not isinstance(d, str):
raise InvalidArguments('Exclude argument not a string.') raise InvalidArguments('Exclude argument not a string.')
elif os.path.isabs(d): elif os.path.isabs(d):
raise InvalidArguments('Exclude argument cannot be absolute.') raise InvalidArguments('Exclude argument cannot be absolute.')
exclude_directories = set(exclude) exclude_directories: T.Set[str] = set(exclude)
else: else:
exclude_directories = set() exclude_directories = set()
exclude = (exclude_files, exclude_directories) exclude = (exclude_files, exclude_directories)
install_mode = self._get_kwarg_install_mode(kwargs) install_mode = self._get_kwarg_install_mode(kwargs)
idir = InstallDir(self.subdir, subdir, install_dir, install_mode, exclude, strip_directory) idir = build.InstallDir(self.subdir, subdir, install_dir, install_mode, exclude, strip_directory)
self.build.install_dirs.append(idir) self.build.install_dirs.append(idir)
return idir return InstallDirHolder(idir)
@FeatureNewKwargs('configure_file', '0.47.0', ['copy', 'output_format', 'install_mode', 'encoding']) @FeatureNewKwargs('configure_file', '0.47.0', ['copy', 'output_format', 'install_mode', 'encoding'])
@FeatureNewKwargs('configure_file', '0.46.0', ['format']) @FeatureNewKwargs('configure_file', '0.46.0', ['format'])

@ -22,7 +22,7 @@ from ..mesonlib import (MesonException, Popen_safe, MachineChoice,
get_variable_regex, do_replacement) get_variable_regex, do_replacement)
from ..interpreterbase import InterpreterObject, InterpreterException, FeatureNew from ..interpreterbase import InterpreterObject, InterpreterException, FeatureNew
from ..interpreterbase import stringArgs, permittedKwargs from ..interpreterbase import stringArgs, permittedKwargs
from ..interpreter import Interpreter, DependencyHolder, InstallDir from ..interpreter import Interpreter, DependencyHolder, InstallDirHolder
from ..compilers.compilers import CFLAGS_MAPPING, CEXE_MAPPING from ..compilers.compilers import CFLAGS_MAPPING, CEXE_MAPPING
from ..dependencies.base import InternalDependency, PkgConfigDependency from ..dependencies.base import InternalDependency, PkgConfigDependency
from ..environment import Environment from ..environment import Environment
@ -192,7 +192,7 @@ class ExternalProject(InterpreterObject):
self.subproject, self.subproject,
target_kwargs) target_kwargs)
idir = InstallDir(self.subdir.as_posix(), idir = build.InstallDir(self.subdir.as_posix(),
Path('dist', self.rel_prefix).as_posix(), Path('dist', self.rel_prefix).as_posix(),
install_dir='.', install_dir='.',
install_mode=None, install_mode=None,
@ -200,7 +200,7 @@ class ExternalProject(InterpreterObject):
strip_directory=True, strip_directory=True,
from_source_dir=False) from_source_dir=False)
return [self.target, idir] return [self.target, InstallDirHolder(idir)]
@stringArgs @stringArgs
@permittedKwargs({'subdir'}) @permittedKwargs({'subdir'})

@ -1,7 +1,7 @@
{ {
"stdout": [ "stdout": [
{ {
"line": "test cases/failing/69 install_data rename bad size/meson.build:3:0: ERROR: Size of rename argument is different from number of sources" "line": "test cases/failing/69 install_data rename bad size/meson.build:3:0: ERROR: \"rename\" and \"sources\" argument lists must be the same length if \"rename\" is given. Rename has 1 elements and sources has 2."
} }
] ]
} }

Loading…
Cancel
Save