diff --git a/mesonbuild/msubprojects.py b/mesonbuild/msubprojects.py index b50c98686..7b608c58e 100755 --- a/mesonbuild/msubprojects.py +++ b/mesonbuild/msubprojects.py @@ -4,23 +4,24 @@ from pathlib import Path from . import mlog from .mesonlib import quiet_git, verbose_git, GitException, Popen_safe, MesonException, windows_proof_rmtree -from .wrap.wrap import API_ROOT, PackageDefinition, Resolver, WrapException, ALL_TYPES +from .wrap.wrap import PackageDefinition, Resolver, WrapException, ALL_TYPES from .wrap import wraptool ALL_TYPES_STRING = ', '.join(ALL_TYPES) def update_wrapdb_file(wrap): - patch_url = wrap.get('patch_url') - branch, revision = wraptool.parse_patch_url(patch_url) + try: + patch_url = wrap.get('patch_url') + branch, revision = wraptool.parse_patch_url(patch_url) + except WrapException: + return new_branch, new_revision = wraptool.get_latest_version(wrap.name) if new_branch != branch or new_revision != revision: wraptool.update_wrap_file(wrap.filename, wrap.name, new_branch, new_revision) mlog.log(' -> New wrap file downloaded.') def update_file(r, wrap, repo_dir, options): - patch_url = wrap.values.get('patch_url', '') - if patch_url.startswith(API_ROOT): - update_wrapdb_file(wrap) + update_wrapdb_file(wrap) if not os.path.isdir(repo_dir): # The subproject is not needed, or it is a tarball extracted in # 'libfoo-1.0' directory and the version has been bumped and the new diff --git a/mesonbuild/wrap/wrap.py b/mesonbuild/wrap/wrap.py index 5fe8b3311..6c5a867f6 100644 --- a/mesonbuild/wrap/wrap.py +++ b/mesonbuild/wrap/wrap.py @@ -42,10 +42,8 @@ try: # regarding 'imported but unused' can be safely ignored import ssl # noqa has_ssl = True - API_ROOT = 'https://wrapdb.mesonbuild.com/v1/' except ImportError: has_ssl = False - API_ROOT = 'http://wrapdb.mesonbuild.com/v1/' REQ_TIMEOUT = 600.0 SSL_WARNING_PRINTED = False diff --git a/mesonbuild/wrap/wraptool.py b/mesonbuild/wrap/wraptool.py index fb91f3a2b..0c3b77f21 100644 --- a/mesonbuild/wrap/wraptool.py +++ b/mesonbuild/wrap/wraptool.py @@ -19,8 +19,9 @@ import shutil import typing as T from glob import glob - -from .wrap import API_ROOT, open_wrapdburl +from urllib.parse import urlparse +from urllib.request import urlopen +from .wrap import WrapException from .. import mesonlib @@ -57,38 +58,30 @@ def add_arguments(parser: 'argparse.ArgumentParser') -> None: p.add_argument('project_path') p.set_defaults(wrap_func=promote) -def get_result(urlstring: str) -> T.Dict[str, T.Any]: - u = open_wrapdburl(urlstring) - data = u.read().decode('utf-8') - jd = json.loads(data) - if jd['output'] != 'ok': - print('Got bad output from server.', file=sys.stderr) - raise SystemExit(data) - assert isinstance(jd, dict) - return jd - -def get_projectlist() -> T.List[str]: - jd = get_result(API_ROOT + 'projects') - projects = jd['projects'] - assert isinstance(projects, list) - return projects +def get_releases() -> T.Dict[str, T.Any]: + url = urlopen('https://wrapdb.mesonbuild.com/v2/releases.json') + return T.cast(T.Dict[str, T.Any], json.loads(url.read().decode())) def list_projects(options: 'argparse.Namespace') -> None: - projects = get_projectlist() - for p in projects: + releases = get_releases() + for p in releases.keys(): print(p) def search(options: 'argparse.Namespace') -> None: name = options.name - jd = get_result(API_ROOT + 'query/byname/' + name) - for p in jd['projects']: - print(p) + releases = get_releases() + for p in releases.keys(): + if p.startswith(name): + print(p) def get_latest_version(name: str) -> tuple: - jd = get_result(API_ROOT + 'query/get_latest/' + name) - branch = jd['branch'] - revision = jd['revision'] - return branch, revision + releases = get_releases() + info = releases.get(name) + if not info: + raise WrapException(f'Wrap {name} not found in wrapdb') + latest_version = info['versions'][0] + version, revision = latest_version.rsplit('-', 1) + return version, revision def install(options: 'argparse.Namespace') -> None: name = options.name @@ -99,16 +92,28 @@ def install(options: 'argparse.Namespace') -> None: wrapfile = os.path.join('subprojects', name + '.wrap') if os.path.exists(wrapfile): raise SystemExit('Wrap file already exists.') - (branch, revision) = get_latest_version(name) - u = open_wrapdburl(API_ROOT + f'projects/{name}/{branch}/{revision}/get_wrap') - data = u.read() + (version, revision) = get_latest_version(name) + url = urlopen(f'https://wrapdb.mesonbuild.com/v2/{name}_{version}-{revision}/{name}.wrap') with open(wrapfile, 'wb') as f: - f.write(data) - print('Installed', name, 'branch', branch, 'revision', revision) + f.write(url.read()) + print(f'Installed {name} version {version} revision {revision}') def parse_patch_url(patch_url: str) -> T.Tuple[str, int]: - arr = patch_url.split('/') - return arr[-3], int(arr[-2]) + u = urlparse(patch_url) + if u.netloc != 'wrapdb.mesonbuild.com': + raise WrapException(f'URL {patch_url} does not seems to be a wrapdb patch') + arr = u.path.strip('/').split('/') + if arr[0] == 'v1': + # e.g. https://wrapdb.mesonbuild.com/v1/projects/zlib/1.2.11/5/get_zip + return arr[-3], int(arr[-2]) + elif arr[0] == 'v2': + # e.g. https://wrapdb.mesonbuild.com/v2/zlib_1.2.11-5/get_patch + tag = arr[-2] + name, version = tag.rsplit('_', 1) + version, revision = version.rsplit('-', 1) + return version, int(revision) + else: + raise WrapException(f'Invalid wrapdb URL {patch_url}') def get_current_version(wrapfile: str) -> T.Tuple[str, int, str, str, str]: cp = configparser.ConfigParser(interpolation=None) @@ -118,11 +123,10 @@ def get_current_version(wrapfile: str) -> T.Tuple[str, int, str, str, str]: branch, revision = parse_patch_url(patch_url) return branch, revision, wrap_data['directory'], wrap_data['source_filename'], wrap_data['patch_filename'] -def update_wrap_file(wrapfile: str, name: str, new_branch: str, new_revision: str) -> None: - u = open_wrapdburl(API_ROOT + f'projects/{name}/{new_branch}/{new_revision}/get_wrap') - data = u.read() +def update_wrap_file(wrapfile: str, name: str, new_version: str, new_revision: str) -> None: + url = urlopen(f'https://wrapdb.mesonbuild.com/v2/{name}_{new_version}-{new_revision}/{name}.wrap') with open(wrapfile, 'wb') as f: - f.write(data) + f.write(url.read()) def update(options: 'argparse.Namespace') -> None: name = options.name @@ -146,17 +150,17 @@ def update(options: 'argparse.Namespace') -> None: os.unlink(os.path.join('subprojects/packagecache', patch_file)) except FileNotFoundError: pass - print('Updated', name, 'to branch', new_branch, 'revision', new_revision) + print(f'Updated {name} version {new_branch} revision {new_revision}') def info(options: 'argparse.Namespace') -> None: name = options.name - jd = get_result(API_ROOT + 'projects/' + name) - versions = jd['versions'] - if not versions: - raise SystemExit('No available versions of' + name) + releases = get_releases() + info = releases.get(name) + if not info: + raise WrapException(f'Wrap {name} not found in wrapdb') print(f'Available versions of {name}:') - for v in versions: - print(' ', v['branch'], v['revision']) + for v in info['versions']: + print(' ', v) def do_promotion(from_path: str, spdir_name: str) -> None: if os.path.isfile(from_path):