| #!/usr/bin/env fuchsia-vendored-python |
| # Copyright 2019 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 json |
| import os |
| import platform |
| import sys |
| |
| |
| def main(): |
| parser = argparse.ArgumentParser() |
| parser.add_argument( |
| '--reference', help='Path to the golden API file', required=False) |
| parser.add_argument( |
| '--manifest', help='Path to the SDK manifest', required=True) |
| parser.add_argument( |
| '--updated', help='Path to the API file to compute', required=True) |
| parser.add_argument( |
| '--warn', |
| help='Whether API changes should only cause warnings', |
| action='store_true') |
| parser.add_argument( |
| '--base_reference', |
| help= |
| 'If the reference has been filtered to remove items, this is the original file' |
| ) |
| parser.add_argument( |
| '--ensure-no-host-tools', |
| action='store_true', |
| help='Error if there are host tools in the SDK manifest.') |
| |
| args = parser.parse_args() |
| |
| if not args.reference: |
| # Nothing to do. |
| with open(args.updated, 'w') as updated_file: |
| updated_file.write('No API verification for this SDK :/') |
| return 0 |
| |
| with open(args.manifest, 'r') as manifest_file: |
| manifest = json.load(manifest_file) |
| |
| ids = [a['id'] for a in manifest['atoms']] |
| |
| with open(args.updated, 'w') as updated_file: |
| updated_file.write('\n'.join(ids)) |
| |
| with open(args.reference, 'r') as reference_file: |
| old_ids = [l.strip() for l in reference_file.readlines()] |
| |
| def is_host_tool_id(id: str) -> bool: |
| """Return True if id should not appear when --no-host-tools is used.""" |
| return id.startswith('sdk://tools/') or id == 'sdk://docs/ref_docs' |
| |
| if args.ensure_no_host_tools: |
| # Remove any host tools from the golden manifest, as well as the |
| # //sdk:docs/ref_docs target which depends on |
| # //sdk:host_tools.all($host_toolchain) |
| old_ids = [i for i in old_ids if not is_host_tool_id(i)] |
| |
| # tools/arm64 should not exist on mac hosts |
| # TODO(fxbug.dev/42999): remove when SDK transition is complete. |
| if platform.mac_ver()[0]: |
| old_ids = [i for i in old_ids if not i.startswith('sdk://tools/arm64')] |
| |
| ids = filter(lambda i: not i.startswith('sdk://fidl/zx'), ids) |
| old_ids = filter(lambda i: not i.startswith('sdk://fidl/zx'), old_ids) |
| |
| new_id_set = set(ids) |
| required_id_set = set() |
| optional_id_set = set() |
| for i in old_ids: |
| if i.startswith('?'): |
| optional_id_set.add(i[1:]) |
| else: |
| required_id_set.add(i) |
| |
| added_ids = new_id_set - (required_id_set | optional_id_set) |
| removed_ids = required_id_set - new_id_set |
| |
| if args.ensure_no_host_tools: |
| added_host_ids = {i for i in added_ids if is_host_tool_id(i)} |
| if added_host_ids: |
| print('Error: Host tools incorrectly added to SDK:') |
| for id in sorted(added_host_ids): |
| print(' - %s' % id) |
| print( |
| 'The SDK atoms above should not be dependencies of GN sdk() targets used' |
| ) |
| print('to build this SDK when sdk_no_host_tools is set!') |
| return 1 |
| |
| if added_ids: |
| print('Elements added to SDK:') |
| for id in sorted(added_ids): |
| print(' - %s' % id) |
| if removed_ids: |
| print('Elements removed from SDK:') |
| for id in sorted(removed_ids): |
| print(' - %s' % id) |
| if removed_ids or added_ids: |
| type = 'Warning' if args.warn else 'Error' |
| print('%s: SDK contents have changed!' % type) |
| if args.base_reference: |
| print( |
| 'The manifest cannot be automatically updated when not cross compiling host tools' |
| ) |
| print( |
| 'Please update the manifest manually - {}'.format( |
| args.base_reference)) |
| print( |
| 'or run fx set with "--args sdk_cross_compile_host_tools=true"') |
| else: |
| print('Please acknowledge this change by running:') |
| print( |
| ' cp ' + os.path.abspath(args.updated) + ' ' + |
| os.path.abspath(args.reference)) |
| print( |
| 'Elements can be marked optional with a leading question mark.') |
| print( |
| 'Please remember to complete transitions by marking elements required!' |
| ) |
| if not args.warn: |
| return 1 |
| |
| return 0 |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main()) |