aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.com>2020-06-04 14:35:18 -0400
committerXavier Claessens <xavier.claessens@collabora.com>2020-07-01 09:51:57 -0400
commit13316f99feaa9831146f6456ce11916042a871cb (patch)
treec8b7d9b4cdb4e0549d209d4727d3d23dc962701c
parentfba796cf1312715b8b97dcb80a4b5c200332b2e8 (diff)
downloadmeson-13316f99feaa9831146f6456ce11916042a871cb.zip
meson-13316f99feaa9831146f6456ce11916042a871cb.tar.gz
meson-13316f99feaa9831146f6456ce11916042a871cb.tar.bz2
wrap: Refactor to split wraps dictionary into 3 separate dicts
It makes the code cleaner to have 3 separate dictionaries for packagename, dependency and programs.
-rw-r--r--mesonbuild/interpreter.py2
-rw-r--r--mesonbuild/mdist.py2
-rw-r--r--mesonbuild/wrap/wrap.py107
3 files changed, 59 insertions, 52 deletions
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index e616d85..3e64a67 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -3590,7 +3590,7 @@ external dependencies (including libraries) must go to "dependencies".''')
# but only if this dependency is required. It is common to first check for a pkg-config,
# then fallback to use find_library() and only afterward check again the dependency
# with a fallback.
- provider = self.environment.wrap_resolver.find_provider(name)
+ provider = self.environment.wrap_resolver.find_dep_provider(name)
if provider:
kwargs['fallback'] = provider
has_fallback = True
diff --git a/mesonbuild/mdist.py b/mesonbuild/mdist.py
index 5ab0ad4..9d94ace 100644
--- a/mesonbuild/mdist.py
+++ b/mesonbuild/mdist.py
@@ -259,7 +259,7 @@ def run(options):
if options.include_subprojects:
subproject_dir = os.path.join(src_root, b.subproject_dir)
for sub in b.subprojects:
- _, directory = wrap.get_directory(subproject_dir, sub)
+ directory = wrap.get_directory(subproject_dir, sub)
subprojects.append(os.path.join(b.subproject_dir, directory))
extra_meson_args.append('-Dwrap_mode=nodownload')
diff --git a/mesonbuild/wrap/wrap.py b/mesonbuild/wrap/wrap.py
index 1a6399d..536b8ae 100644
--- a/mesonbuild/wrap/wrap.py
+++ b/mesonbuild/wrap/wrap.py
@@ -103,9 +103,22 @@ class WrapNotFoundException(WrapException):
class PackageDefinition:
def __init__(self, fname: str):
- self.filename = fname
+ self.type = None
+ self.values = {} # type: T.Dict[str, str]
+ self.provided_deps = {} # type: T.Dict[str, T.Optional[str]]
+ self.provided_programs = [] # type: T.List[str]
self.basename = os.path.basename(fname)
- self.name = self.basename[:-5]
+ self.name = self.basename
+ if self.name.endswith('.wrap'):
+ self.name = self.name[:-5]
+ self.provided_deps[self.name] = None
+ if fname.endswith('.wrap'):
+ self.parse_wrap(fname)
+ 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')
+
+ def parse_wrap(self, fname: str):
try:
self.config = configparser.ConfigParser(interpolation=None)
self.config.read(fname)
@@ -125,27 +138,25 @@ class PackageDefinition:
self.values = dict(self.config[self.wrap_section])
def parse_provide_section(self):
- self.provide = {self.name: None}
- self.provide_programs = []
if self.config.has_section('provide'):
for k, v in self.config['provide'].items():
if k == 'dependency_names':
# A comma separated list of dependency names that does not
# need a variable name
names = {n.strip(): None for n in v.split(',')}
- self.provide.update(names)
+ self.provided_deps.update(names)
continue
if k == 'program_names':
# A comma separated list of program names
- names = {n.strip(): None for n in v.split(',')}
- self.provide_programs += names
+ names = [n.strip() for n in v.split(',')]
+ self.provided_programs += names
continue
if not v:
m = ('Empty dependency variable name for {!r} in {}. '
'If the subproject uses meson.override_dependency() '
'it can be added in the "dependency_names" special key.')
raise WrapException(m.format(k, self.basename))
- self.provide[k] = v
+ self.provided_deps[k] = v
def get(self, key: str) -> str:
try:
@@ -154,22 +165,12 @@ class PackageDefinition:
m = 'Missing key {!r} in {}'
raise WrapException(m.format(key, self.basename))
-def load_wrap(subdir_root: str, packagename: str) -> PackageDefinition:
+def get_directory(subdir_root: str, packagename: str) -> str:
fname = os.path.join(subdir_root, packagename + '.wrap')
if os.path.isfile(fname):
- return PackageDefinition(fname)
- return None
-
-def get_directory(subdir_root: str, packagename: str):
- directory = packagename
- # We always have to load the wrap file, if it exists, because it could
- # override the default directory name.
- wrap = load_wrap(subdir_root, packagename)
- if wrap and 'directory' in wrap.values:
- directory = wrap.get('directory')
- if os.path.dirname(directory):
- raise WrapException('Directory key must be a name and not a path')
- return wrap, directory
+ wrap = PackageDefinition(fname)
+ return wrap.directory
+ return packagename
class Resolver:
def __init__(self, subdir_root: str, wrap_mode=WrapMode.default):
@@ -177,49 +178,60 @@ class Resolver:
self.subdir_root = subdir_root
self.cachedir = os.path.join(self.subdir_root, 'packagecache')
self.filesdir = os.path.join(self.subdir_root, 'packagefiles')
- self.wraps = {} # type: T.Dict[str, T.Tuple[T.Optional[PackageDefinition], T.Optional[str]]]
+ self.wraps = {} # type: T.Dict[str, PackageDefinition]
+ self.provided_deps = {} # type: T.Dict[str, PackageDefinition]
+ self.provided_programs = {} # type: T.Dict[str, PackageDefinition]
self.load_wraps()
def load_wraps(self):
if not os.path.isdir(self.subdir_root):
return
- # Load wrap files upfront
for f in os.listdir(self.subdir_root):
- if f.endswith('.wrap'):
- packagename = f[:-5]
- wrap, directory = get_directory(self.subdir_root, packagename)
- for k in wrap.provide.keys():
- self.wraps[k] = (wrap, directory)
- elif os.path.isdir(os.path.join(self.subdir_root, f)):
- # Keep it in the case we have dirs with no corresponding wrap file.
- self.wraps.setdefault(f, (None, f))
-
- def find_provider(self, packagename: str):
+ fname = os.path.join(self.subdir_root, f)
+ # Ignore not .wrap files, and reserved directories.
+ if (os.path.isfile(fname) and not fname.endswith('.wrap')) or \
+ f in ['packagecache', 'packagefiles']:
+ continue
+ wrap = PackageDefinition(fname)
+ # We could have added a dummy package definition for the directory,
+ # replace it now with the proper wrap. This happens if we already
+ # downloaded the subproject into 'foo-1.0' directory and we now found
+ # 'foo.wrap' file.
+ if wrap.directory in self.wraps:
+ del self.wraps[wrap.directory]
+ self.wraps[wrap.name] = wrap
+ for k in wrap.provided_deps.keys():
+ self.provided_deps[k] = wrap
+ for k in wrap.provided_programs:
+ self.provided_programs[k] = wrap
+
+ def find_dep_provider(self, packagename: str):
# Return value is in the same format as fallback kwarg:
# ['subproject_name', 'variable_name'], or 'subproject_name'.
- wrap, directory = self.wraps.get(packagename, (None, None))
+ wrap = self.provided_deps.get(packagename)
if wrap:
- dep_var = wrap.provide[packagename]
+ dep_var = wrap.provided_deps.get(packagename)
if dep_var:
return [wrap.name, dep_var]
return wrap.name
- return directory
+ return None
def find_program_provider(self, names: T.List[str]):
- wraps = [i[0] for i in self.wraps.values()]
for name in names:
- for wrap in wraps:
- if wrap and name in wrap.provide_programs:
- return wrap.name
+ wrap = self.provided_programs.get(name)
+ if wrap:
+ return wrap.name
return None
def resolve(self, packagename: str, method: str, current_subproject: str = '') -> str:
self.current_subproject = current_subproject
self.packagename = packagename
- self.wrap, self.directory = self.wraps.get(packagename, (None, self.packagename))
- if self.wrap and packagename != self.wrap.name:
- m = 'subproject() must not be called by the name of a dependency it provides. Expecting {!r} but got {!r}.'
- raise WrapException(m.format(self.wrap.name, packagename))
+ self.directory = packagename
+ self.wrap = self.wraps.get(packagename)
+ if not self.wrap:
+ m = 'Subproject directory not found and {}.wrap file not found'
+ raise WrapNotFoundException(m.format(self.packagename))
+ self.directory = self.wrap.directory
self.dirname = os.path.join(self.subdir_root, self.directory)
meson_file = os.path.join(self.dirname, 'meson.build')
@@ -241,11 +253,6 @@ class Resolver:
if not os.path.isdir(self.dirname):
raise WrapException('Path already exists but is not a directory')
else:
- # A wrap file is required to download
- if not self.wrap:
- m = 'Subproject directory not found and {}.wrap file not found'
- raise WrapNotFoundException(m.format(self.packagename))
-
if self.wrap.type == 'file':
self.get_file()
else: