From 0a482919aa521a45abab2fb77f7474151a9f4b82 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 15 Aug 2022 15:56:39 -0700 Subject: Added throw_exception parameter to ValidateOptions() which allows you to select either have ValidateOptions() issue error message and exit,or throw an exception and then you can handle it your own way. per dmoody's sugguestion --- SCons/Script/Main.py | 5 ++++- SCons/Script/Main.xml | 21 +++++++++++++++++ SCons/Script/SConsOptions.py | 31 ++++++++++++++++++++++---- SCons/__init__.py | 6 ++--- bin/update_doc_files.sh | 5 +++++ doc/generated/examples/caching_ex-random_1.xml | 6 ++--- doc/generated/functions.gen | 20 +++++++++++++++-- test/ValidateOptions.py | 14 ++++++++++++ test/fixture/SConstruct-check-valid-options | 14 +++++++++++- 9 files changed, 108 insertions(+), 14 deletions(-) create mode 100755 bin/update_doc_files.sh diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index 850ca71..3516e90 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -492,13 +492,16 @@ def GetOption(name): def SetOption(name, value): return OptionsParser.values.set_option(name, value) -def ValidateOptions(): + +def ValidateOptions(throw_exception=False): """ If you call this after you set all your command line options with AddOption(), it will verify that all command line options are valid. So if you added an option --xyz and you call SCons with --xyy you can cause SCons to issue an error message and exit by calling this function. """ + + OptionsParser.raise_exception_on_error = throw_exception OptionsParser.preserve_unknown_options = False OptionsParser.parse_args(OptionsParser.largs, OptionsParser.values) diff --git a/SCons/Script/Main.xml b/SCons/Script/Main.xml index e6eb499..ace1799 100644 --- a/SCons/Script/Main.xml +++ b/SCons/Script/Main.xml @@ -949,12 +949,21 @@ SetOption('max_drift', 0) + + ([throw_exception=False]) + + Check that all the options specified on the command line are either defined by SCons itself or defined by &f-link-AddOption;. + If throw_exception is True, &f-ValidateOptions; will raise a + SConsBadOptionError + exception instead of printing an error message and exiting with an error status. + + If there are any command line options not defined. Calling this function will cause SCons to issue an error message and then exit with an error exit status. @@ -967,6 +976,18 @@ SetOption('max_drift', 0) Be aware that some tools call &f-link-AddOption;, if you are getting error messages for arguments that they add, you will need to ensure that you load those tools before you call &f-ValidateOptions;. + + + Example: + + + +except SConsBadOptionError as e: + print("Parser is SConsOptionParser:%s" % (isinstance(e.parser, SConsOptionParser))) + print("Message is :%s" % e.opt_str) + Exit(3) + + diff --git a/SCons/Script/SConsOptions.py b/SCons/Script/SConsOptions.py index 0dff6be..aab8c7e 100644 --- a/SCons/Script/SConsOptions.py +++ b/SCons/Script/SConsOptions.py @@ -289,14 +289,37 @@ class SConsOptionGroup(optparse.OptionGroup): return result +class SConsBadOptionError(optparse.BadOptionError): + """ + Instance attributes: + opt_str : str + The offending option specified on command line which is not recognized + parser : OptionParser + the active argument parser + """ + + def __init__(self, opt_str, parser=None): + self.opt_str = opt_str + self.parser = parser + + def __str__(self): + return _("no such option: %s") % self.opt_str + + class SConsOptionParser(optparse.OptionParser): preserve_unknown_options = False + raise_exception_on_error = False def error(self, msg): - # overridden OptionValueError exception handler - self.print_usage(sys.stderr) - sys.stderr.write("SCons Error: %s\n" % msg) - sys.exit(2) + """ + overridden OptionValueError exception handler + """ + if self.raise_exception_on_error: + raise SConsBadOptionError(msg, self) + else: + self.print_usage(sys.stderr) + sys.stderr.write("SCons Error: %s\n" % msg) + sys.exit(2) def _process_long_opt(self, rargs, values): """ SCons-specific processing of long options. diff --git a/SCons/__init__.py b/SCons/__init__.py index dc8a9c0..de64c52 100644 --- a/SCons/__init__.py +++ b/SCons/__init__.py @@ -1,9 +1,9 @@ __version__="4.4.1" __copyright__="Copyright (c) 2001 - 2022 The SCons Foundation" __developer__="bdbaddog" -__date__="Sat, 13 Aug 2022 15:38:28 -0700" +__date__="Mon, 15 Aug 2022 11:59:33 -0700" __buildsys__="M1Dog2021" -__revision__="c7deb78684a518c59ed05c40bef266e9d27a9957" -__build__="c7deb78684a518c59ed05c40bef266e9d27a9957" +__revision__="18745cfc5e75df8028682183097202f926e22134" +__build__="18745cfc5e75df8028682183097202f926e22134" # make sure compatibility is always in place import SCons.compat # noqa \ No newline at end of file diff --git a/bin/update_doc_files.sh b/bin/update_doc_files.sh new file mode 100755 index 0000000..5e5cbe6 --- /dev/null +++ b/bin/update_doc_files.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +python bin/docs-update-generated.py +python bin/docs-validate.py +python bin/docs-create-example-outputs.py diff --git a/doc/generated/examples/caching_ex-random_1.xml b/doc/generated/examples/caching_ex-random_1.xml index 14432f1..a2de9bd 100644 --- a/doc/generated/examples/caching_ex-random_1.xml +++ b/doc/generated/examples/caching_ex-random_1.xml @@ -1,8 +1,8 @@ % scons -Q -cc -o f4.o -c f4.c +cc -o f2.o -c f2.c cc -o f5.o -c f5.c -cc -o f3.o -c f3.c cc -o f1.o -c f1.c -cc -o f2.o -c f2.c +cc -o f3.o -c f3.c +cc -o f4.o -c f4.c cc -o prog f1.o f2.o f3.o f4.o f5.o diff --git a/doc/generated/functions.gen b/doc/generated/functions.gen index fd6c44b..6deda59 100644 --- a/doc/generated/functions.gen +++ b/doc/generated/functions.gen @@ -4385,13 +4385,17 @@ the tool object, previously it did not return - ValidateOptions() - env.ValidateOptions() + ValidateOptions([throw_exception=False]) Check that all the options specified on the command line are either defined by SCons itself or defined by &f-link-AddOption;. + If throw_exception is True, &f-ValidateOptions; will raise a + SConsBadOptionError + exception instead of printing an error message and exiting with an error status. + + If there are any command line options not defined. Calling this function will cause SCons to issue an error message and then exit with an error exit status. @@ -4404,6 +4408,18 @@ the tool object, previously it did not return Be aware that some tools call &f-link-AddOption;, if you are getting error messages for arguments that they add, you will need to ensure that you load those tools before you call &f-ValidateOptions;. + + + Example: + + + +except SConsBadOptionError as e: + print("Parser is SConsOptionParser:%s" % (isinstance(e.parser, SConsOptionParser))) + print("Message is :%s" % e.opt_str) + Exit(3) + + diff --git a/test/ValidateOptions.py b/test/ValidateOptions.py index e35ed15..9b53c09 100644 --- a/test/ValidateOptions.py +++ b/test/ValidateOptions.py @@ -47,6 +47,20 @@ test.run(arguments="--garbage=xyz", status=2, stderr=".*SCons Error: no such opt test.fail_test(("This is in SConstruct" in test.stdout()), message='"This is in SConstruct" should not be output. This means ValidateOptions() did not error out before this was printed') +# Now we'll test having ValidateOptions raise a SConsBadOptionError exception +test.run(arguments="--garbage=xyz raise=1", status=2, + stderr=".*SConsBadOptionError: no such option: no such option: --garbage.*", + match=TestSCons.match_re_dotall) +test.fail_test(("This is in SConstruct" in test.stdout()), + message='"This is in SConstruct" should not be output. This means ValidateOptions() did not error out before this was printed') + +# Now we'll test having ValidateOptions raise a SConsBadOptionError exception and catching that exception +test.run(arguments="--garbage=xyz raise=2", status=3, + stdout=".*Parser is SConsOptionParser:True.*Message is .no such option. --garbage.*", + match=TestSCons.match_re_dotall) +test.fail_test(("This is in SConstruct" in test.stdout()), + message='"This is in SConstruct" should not be output. This means ValidateOptions() did not error out before this was printed') + # Local Variables: # tab-width:4 # indent-tabs-mode:nil diff --git a/test/fixture/SConstruct-check-valid-options b/test/fixture/SConstruct-check-valid-options index 47f253c..2c935a2 100644 --- a/test/fixture/SConstruct-check-valid-options +++ b/test/fixture/SConstruct-check-valid-options @@ -1,9 +1,21 @@ +import sys +from SCons.Script.SConsOptions import SConsOptionParser, SConsBadOptionError AddOption( '--testing', help='Test arg', ) -ValidateOptions() +if ARGUMENTS.get('raise', 0) == '1': + ValidateOptions(throw_exception=True) +elif ARGUMENTS.get('raise', 0) == '2': + try: + ValidateOptions(throw_exception=True) + except SConsBadOptionError as e: + print("Parser is SConsOptionParser:%s" % (isinstance(e.parser, SConsOptionParser))) + print("Message is :%s" % e.opt_str) + Exit(3) +else: + ValidateOptions() print("This is in SConstruct") -- cgit v0.12