summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMats Wichmann <mats@linux.com>2018-07-21 17:55:31 (GMT)
committerMats Wichmann <mats@linux.com>2018-07-21 18:24:13 (GMT)
commit9ec0b9861951cc72de39c742c1162a84696ce91f (patch)
treed94821f99072be08e14d2de2dcdeddb583d156dd
parentee03bf12b40248e89ada1e501cf52b9b7cd9f867 (diff)
downloadSCons-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.txt1
-rw-r--r--src/engine/SCons/Script/SConscript.py24
-rw-r--r--src/engine/SCons/Script/SConscript.xml18
-rw-r--r--src/engine/SCons/Script/__init__.py10
-rw-r--r--src/engine/SCons/Warnings.py7
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