diff options
author | Mats Wichmann <mats@linux.com> | 2018-07-21 17:55:31 (GMT) |
---|---|---|
committer | Mats Wichmann <mats@linux.com> | 2018-07-21 18:24:13 (GMT) |
commit | 9ec0b9861951cc72de39c742c1162a84696ce91f (patch) | |
tree | d94821f99072be08e14d2de2dcdeddb583d156dd | |
parent | ee03bf12b40248e89ada1e501cf52b9b7cd9f867 (diff) | |
download | SCons-9ec0b9861951cc72de39c742c1162a84696ce91f.zip SCons-9ec0b9861951cc72de39c742c1162a84696ce91f.tar.gz SCons-9ec0b9861951cc72de39c742c1162a84696ce91f.tar.bz2 |
Add ability for SConscript to fail on missing script
SConscript call now takes an optional must_exist flag, which defaults
to False for compatiility with current behavior. If True, an exception
is raised if the file is missing. To improve readability, the
decision is moved off to a new function rather than being inline in
_SConscript.
A global setting to control the overall behavior is also added.
A deprecation warning is added for the current behavior, which is
printed only once.
Signed-off-by: Mats Wichmann <mats@linux.com>
-rw-r--r-- | src/CHANGES.txt | 1 | ||||
-rw-r--r-- | src/engine/SCons/Script/SConscript.py | 24 | ||||
-rw-r--r-- | src/engine/SCons/Script/SConscript.xml | 18 | ||||
-rw-r--r-- | src/engine/SCons/Script/__init__.py | 10 | ||||
-rw-r--r-- | src/engine/SCons/Warnings.py | 7 |
5 files changed, 52 insertions, 8 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 79d25db..3b0e603 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -97,6 +97,7 @@ RELEASE 3.1.0.alpha.yyyymmdd - NEW DATE WILL BE INSERTED HERE This changes SCons to better comply with normal Python installation practices. From Mats Wichmann: + - Begin adding support for SConscript() failing on missing script - Updated manpage scons.xml to fix a nested list problem - Updated doc terminiology: use prepend instead of append as appropriate - xml validity fixes from SConstruct.py change diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index db6552c..5968346 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -153,6 +153,27 @@ def Return(*vars, **kw): stack_bottom = '% Stack boTTom %' # hard to define a variable w/this name :) +def handle_missing_SConscript(f, must_exist): + """Take appropriate action on missing file in SConscript() call. + + The action may be to raise an exception, or print a warning. + On first warning, also print a deprecation warning. + """ + + if SCons.Script._no_missing_sconscript or must_exist: + msg = "Fatal: missing SConscript '%s'" % f.get_internal_path() + raise SCons.Errors.UserError(msg) + + if SCons.Script._warn_missing_sconscript_deprecated: + msg = "Calling missing SConscripts without error is deprecated.\n" + \ + "Transition by adding must_exist=0 to SConscript calls.\n" + \ + "Missing SConscript '%s'" % f.get_internal_path() + SCons.Warnings.warn(SCons.Warnings.DeprecatedMissingSConscriptWarning, msg) + SCons.Script._warn_missing_sconscript_deprecated = False + else: + msg = "Ignoring missing SConscript '%s'" % f.get_internal_path() + SCons.Warnings.warn(SCons.Warnings.MissingSConscriptWarning, msg) + def _SConscript(fs, *files, **kw): top = fs.Top sd = fs.SConstruct_dir.rdir() @@ -264,8 +285,7 @@ def _SConscript(fs, *files, **kw): if old_file is not None: call_stack[-1].globals.update({__file__:old_file}) else: - SCons.Warnings.warn(SCons.Warnings.MissingSConscriptWarning, - "Ignoring missing SConscript '%s'" % f.get_internal_path()) + handle_missing_SConscript(f, kw.get('must_exist', False)) finally: SCons.Script.sconscript_reading = SCons.Script.sconscript_reading - 1 diff --git a/src/engine/SCons/Script/SConscript.xml b/src/engine/SCons/Script/SConscript.xml index 8553fbe..29a89c2 100644 --- a/src/engine/SCons/Script/SConscript.xml +++ b/src/engine/SCons/Script/SConscript.xml @@ -357,12 +357,12 @@ Return('val1 val2') <scons_function name="SConscript"> <arguments> -(scripts, [exports, variant_dir, duplicate]) -<!-- (scripts, [exports, variant_dir, src_dir, duplicate]) --> +(scripts, [exports, variant_dir, duplicate, must_exist=flag]) +<!-- (scripts, [exports, variant_dir, src_dir, duplicate, must_exist=flag]) --> </arguments> <arguments> -(dirs=subdirs, [name=script, exports, variant_dir, duplicate]) -<!-- (dirs=subdirs, [name=script, exports, variant_dir, src_dir, duplicate]) --> +(dirs=subdirs, [name=script, exports, variant_dir, duplicate, must_exist=flag]) +<!-- (dirs=subdirs, [name=script, exports, variant_dir, src_dir, duplicate, must_exist=flag]) --> </arguments> <summary> <para> @@ -562,6 +562,16 @@ and what about this alternative? TODO??? SConscript('build/SConscript', src_dir='src') --> </para> +<para> +The optional +<varname>must_exist</varname> +argument, if true, causes an exception to be raised if a requested +&SConscript; file is not found. The default is false, +which only prints a warning, but this behavior is deprecated. +For scripts which truly intend to be optional, transition to +explicty supplying +<literal>must_exist=False</literal> to the call. +</para> <para> Here are some composite examples: diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index 89fc061..90bc311 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -276,6 +276,16 @@ def HelpFunction(text, append=False): # Will be non-zero if we are reading an SConscript file. sconscript_reading = 0 +_no_missing_sconscript = False +_warn_missing_sconscript_deprecated = True + +def set_missing_sconscript_error(flag=1): + """Set behavior on missing file in SConscript() call. Returns previous value""" + global _no_missing_sconscript + old = _no_missing_sconscript + _no_missing_sconscript = flag + return old + # def Variables(files=[], args=ARGUMENTS): return SCons.Variables.Variables(files, args) diff --git a/src/engine/SCons/Warnings.py b/src/engine/SCons/Warnings.py index e8158a4..63acd22 100644 --- a/src/engine/SCons/Warnings.py +++ b/src/engine/SCons/Warnings.py @@ -147,6 +147,9 @@ class DeprecatedSigModuleWarning(MandatoryDeprecatedWarning): class DeprecatedBuilderKeywordsWarning(MandatoryDeprecatedWarning): pass +class DeprecatedMissingSConscriptWarning(DeprecatedWarning): + pass + # The below is a list of 2-tuples. The first element is a class object. # The second element is true if that class is enabled, false if it is disabled. @@ -179,8 +182,8 @@ def warn(clazz, *args): global _enabled, _warningAsException, _warningOut warning = clazz(args) - for clazz, flag in _enabled: - if isinstance(warning, clazz): + for cls, flag in _enabled: + if isinstance(warning, cls): if flag: if _warningAsException: raise warning |