implement the new preserve_path kwarg for install_data too

Primarily interesting to me because it is then available for the python
module's install_sources method.

Based on the new feature in install_headers.
pull/10514/head
Eli Schwartz 2 years ago
parent b89451847a
commit e7d87b6f58
No known key found for this signature in database
GPG Key ID: CEB167EFB5722BD6
  1. 8
      docs/markdown/snippets/install_sources_preserve_path_arg.md
  2. 9
      docs/yaml/functions/install_data.yaml
  3. 32
      mesonbuild/interpreter/interpreter.py
  4. 2
      mesonbuild/interpreter/type_checking.py
  5. 14
      mesonbuild/modules/python.py
  6. 0
      test cases/common/252 install data structured/dir1/bad
  7. 0
      test cases/common/252 install data structured/dir1/file1
  8. 0
      test cases/common/252 install data structured/dir1/file2
  9. 0
      test cases/common/252 install data structured/dir1/file3
  10. 0
      test cases/common/252 install data structured/dir2/bad
  11. 0
      test cases/common/252 install data structured/dir2/file1
  12. 0
      test cases/common/252 install data structured/dir2/file2
  13. 0
      test cases/common/252 install data structured/dir2/file3
  14. 0
      test cases/common/252 install data structured/dir3/bad
  15. 0
      test cases/common/252 install data structured/dir3/file1
  16. 0
      test cases/common/252 install data structured/dir3/file2
  17. 0
      test cases/common/252 install data structured/dir3/file3
  18. 16
      test cases/common/252 install data structured/meson.build
  19. 1
      test cases/common/252 install data structured/pysrc/__init__.py
  20. 1
      test cases/common/252 install data structured/pysrc/bad.py
  21. 1
      test cases/common/252 install data structured/pysrc/bar.py
  22. 1
      test cases/common/252 install data structured/pysrc/foo.py
  23. 11
      test cases/common/252 install data structured/pysrc/meson.build
  24. 1
      test cases/common/252 install data structured/pysrc/submod/__init__.py
  25. 1
      test cases/common/252 install data structured/pysrc/submod/bad.py
  26. 1
      test cases/common/252 install data structured/pysrc/submod/baz.py
  27. 18
      test cases/common/252 install data structured/test.json
  28. 2
      test cases/python/7 install path/meson.build
  29. 0
      test cases/python/7 install path/structured/alpha/one.py
  30. 0
      test cases/python/7 install path/structured/alpha/three.py
  31. 0
      test cases/python/7 install path/structured/alpha/two.py
  32. 0
      test cases/python/7 install path/structured/beta/one.py
  33. 9
      test cases/python/7 install path/structured/meson.build
  34. 0
      test cases/python/7 install path/structured/one.py
  35. 0
      test cases/python/7 install path/structured/two.py
  36. 6
      test cases/python/7 install path/test.json

@ -0,0 +1,8 @@
## Added preserve_path arg to install_data
The [[install_data]] function now has an optional argument `preserve_path`
that allows installing multi-directory data file structures that live
alongside source code with a single command.
This is also available in the specialized `py_installation.install_sources`
method.

@ -43,6 +43,15 @@ kwargs:
to install only a subset of the files. By default these files have no install
tag which means they are not being installed when `--tags` argument is specified.
preserve_path:
type: bool
since: 0.64.0
default: false
description: |
Disable stripping child-directories from data files when installing.
This is equivalent to GNU Automake's `nobase` option.
rename:
type: list[str]
since: 0.46.0

