diff options
Diffstat (limited to 'llvm_tools/fetch_cros_sdk_rolls.py')
-rwxr-xr-x | llvm_tools/fetch_cros_sdk_rolls.py | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/llvm_tools/fetch_cros_sdk_rolls.py b/llvm_tools/fetch_cros_sdk_rolls.py new file mode 100755 index 00000000..42af678a --- /dev/null +++ b/llvm_tools/fetch_cros_sdk_rolls.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 +# Copyright 2020 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Gets info about completed chromiumos-sdk runs. + +Moreover, this script exists to get versions of published sdk tarballs in +gs://chromiumos-sdk/. The hope is that it'll help answer the question "when did +the toolchain ebuild ${x} go live?" +""" + +# pylint: disable=cros-logging-import + +import argparse +import json +import logging +import os +import shutil +import subprocess +import sys +import tempfile +from typing import Dict, List +from pathlib import Path + + +def fetch_all_sdk_manifest_paths() -> List[str]: + """Fetches all paths of SDK manifests; newer = later in the return value.""" + results = subprocess.run( + ['gsutil', 'ls', 'gs://chromiumos-sdk/cros-sdk-20??.*.Manifest'], + check=True, + stdout=subprocess.PIPE, + encoding='utf-8', + ).stdout + # These are named so that sorted order == newest last. + return sorted(x.strip() for x in results.splitlines()) + + +def fetch_manifests_into(into_dir: Path, manifests: List[str]): + # Wrap this in a `try` block because gsutil likes to print to stdout *and* + # stderr even on success, so we silence them & only print on failure. + try: + subprocess.run( + [ + 'gsutil', + '-m', + 'cp', + '-I', + str(into_dir), + ], + check=True, + input='\n'.join(manifests), + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + encoding='utf-8', + ) + except subprocess.CalledProcessError as e: + logging.exception('gsutil failed; output:\n%s', e.stdout) + + +def load_manifest_versions(manifest: Path) -> Dict[str, str]: + with manifest.open(encoding='utf-8') as f: + raw_versions = json.load(f) + + # We get a dict of list of lists of versions and some other metadata, e.g. + # {"foo/bar": [["1.2.3", {}]]} + # Trim out the metadata. + return {k: v[0][0] for k, v in raw_versions['packages'].items()} + + +def main(): + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument( + '-d', '--debug', action='store_true', help='Emit debugging output') + parser.add_argument( + '-n', + '--number', + type=int, + default=20, + help='Number of recent manifests to fetch info about. 0 means unlimited.') + args = parser.parse_args() + + is_debug = args.debug + logging.basicConfig(level=logging.DEBUG if is_debug else logging.INFO) + + logging.debug('Fetching SDK manifests') + manifest_paths = fetch_all_sdk_manifest_paths() + logging.debug('%d SDK manifests fetched', len(manifest_paths)) + + number = args.number + if number: + manifest_paths = manifest_paths[-number:] + + tempdir = Path(tempfile.mkdtemp(prefix='cros-sdk-rolls')) + try: + logging.debug('Working in tempdir %r', tempdir) + fetch_manifests_into(tempdir, manifest_paths) + + for path in manifest_paths: + basename = os.path.basename(path) + versions = load_manifest_versions(tempdir.joinpath(basename)) + print(f'{basename}: {versions["sys-devel/llvm"]}') + finally: + if is_debug: + logging.debug('Keeping around tempdir %r to aid debugging', tempdir) + else: + shutil.rmtree(tempdir) + + +if __name__ == '__main__': + sys.exit(main()) |