| # This source file is part of the Swift.org open source project |
| # |
| # Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors |
| # Licensed under Apache License v2.0 with Runtime Library Exception |
| # |
| # See https://swift.org/LICENSE.txt for license information |
| # See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| |
| |
| """ |
| Temporary module with functionaly used to migrate away from build-script-impl. |
| """ |
| |
| |
| from __future__ import absolute_import, unicode_literals |
| |
| import itertools |
| import subprocess |
| |
| import six |
| from six.moves import map |
| |
| from swift_build_support.swift_build_support.targets import \ |
| StdlibDeploymentTarget |
| |
| |
| __all__ = [ |
| 'UnknownSDKError', |
| |
| 'check_impl_args', |
| 'migrate_swift_sdks', |
| 'parse_args', |
| ] |
| |
| |
| # ----------------------------------------------------------------------------- |
| |
| class UnknownSDKError(Exception): |
| """Error indicating an unknown SDK was encountered when migrating to target |
| triples. |
| """ |
| |
| def __init__(self, sdk): |
| self.sdk = sdk |
| |
| super(UnknownSDKError, self).__init__( |
| 'Unknown SDK: {}'.format(self.sdk)) |
| |
| |
| def migrate_swift_sdks(args): |
| """Migrate usages of the now deprecated `--swift-sdks` option to the new |
| `--stdlib-deployment-targets` option, converting Swift SDKs to the |
| corresponding targets. |
| |
| This function is a stop-gap to replacing all instances of `--swift-sdks`. |
| """ |
| |
| def _flatten(iterable): |
| return itertools.chain.from_iterable(iterable) |
| |
| def _swift_sdk_to_stdlib_targets(sdk): |
| targets = StdlibDeploymentTarget.get_migrated_targets_for_sdk(sdk) |
| if targets is None: |
| raise UnknownSDKError(sdk) |
| |
| return targets |
| |
| def _migrate_swift_sdks_arg(arg): |
| if not arg.startswith('--swift-sdks'): |
| return arg |
| |
| sdks = arg.split('=')[1] |
| sdk_list = [] if sdks == '' else sdks.split(';') |
| |
| targets = _flatten(map(_swift_sdk_to_stdlib_targets, sdk_list)) |
| target_names = [target.name for target in targets] |
| |
| return '--stdlib-deployment-targets={}'.format(' '.join(target_names)) |
| |
| return list(map(_migrate_swift_sdks_arg, args)) |
| |
| |
| # ----------------------------------------------------------------------------- |
| |
| def _process_disambiguation_arguments(args, unknown_args): |
| """These arguments are only listed in the driver arguments to stop argparse |
| from auto expanding arguments like --install-swift to the known argument |
| --install-swiftevolve. Remove them from args and add them to unknown_args |
| again. |
| """ |
| |
| if hasattr(args, 'impl_skip_test_swift'): |
| if args.impl_skip_test_swift: |
| unknown_args.append('--skip-test-swift') |
| del args.impl_skip_test_swift |
| |
| if hasattr(args, 'impl_install_swift'): |
| if args.impl_install_swift: |
| unknown_args.append('--install-swift') |
| del args.impl_install_swift |
| |
| return args, unknown_args |
| |
| |
| def parse_args(parser, args, namespace=None): |
| """Parses a given argument list with the given argparse.ArgumentParser. |
| |
| Return a processed arguments object. Any unknown arguments are stored in |
| `build_script_impl_args` attribute as a list. Ignores '--' to be compatible |
| with old style argument list. |
| """ |
| |
| args = [arg for arg in args if arg != '--'] |
| args, unknown_args = parser.parse_known_args(args, namespace) |
| args, unknown_args = _process_disambiguation_arguments(args, unknown_args) |
| |
| args.build_script_impl_args = unknown_args |
| |
| return args |
| |
| |
| # ----------------------------------------------------------------------------- |
| |
| def check_impl_args(build_script_impl, args): |
| """Check whether given argv are all known arguments for |
| `build-script-impl`. |
| |
| Raises a ValueError if any invalid argument is found. Return nothing |
| otherwise. |
| """ |
| |
| pipe = subprocess.Popen( |
| [build_script_impl, '--check-args-only=1'] + args, |
| stdout=subprocess.PIPE, |
| stderr=subprocess.PIPE) |
| |
| _, err = pipe.communicate() |
| |
| if pipe.returncode != 0: |
| raise ValueError(six.text_type(err.splitlines()[0].decode())) |