diff options
author | Xavier Claessens <xavier.claessens@collabora.com> | 2020-09-29 22:24:56 -0400 |
---|---|---|
committer | Xavier Claessens <xavier.claessens@collabora.com> | 2020-10-13 17:55:16 -0400 |
commit | 3a0182378612bc764667328805b11bc92db696c2 (patch) | |
tree | f640f6c2c0499b2c657bfee85ddb52054ad3d79d /mesonbuild/wrap/wrap.py | |
parent | 173c115834e37acf2a66fd00fa4010e5765c39a9 (diff) | |
download | meson-3a0182378612bc764667328805b11bc92db696c2.zip meson-3a0182378612bc764667328805b11bc92db696c2.tar.gz meson-3a0182378612bc764667328805b11bc92db696c2.tar.bz2 |
wrap: Add 'redirect' type and use it when auto promote
Diffstat (limited to 'mesonbuild/wrap/wrap.py')
-rw-r--r-- | mesonbuild/wrap/wrap.py | 52 |
1 files changed, 39 insertions, 13 deletions
diff --git a/mesonbuild/wrap/wrap.py b/mesonbuild/wrap/wrap.py index ef35c6d..a4e0b25 100644 --- a/mesonbuild/wrap/wrap.py +++ b/mesonbuild/wrap/wrap.py @@ -26,6 +26,7 @@ import subprocess import sys import configparser import typing as T +import textwrap from .._pathlib import Path from . import WrapMode @@ -90,9 +91,8 @@ class WrapNotFoundException(WrapException): pass class PackageDefinition: - def __init__(self, fname: str, filesdir: str = None): + def __init__(self, fname: str): self.filename = fname - self.filesdir = filesdir self.type = None # type: T.Optional[str] self.values = {} # type: T.Dict[str, str] self.provided_deps = {} # type: T.Dict[str, T.Optional[str]] @@ -103,20 +103,42 @@ class PackageDefinition: self.directory = self.name self.provided_deps[self.name] = None if self.has_wrap: - self.parse_wrap(fname) + self.parse_wrap() self.directory = self.values.get('directory', self.name) if os.path.dirname(self.directory): raise WrapException('Directory key must be a name and not a path') if self.type and self.type not in ALL_TYPES: raise WrapException('Unknown wrap type {!r}'.format(self.type)) + self.filesdir = os.path.join(os.path.dirname(self.filename), 'packagefiles') - def parse_wrap(self, fname: str) -> None: + def parse_wrap(self) -> None: try: self.config = configparser.ConfigParser(interpolation=None) - self.config.read(fname) + self.config.read(self.filename) except configparser.Error: raise WrapException('Failed to parse {}'.format(self.basename)) self.parse_wrap_section() + if self.type == 'redirect': + # [wrap-redirect] have a `filename` value pointing to the real wrap + # file we should parse instead. It must be relative to the current + # wrap file location and must be in the form foo/subprojects/bar.wrap. + dirname = Path(self.filename).parent + fname = Path(self.values['filename']) + for i, p in enumerate(fname.parts): + if i % 2 == 0: + if p == '..': + raise WrapException('wrap-redirect filename cannot contain ".."') + else: + if p != 'subprojects': + raise WrapException('wrap-redirect filename must be in the form foo/subprojects/bar.wrap') + if fname.suffix != '.wrap': + raise WrapException('wrap-redirect filename must be a .wrap file') + fname = dirname / fname + if not fname.is_file(): + raise WrapException('wrap-redirect filename does not exist') + self.filename = str(fname) + self.parse_wrap() + return self.parse_provide_section() def parse_wrap_section(self) -> None: @@ -171,7 +193,6 @@ class Resolver: self.wrap_mode = wrap_mode self.subdir_root = os.path.join(source_dir, subdir) self.cachedir = os.path.join(self.subdir_root, 'packagecache') - self.filesdir = os.path.join(self.subdir_root, 'packagefiles') self.wraps = {} # type: T.Dict[str, PackageDefinition] self.provided_deps = {} # type: T.Dict[str, PackageDefinition] self.provided_programs = {} # type: T.Dict[str, PackageDefinition] @@ -185,7 +206,7 @@ class Resolver: if not i.endswith('.wrap'): continue fname = os.path.join(self.subdir_root, i) - wrap = PackageDefinition(fname, self.filesdir) + wrap = PackageDefinition(fname) self.wraps[wrap.name] = wrap if wrap.directory in dirs: dirs.remove(wrap.directory) @@ -194,7 +215,7 @@ class Resolver: if i in ['packagecache', 'packagefiles']: continue fname = os.path.join(self.subdir_root, i) - wrap = PackageDefinition(fname, self.filesdir) + wrap = PackageDefinition(fname) self.wraps[wrap.name] = wrap for wrap in self.wraps.values(): @@ -252,13 +273,18 @@ class Resolver: # project's subproject_dir even if the wrap file comes from another # subproject. self.dirname = os.path.join(self.subdir_root, self.directory) - # Copy .wrap file into main project's subproject_dir - wrap_dir = os.path.normpath(os.path.dirname(self.wrap.filename)) - main_dir = os.path.normpath(self.subdir_root) - if wrap_dir != main_dir: + # Check if the wrap comes from the main project. + main_fname = os.path.join(self.subdir_root, self.wrap.basename) + if self.wrap.filename != main_fname: rel = os.path.relpath(self.wrap.filename, self.source_dir) mlog.log('Using', mlog.bold(rel)) - shutil.copy2(self.wrap.filename, self.subdir_root) + # Write a dummy wrap file in main project that redirect to the + # wrap we picked. + with open(main_fname, 'w') as f: + f.write(textwrap.dedent('''\ + [wrap-redirect] + filename = {} + '''.format(os.path.relpath(self.wrap.filename, self.subdir_root)))) else: # No wrap file, it's a dummy package definition for an existing # directory. Use the source code in place. |