tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

update_sdk.py (5225B)


      1 #!/usr/bin/env python3
      2 # Copyright 2022 The Chromium Authors
      3 # Use of this source code is governed by a BSD-style license that can be
      4 # found in the LICENSE file.
      5 """Check out the Fuchsia SDK from a given GCS path. Should be used in a
      6 'hooks_os' entry so that it only runs when .gclient's custom_vars includes
      7 'fuchsia'."""
      8 
      9 import argparse
     10 import json
     11 import logging
     12 import os
     13 import platform
     14 import subprocess
     15 import sys
     16 from typing import Optional
     17 
     18 from gcs_download import DownloadAndUnpackFromCloudStorage
     19 
     20 sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__),
     21                                             'test')))
     22 
     23 from common import SDK_ROOT, get_host_os, make_clean_directory
     24 
     25 _VERSION_FILE = os.path.join(SDK_ROOT, 'meta', 'manifest.json')
     26 
     27 
     28 def _GetHostArch():
     29  host_arch = platform.machine()
     30  # platform.machine() returns AMD64 on 64-bit Windows.
     31  if host_arch in ['x86_64', 'AMD64']:
     32    return 'amd64'
     33  elif host_arch == 'aarch64':
     34    return 'arm64'
     35  raise Exception('Unsupported host architecture: %s' % host_arch)
     36 
     37 
     38 def GetSDKOverrideGCSPath() -> Optional[str]:
     39  """Fetches the sdk override path from a file or an environment variable.
     40 
     41  Returns:
     42    The override sdk location, stripped of white space.
     43      Example: gs://fuchsia-artifacts/development/some-id/sdk
     44  """
     45  if os.getenv('FUCHSIA_SDK_OVERRIDE'):
     46    return os.environ['FUCHSIA_SDK_OVERRIDE'].strip()
     47 
     48  path = os.path.join(os.path.dirname(__file__), 'sdk_override.txt')
     49 
     50  if os.path.isfile(path):
     51    with open(path, 'r') as f:
     52      return f.read().strip()
     53 
     54  return None
     55 
     56 
     57 def _GetCurrentVersionFromManifest() -> Optional[str]:
     58  if not os.path.exists(_VERSION_FILE):
     59    return None
     60  with open(_VERSION_FILE) as f:
     61    try:
     62      data = json.load(f)
     63    except json.decoder.JSONDecodeError:
     64      logging.warning('manifest.json is not at the JSON format and may be empty.')
     65      return None
     66    if 'id' not in data:
     67      logging.warning('The key "id" does not exist in manifest.json')
     68      return None
     69    return data['id']
     70 
     71 
     72 def main():
     73  parser = argparse.ArgumentParser()
     74  parser.add_argument('--cipd-prefix', help='CIPD base directory for the SDK.')
     75  parser.add_argument('--version', help='Specifies the SDK version.')
     76  parser.add_argument('--verbose',
     77                      '-v',
     78                      action='store_true',
     79                      help='Enable debug-level logging.')
     80  parser.add_argument(
     81      '--file',
     82      help='Specifies the sdk tar.gz file name without .tar.gz suffix',
     83      default='core')
     84  args = parser.parse_args()
     85 
     86  logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO)
     87 
     88  # Exit if there's no SDK support for this platform.
     89  try:
     90    host_plat = get_host_os()
     91  except:
     92    logging.warning('Fuchsia SDK is not supported on this platform.')
     93    return 0
     94 
     95  # TODO(crbug.com/326004432): Remove this once DEPS have been fixed not to
     96  # include the "version:" prefix.
     97  if args.version.startswith('version:'):
     98    args.version = args.version[len('version:'):]
     99 
    100  gcs_tarball_prefix = GetSDKOverrideGCSPath()
    101  if not gcs_tarball_prefix:
    102    # sdk_override contains the full path but not only the version id. But since
    103    # the scenario is limited to dry-run, it's not worth complexity to extract
    104    # the version id.
    105    if args.version == _GetCurrentVersionFromManifest():
    106      return 0
    107 
    108  make_clean_directory(SDK_ROOT)
    109 
    110  # Download from CIPD if there is no override file.
    111  if not gcs_tarball_prefix:
    112    if not args.cipd_prefix:
    113      parser.exit(1, '--cipd-prefix must be specified.')
    114    if not args.version:
    115      parser.exit(2, '--version must be specified.')
    116    logging.info('Downloading SDK from CIPD...')
    117    ensure_file = '%s%s-%s version:%s' % (args.cipd_prefix, host_plat,
    118                                          _GetHostArch(), args.version)
    119    subprocess.run(('cipd', 'ensure', '-ensure-file', '-', '-root', SDK_ROOT,
    120                    '-log-level', 'warning'),
    121                   check=True,
    122                   text=True,
    123                   input=ensure_file)
    124 
    125    # Verify that the downloaded version matches the expected one.
    126    downloaded_version = _GetCurrentVersionFromManifest()
    127    if downloaded_version != args.version:
    128      logging.error(
    129          'SDK version after download does not match expected (downloaded:%s '
    130          'vs expected:%s)', downloaded_version, args.version)
    131      return 3
    132  else:
    133    logging.info('Downloading SDK from GCS...')
    134    DownloadAndUnpackFromCloudStorage(
    135        f'{gcs_tarball_prefix}/{get_host_os()}-{_GetHostArch()}/'
    136        f'{args.file}.tar.gz', SDK_ROOT)
    137 
    138  # Build rules (e.g. fidl_library()) depend on updates to the top-level
    139  # manifest to spot when to rebuild for an SDK update. Ensure that ninja
    140  # sees that the SDK manifest has changed, regardless of the mtime set by
    141  # the download & unpack steps above, by setting mtime to now.
    142  # See crbug.com/1457463
    143  os.utime(os.path.join(SDK_ROOT, 'meta', 'manifest.json'), None)
    144 
    145  root_dir = os.path.dirname(os.path.realpath(__file__))
    146  build_def_cmd = [
    147      os.path.join(root_dir, 'gen_build_defs.py'),
    148  ]
    149  subprocess.run(build_def_cmd, check=True)
    150 
    151  return 0
    152 
    153 
    154 if __name__ == '__main__':
    155  sys.exit(main())