diff --git a/utils/build-script b/utils/build-script index c4a84a4210a76..743f21981c642 100755 --- a/utils/build-script +++ b/utils/build-script @@ -962,6 +962,12 @@ details of the setups of other systems or automated environments.""") default=False, const=True) + parser.add_argument( + # Explicitly unavailable options here. + "--build-jobs", + "--common-cmake-options", + action=arguments.action.unavailable) + args = migration.parse_args(parser, sys.argv[1:]) build_script_impl = os.path.join( diff --git a/utils/swift_build_support/swift_build_support/arguments.py b/utils/swift_build_support/swift_build_support/arguments.py index 47847899b741e..70e032070674a 100644 --- a/utils/swift_build_support/swift_build_support/arguments.py +++ b/utils/swift_build_support/swift_build_support/arguments.py @@ -22,7 +22,8 @@ import shlex __all__ = [ - "type" + "action", + "type", ] @@ -34,6 +35,7 @@ def _register(registry, name, value): setattr(registry, name, value) +# Types ---------------------------------------------------------------------- type = _Registry() @@ -99,3 +101,30 @@ def type_executable(string): "%r is not executable" % string) _register(type, 'executable', type_executable) + +# Actions -------------------------------------------------------------------- +action = _Registry() + + +class _UnavailableAction(argparse.Action): + def __init__(self, + option_strings, + dest=argparse.SUPPRESS, + default=argparse.SUPPRESS, + nargs='?', + help=None): + super(_UnavailableAction, self).__init__( + option_strings=option_strings, + dest=dest, + default=default, + nargs=nargs, + help=help) + + def __call__(self, parser, namespace, values, option_string=None): + if option_string is not None: + arg = option_string + else: + arg = str(values) + parser.error('unknown argument: %s' % arg) + +_register(action, 'unavailable', _UnavailableAction) diff --git a/utils/swift_build_support/tests/test_arguments.py b/utils/swift_build_support/tests/test_arguments.py index 24137175c0337..0ed8f44853d18 100644 --- a/utils/swift_build_support/tests/test_arguments.py +++ b/utils/swift_build_support/tests/test_arguments.py @@ -14,8 +14,17 @@ import os import sys import unittest +try: + # py2 + from StringIO import StringIO +except ImportError: + # py3 + from io import StringIO -from swift_build_support.arguments import type as argtype +from swift_build_support.arguments import ( + type as argtype, + action as argaction, +) class ArgumentsTypeTestCase(unittest.TestCase): @@ -87,3 +96,41 @@ def test_executable(self): self.assertRaises( argparse.ArgumentTypeError, argtype.executable, "../example-command-not-exist") + + +class ArgumentsActionTestCase(unittest.TestCase): + + def test_unavailable(self): + orig_stderr = sys.stderr + + parser = argparse.ArgumentParser() + parser.add_argument("--foo") + parser.add_argument( + "--do-not-use", + "--never-ever", + action=argaction.unavailable) + + args, unknown_args = parser.parse_known_args( + ['--foo', 'bar', '--baz', 'qux']) + + self.assertEqual(args.foo, 'bar') + self.assertEqual(unknown_args, ['--baz', 'qux']) + self.assertFalse(hasattr(args, 'sentinel')) + + stderr = StringIO() + sys.stderr = stderr + self.assertRaises( + SystemExit, + parser.parse_known_args, + ['--foo', 'bar', '--do-not-use', 'baz']) + self.assertIn('--do-not-use', stderr.getvalue()) + + stderr = StringIO() + sys.stderr = stderr + self.assertRaises( + SystemExit, + parser.parse_known_args, + ['--foo', 'bar', '--never-ever=baz']) + self.assertIn('--never-ever', stderr.getvalue()) + + sys.stderr = orig_stderr