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.
pull/8941/head
Xavier Claessens 4 years ago
parent 6776bfad3c
commit ced9efb579
  1. 68
      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,12 +371,17 @@ 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:
self.packagename = packagename
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)

Loading…
Cancel
Save