summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.com>2021-06-28 11:53:34 -0400
committerXavier Claessens <xavier.claessens@collabora.com>2022-10-09 13:04:03 -0400
commitced9efb5793ff932a0132e79378ded4e393c200d (patch)
tree09bc4bdb234114451e9a9ea2b584160e86115fb3
parent6776bfad3ce0601b9ee0c604b5d51031726824b3 (diff)
downloadmeson-ced9efb5793ff932a0132e79378ded4e393c200d.tar.gz
Get wrap from wrapdb when not found locally
Download wrap file from wrapdb automatically when it is not found locally but we have it in wrapdb.json. This makes for example `dependency('glib-2.0')` work out of the box simply by running `meson wrap update-db`, even if the project does not provide any wraps.
-rw-r--r--mesonbuild/wrap/wrap.py68
1 files changed, 55 insertions, 13 deletions
diff --git a/mesonbuild/wrap/wrap.py b/mesonbuild/wrap/wrap.py
index 10aa1b80e..1cc55ee7f 100644
--- a/mesonbuild/wrap/wrap.py
+++ b/mesonbuild/wrap/wrap.py
@@ -29,10 +29,12 @@ import configparser
import time
import typing as T
import textwrap
+import json
from base64 import b64encode
from netrc import netrc
from pathlib import Path
+
from . import WrapMode
from .. import coredata
from ..mesonlib import quiet_git, GIT, ProgressBar, MesonException, windows_proof_rmtree, Popen_safe
@@ -262,8 +264,12 @@ class Resolver:
self.netrc: T.Optional[netrc] = None
self.provided_deps = {} # type: T.Dict[str, PackageDefinition]
self.provided_programs = {} # type: T.Dict[str, PackageDefinition]
+ self.wrapdb: T.Dict[str, T.Any] = {}
+ self.wrapdb_provided_deps: T.Dict[str, str] = {}
+ self.wrapdb_provided_programs: T.Dict[str, str] = {}
self.load_wraps()
self.load_netrc()
+ self.load_wrapdb()
def load_netrc(self) -> None:
try:
@@ -294,18 +300,48 @@ class Resolver:
self.wraps[wrap.name] = wrap
for wrap in self.wraps.values():
- for k in wrap.provided_deps.keys():
- if k in self.provided_deps:
- prev_wrap = self.provided_deps[k]
- m = f'Multiple wrap files provide {k!r} dependency: {wrap.basename} and {prev_wrap.basename}'
- raise WrapException(m)
- self.provided_deps[k] = wrap
- for k in wrap.provided_programs:
- if k in self.provided_programs:
- prev_wrap = self.provided_programs[k]
- m = f'Multiple wrap files provide {k!r} program: {wrap.basename} and {prev_wrap.basename}'
- raise WrapException(m)
- self.provided_programs[k] = wrap
+ self.add_wrap(wrap)
+
+ def add_wrap(self, wrap: PackageDefinition) -> None:
+ for k in wrap.provided_deps.keys():
+ if k in self.provided_deps:
+ prev_wrap = self.provided_deps[k]
+ m = f'Multiple wrap files provide {k!r} dependency: {wrap.basename} and {prev_wrap.basename}'
+ raise WrapException(m)
+ self.provided_deps[k] = wrap
+ for k in wrap.provided_programs:
+ if k in self.provided_programs:
+ prev_wrap = self.provided_programs[k]
+ m = f'Multiple wrap files provide {k!r} program: {wrap.basename} and {prev_wrap.basename}'
+ raise WrapException(m)
+ self.provided_programs[k] = wrap
+
+ def load_wrapdb(self) -> None:
+ try:
+ with Path(self.subdir_root, 'wrapdb.json').open('r', encoding='utf-8') as f:
+ self.wrapdb = json.load(f)
+ except FileNotFoundError:
+ return
+ for name, info in self.wrapdb.items():
+ self.wrapdb_provided_deps.update({i: name for i in info.get('dependency_names', [])})
+ self.wrapdb_provided_programs.update({i: name for i in info.get('program_names', [])})
+
+ def get_from_wrapdb(self, subp_name: str) -> PackageDefinition:
+ info = self.wrapdb.get(subp_name)
+ if not info:
+ return None
+ self.check_can_download()
+ latest_version = info['versions'][0]
+ version, revision = latest_version.rsplit('-', 1)
+ url = urllib.request.urlopen(f'https://wrapdb.mesonbuild.com/v2/{subp_name}_{version}-{revision}/{subp_name}.wrap')
+ fname = Path(self.subdir_root, f'{subp_name}.wrap')
+ with fname.open('wb') as f:
+ f.write(url.read())
+ mlog.log(f'Installed {subp_name} version {version} revision {revision}')
+ wrap = PackageDefinition(str(fname))
+ self.wraps[wrap.name] = wrap
+ self.add_wrap(wrap)
+ return wrap
def merge_wraps(self, other_resolver: 'Resolver') -> None:
for k, v in other_resolver.wraps.items():
@@ -323,7 +359,8 @@ class Resolver:
if wrap:
dep_var = wrap.provided_deps.get(packagename)
return wrap.name, dep_var
- return None, None
+ wrap_name = self.wrapdb_provided_deps.get(packagename)
+ return wrap_name, None
def get_varname(self, subp_name: str, depname: str) -> T.Optional[str]:
wrap = self.wraps.get(subp_name)
@@ -334,6 +371,9 @@ class Resolver:
wrap = self.provided_programs.get(name)
if wrap:
return wrap.name
+ wrap_name = self.wrapdb_provided_programs.get(name)
+ if wrap_name:
+ return wrap_name
return None
def resolve(self, packagename: str, method: str) -> str:
@@ -341,6 +381,8 @@ class Resolver:
self.directory = packagename
self.wrap = self.wraps.get(packagename)
if not self.wrap:
+ self.wrap = self.get_from_wrapdb(packagename)
+ if not self.wrap:
m = f'Neither a subproject directory nor a {self.packagename}.wrap file was found.'
raise WrapNotFoundException(m)
self.directory = self.wrap.directory