@ -79,6 +79,7 @@ from .type_checking import (
INSTALL_TAG_KW,
LANGUAGE_KW,
NATIVE_KW,
PRESERVE_PATH_KW,
REQUIRED_KW,
SOURCES_KW,
VARIABLES_KW,
@ -2094,7 +2095,7 @@ class Interpreter(InterpreterBase, HoldableObject):
@typed_pos_args('install_headers', varargs=(str, mesonlib.File))
@typed_kwargs(
'install_headers',
KwargInfo('preserve_path', bool, default=False, since='0.63.0'),
PRESERVE_PATH_KW,
KwargInfo('subdir', (str, NoneType)),
INSTALL_MODE_KW.evolve(since='0.47.0'),
INSTALL_DIR_KW,
@ -2302,6 +2303,7 @@ class Interpreter(InterpreterBase, HoldableObject):
INSTALL_MODE_KW.evolve(since='0.38.0'),
INSTALL_TAG_KW.evolve(since='0.60.0'),
INSTALL_DIR_KW,
PRESERVE_PATH_KW.evolve(since='0.64.0'),
)
def func_install_data(self, node: mparser.BaseNode,
args: T.Tuple[T.List['mesonlib.FileOrString']],
@ -2321,19 +2323,35 @@ class Interpreter(InterpreterBase, HoldableObject):
else:
install_dir_name = '{datadir}'
return self.install_data_impl(sources, kwargs['install_dir'], kwargs['install_mode'],
rename, kwargs['install_tag'], install_dir_name)
rename, kwargs['install_tag'], install_dir_name,
preserve_path=kwargs['preserve_path'])
def install_data_impl(self, sources: T.List[mesonlib.File], install_dir: T.Optional[str],
install_mode: FileMode, rename: T.Optional[str],
tag: T.Optional[str],
install_dir_name: T.Optional[str] = None,
install_data_type: T.Optional[str] = None) -> build.Data:
install_data_type: T.Optional[str] = None,
preserve_path: bool = False) -> build.Data:
"""Just the implementation with no validation."""
data = build.Data(sources, install_dir, install_dir_name or install_dir, install_mode,
self.subproject, rename, tag, install_data_type)
self.build.data.append(data)
return data
idir = install_dir or ''
idir_name = install_dir_name or idir
dirs = collections.defaultdict(list)
ret_data = []
if preserve_path:
for file in sources:
dirname = os.path.dirname(file.fname)
dirs[dirname].append(file)
else:
dirs[''].extend(sources)
for childdir, files in dirs.items():
d = build.Data(files, os.path.join(idir, childdir), os.path.join(idir_name, childdir),
install_mode, self.subproject, rename, tag, install_data_type)
ret_data.append(d)
self.build.data.extend(ret_data)
return ret_data
@typed_pos_args('install_subdir', str)
@typed_kwargs(

@ -438,3 +438,5 @@ VARIABLES_KW: KwargInfo[T.Dict[str, str]] = KwargInfo(
convertor=variables_convertor,
default={},
)
PRESERVE_PATH_KW: KwargInfo[bool] = KwargInfo('preserve_path', bool, default=False, since='0.63.0')

@ -30,7 +30,7 @@ from ..dependencies.base import process_method_kw
from ..dependencies.detect import get_dep_identifier
from ..environment import detect_cpu_family
from ..interpreter import ExternalProgramHolder, extract_required_kwarg, permitted_dependency_kwargs
from ..interpreter.type_checking import NoneType
from ..interpreter.type_checking import NoneType, PRESERVE_PATH_KW
from ..interpreterbase import (
noPosargs, noKwargs, permittedKwargs, ContainerTypeInfo,
InvalidArguments, typed_pos_args, typed_kwargs, KwargInfo,
@ -588,8 +588,13 @@ class PythonInstallation(ExternalProgramHolder):
return dep
@typed_pos_args('install_data', varargs=(str, mesonlib.File))
@typed_kwargs('python_installation.install_sources', _PURE_KW, _SUBDIR_KW,
KwargInfo('install_tag', (str, NoneType), since='0.60.0'))
@typed_kwargs(
'python_installation.install_sources',
_PURE_KW,
_SUBDIR_KW,
PRESERVE_PATH_KW,
KwargInfo('install_tag', (str, NoneType), since='0.60.0')
)
def install_sources_method(self, args: T.Tuple[T.List[T.Union[str, mesonlib.File]]],
kwargs: 'PyInstallKw') -> 'Data':
tag = kwargs['install_tag'] or 'runtime'
@ -597,7 +602,8 @@ class PythonInstallation(ExternalProgramHolder):
self.interpreter.source_strings_to_files(args[0]),
self._get_install_dir_impl(kwargs['pure'], kwargs['subdir']),
mesonlib.FileMode(), rename=None, tag=tag, install_data_type='python',
install_dir_name=self._get_install_dir_name_impl(kwargs['pure'], kwargs['subdir']))
install_dir_name=self._get_install_dir_name_impl(kwargs['pure'], kwargs['subdir']),
preserve_path=kwargs['preserve_path'])
@noPosargs
@typed_kwargs('python_installation.install_dir', _PURE_KW, _SUBDIR_KW)

@ -0,0 +1,16 @@
project('install structured data')
install_data(
'dir1/file1',
'dir1/file2',
'dir1/file3',
'dir2/file1',
'dir2/file2',
'dir2/file3',
'dir3/file1',
'dir3/file2',
'dir3/file3',
install_dir: get_option('datadir'),
preserve_path: true,
)
subdir('pysrc')

@ -0,0 +1 @@
'''mod.bad should not be installed'''

@ -0,0 +1,11 @@
py_inst = import('python').find_installation()
py_inst.install_sources(
'__init__.py',
'foo.py',
'bar.py',
'submod/__init__.py',
'submod/baz.py',
subdir: 'mod',
preserve_path: true,
)

@ -0,0 +1 @@
'''mod.submod.bad should not be installed'''

@ -0,0 +1,18 @@
{
"installed": [
{"type": "python_file", "file": "usr/@PYTHON_PURELIB@/mod/__init__.py"},
{"type": "python_file", "file": "usr/@PYTHON_PURELIB@/mod/foo.py"},
{"type": "python_file", "file": "usr/@PYTHON_PURELIB@/mod/bar.py"},
{"type": "python_file", "file": "usr/@PYTHON_PURELIB@/mod/submod/__init__.py"},
{"type": "python_file", "file": "usr/@PYTHON_PURELIB@/mod/submod/baz.py"},
{"type": "file", "file": "usr/share/dir1/file1"},
{"type": "file", "file": "usr/share/dir1/file2"},
{"type": "file", "file": "usr/share/dir1/file3"},
{"type": "file", "file": "usr/share/dir2/file1"},
{"type": "file", "file": "usr/share/dir2/file2"},
{"type": "file", "file": "usr/share/dir2/file3"},
{"type": "file", "file": "usr/share/dir3/file1"},
{"type": "file", "file": "usr/share/dir3/file2"},
{"type": "file", "file": "usr/share/dir3/file3"}
]
}

@ -8,3 +8,5 @@ project('install path',
py = import('python').find_installation()
py.install_sources('test.py')
py.install_sources('test.py', pure: false)
subdir('structured')

@ -0,0 +1,9 @@
py.install_sources(
'one.py',
'two.py',
'alpha/one.py',
'alpha/two.py',
'alpha/three.py',
'beta/one.py',
preserve_path: true,
)

@ -1,5 +1,11 @@
{
"installed": [
{"type": "file", "file": "pure/one.py"},
{"type": "file", "file": "pure/two.py"},
{"type": "file", "file": "pure/alpha/one.py"},
{"type": "file", "file": "pure/alpha/two.py"},
{"type": "file", "file": "pure/alpha/three.py"},
{"type": "file", "file": "pure/beta/one.py"},
{"type": "file", "file": "plat/test.py"},
{"type": "file", "file": "pure/test.py"}
]

Loading…
Cancel
Save