aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/wrap
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 /mesonbuild/wrap
parent6776bfad3ce0601b9ee0c604b5d51031726824b3 (diff)
downloadmeson-ced9efb5793ff932a0132e79378ded4e393c200d.zip
meson-ced9efb5793ff932a0132e79378ded4e393c200d.tar.gz
meson-ced9efb5793ff932a0132e79378ded4e393c200d.tar.bz2
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.
Diffstat (limited to 'mesonbuild/wrap')
-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 10aa1b8..1cc55ee 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