Skip to content

Commit

Permalink
Get wrap from wrapdb when not found locally
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
xclaesse committed Oct 9, 2022
1 parent 6776bfa commit ced9efb
Showing 1 changed file with 55 additions and 13 deletions.
68 changes: 55 additions & 13 deletions mesonbuild/wrap/wrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@
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
Expand Down Expand Up @@ -262,8 +264,12 @@ def __post_init__(self) -> None:
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:
Expand Down Expand Up @@ -294,18 +300,48 @@ def load_wraps(self) -> None:
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():
Expand All @@ -323,7 +359,8 @@ def find_dep_provider(self, packagename: str) -> T.Tuple[T.Optional[str], T.Opti
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)
Expand All @@ -334,12 +371,17 @@ def find_program_provider(self, names: T.List[str]) -> T.Optional[str]:
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)
Expand Down

0 comments on commit ced9efb

Please sign in to comment.