summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.com>2020-09-29 22:24:56 -0400
committerXavier Claessens <xavier.claessens@collabora.com>2020-10-13 17:55:16 -0400
commit3a0182378612bc764667328805b11bc92db696c2 (patch)
treef640f6c2c0499b2c657bfee85ddb52054ad3d79d
parent173c115834e37acf2a66fd00fa4010e5765c39a9 (diff)
downloadmeson-3a0182378612bc764667328805b11bc92db696c2.tar.gz
wrap: Add 'redirect' type and use it when auto promote
-rw-r--r--mesonbuild/wrap/wrap.py52
-rwxr-xr-xrun_unittests.py48
2 files changed, 87 insertions, 13 deletions
diff --git a/mesonbuild/wrap/wrap.py b/mesonbuild/wrap/wrap.py
index ef35c6dbb..a4e0b25c0 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.
diff --git a/run_unittests.py b/run_unittests.py
index cfab11bcf..f6adcee14 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -69,6 +69,8 @@ import mesonbuild.modules.pkgconfig
from mesonbuild.mtest import TAPParser, TestResult
+from mesonbuild.wrap.wrap import PackageDefinition, WrapException
+
from run_tests import (
Backend, FakeBuild, FakeCompilerOptions,
ensure_backend_detects_changes, exe_suffix, get_backend_commands,
@@ -5166,6 +5168,52 @@ recommended as it is not supported on some platforms''')
out = self.init(testdir)
self.assertNotRegex(out, r'WARNING')
+ def test_wrap_redirect(self):
+ redirect_wrap = os.path.join(self.builddir, 'redirect.wrap')
+ real_wrap = os.path.join(self.builddir, 'foo/subprojects/real.wrap')
+ os.makedirs(os.path.dirname(real_wrap))
+
+ # Invalid redirect, filename must have .wrap extension
+ with open(redirect_wrap, 'w') as f:
+ f.write(textwrap.dedent('''
+ [wrap-redirect]
+ filename = foo/subprojects/real.wrapper
+ '''))
+ with self.assertRaisesRegex(WrapException, 'wrap-redirect filename must be a .wrap file'):
+ PackageDefinition(redirect_wrap)
+
+ # Invalid redirect, filename cannot be in parent directory
+ with open(redirect_wrap, 'w') as f:
+ f.write(textwrap.dedent('''
+ [wrap-redirect]
+ filename = ../real.wrap
+ '''))
+ with self.assertRaisesRegex(WrapException, 'wrap-redirect filename cannot contain ".."'):
+ PackageDefinition(redirect_wrap)
+
+ # Invalid redirect, filename must be in foo/subprojects/real.wrap
+ with open(redirect_wrap, 'w') as f:
+ f.write(textwrap.dedent('''
+ [wrap-redirect]
+ filename = foo/real.wrap
+ '''))
+ with self.assertRaisesRegex(WrapException, 'wrap-redirect filename must be in the form foo/subprojects/bar.wrap'):
+ wrap = PackageDefinition(redirect_wrap)
+
+ # Correct redirect
+ with open(redirect_wrap, 'w') as f:
+ f.write(textwrap.dedent('''
+ [wrap-redirect]
+ filename = foo/subprojects/real.wrap
+ '''))
+ with open(real_wrap, 'w') as f:
+ f.write(textwrap.dedent('''
+ [wrap-git]
+ url = http://invalid
+ '''))
+ wrap = PackageDefinition(redirect_wrap)
+ self.assertEqual(wrap.get('url'), 'http://invalid')
+
class FailureTests(BasePlatformTests):
'''
Tests that test failure conditions. Build files here should be dynamically