| #!/usr/bin/env python |
| # Copyright 2022 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import argparse |
| import dataclasses |
| import json |
| import os |
| import re |
| import sys |
| import urllib.request |
| |
| _BASE_URL = 'https://mirrors.edge.kernel.org/pub/linux/utils/util-linux' |
| |
| |
| def _parse_index_page(url): |
| entries = [] |
| |
| with urllib.request.urlopen(url) as response: |
| html = response.read().decode().splitlines() |
| for line in html: |
| if not line.startswith('<a href='): |
| continue |
| match = re.match(r'^<a href="([^"]+)">.*</a>\s+', line) |
| name = match.group(1) |
| entries.append(name) |
| |
| return entries |
| |
| |
| def _try_int(x): |
| try: |
| return int(x) |
| except ValueError: |
| return x |
| |
| |
| def _as_version_tuple(version: str): |
| return [_try_int(x) for x in re.split(r'[-.]', version)] |
| |
| |
| def do_latest(): |
| """Retrieve latest version. |
| |
| This is kind of hacky, but the Apache default index page hasn't changed |
| in 15+ years so it should be ok. |
| |
| This package only uses major.minor for folders but major.minor.bugfix in |
| tarball names. So if the most recent folder is '2.25' and within '2.25' |
| there are tarballs with versions '2.25', '2.25.1', and '2.25.2', we need |
| to retrieve '2.25.2' since that's the current version. |
| """ |
| entries = _parse_index_page(_BASE_URL) |
| matches = [] |
| for entry in entries: |
| match = re.match(r'^v(\d+(?:\.\d+)*)/?$', entry) |
| if match: |
| matches.append(match.group(1)) |
| |
| # Need to loop over high numbers since the latest folder might only be |
| # release candidates. If so, we need to go to the next folder. |
| versions = sorted(matches, key=_as_version_tuple) |
| |
| matches = [] |
| for ver in reversed(versions): |
| entries = _parse_index_page(f'{_BASE_URL}/v{ver}') |
| for entry in entries: |
| if not entry.startswith('util-linux-'): |
| continue |
| if not entry.endswith('.tar.gz'): |
| continue |
| if '-rc' in entry: |
| continue |
| matches.append(entry[len('util-linux-'):-len('.tar.gz')]) |
| if matches: |
| break |
| |
| current = max(matches, key=_as_version_tuple) |
| |
| print(current) |
| return 0 |
| |
| |
| def get_download_url(version, platform): |
| """Get URL of the given version and platform. |
| |
| See docstring for do_latest() for details about URLs for this package. |
| Basically, we need 'BASE/vMAJ.MIN/util-linux-FULLVER.tar.gz'. |
| """ |
| major, minor, *rest = version.rstrip('/').split('.') |
| url = f'{_BASE_URL}/v{major}.{minor}/util-linux-{version}.tar.gz' |
| manifest = {'url': [url], 'ext': '.tar.gz'} |
| print(json.dumps(manifest)) |
| |
| |
| def main(): |
| ap = argparse.ArgumentParser() |
| sub = ap.add_subparsers() |
| |
| latest = sub.add_parser("latest") |
| latest.set_defaults(func=lambda _opts: do_latest()) |
| |
| download = sub.add_parser("get_url") |
| download.set_defaults( |
| func=lambda opts: get_download_url( |
| os.environ['_3PP_VERSION'], os.environ['_3PP_PLATFORM'] |
| ) |
| ) |
| |
| opts = ap.parse_args() |
| return opts.func(opts) |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main()) |