summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xCHANGES.txt25
-rw-r--r--SCons/Environment.xml107
-rw-r--r--SCons/Node/FS.py42
-rw-r--r--SCons/Node/FSTests.py17
-rw-r--r--SCons/Node/NodeTests.py2
-rw-r--r--SCons/Node/Python.py3
-rw-r--r--SCons/Node/__init__.py10
-rw-r--r--SCons/Util.py4
-rw-r--r--doc/man/sconsign.xml85
-rw-r--r--test/SConsignFile/default.py26
-rw-r--r--test/SConsignFile/explicit-dbm-module.py85
-rw-r--r--test/SConsignFile/explicit-file.py28
-rw-r--r--test/SConsignFile/make-directory.py17
-rw-r--r--test/SConsignFile/use-dbhash.py18
-rw-r--r--test/SConsignFile/use-dbm.py40
-rw-r--r--test/SConsignFile/use-dumbdbm.py25
-rw-r--r--test/SConsignFile/use-gdbm.py23
-rw-r--r--test/Value/GetContent.py50
18 files changed, 383 insertions, 224 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 99c12d4..e4b1bf8 100755
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -42,6 +42,13 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
hash format that SCons uses. It can also be set via SetOption('hash_format'). Supported
values include md5, sha1, and sha256, but you can also use any other algorithm that is
offered by your Python interpreter's hashlib package.
+ - Fix incorrect cache hits and/or misses when running in interactive mode by having
+ SCons.Node.Node.clear() clear out all caching-related state.
+
+ From Jason Kenny
+ - Fix python3 crash when Value node get_text_content when child content does not have decode()
+ NOTE: If you depend on Value node's get_text_content returning concatenated contents of it's
+ children. This may break your code. It now concatenates the csig() of all children.
From Joachim Kuebart:
- Suppress missing SConscript deprecation warning if `must_exist=False`
@@ -55,6 +62,13 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
From Daniel Moody:
- Fix issue where java parsed a class incorrectly from lambdas used after a new.
+ From Simon Tegelid
+ - Fix using TEMPFILE in multiple actions in an action list. Previously a builder, or command
+ with an action list like this:
+ ['${TEMPFILE("xxx.py -otempfile $SOURCE")}', '${TEMPFILE("yyy.py -o$TARGET tempfile")}']
+ Could yield a single tempfile with the first TEMPFILE's contents, used by both steps
+ in the action list.
+
From Mats Wichmann:
- Complete tests for Dictionary, env.keys() and env.values() for
OverrideEnvironment. Enable env.setdefault() method, add tests.
@@ -93,15 +107,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
special-case Windows here. dblite is the default storage engine for the SConsign file(s).
- Fix cut-n-paste error in msvc debug printout and make some debug output
in msvs and msvsTests.py be off until needed (uncomment to use)
-
- From Simon Tegelid
- - Fix using TEMPFILE in multiple actions in an action list. Previously a builder, or command
- with an action list like this:
- ['${TEMPFILE("xxx.py -otempfile $SOURCE")}', '${TEMPFILE("yyy.py -o$TARGET tempfile")}']
- Could yield a single tempfile with the first TEMPFILE's contents, used by both steps
- in the action list.
-
-
+ - Fix Issue #3014 - Empty file and missing file have same csig
@@ -135,6 +141,7 @@ RELEASE 4.0.0 - Sat, 04 Jul 2020 12:00:27 +0000
removed libxslt support from the Docbook Tool. (issue #3580)
- Added Docker images for building and testing SCons. (issue #3585)
+
From James Benton:
- Improve Visual Studio solution/project generation code to add support
for a per-variant cppflags. Intellisense can be affected by cppflags,
diff --git a/SCons/Environment.xml b/SCons/Environment.xml
index 7d3927b..14221fd 100644
--- a/SCons/Environment.xml
+++ b/SCons/Environment.xml
@@ -2743,58 +2743,76 @@ SConscript('bar/SConscript') # will chdir to bar
<scons_function name="SConsignFile">
<arguments>
-([file, dbm_module])
+([name, dbm_module])
</arguments>
<summary>
<para>
-This tells
-&scons;
-to store all file signatures
-in the specified database
-<parameter>file</parameter>.
-If the
-<parameter>file</parameter>
-name is omitted,
-<filename>.sconsign</filename>
-is used by default.
-(The actual file name(s) stored on disk
-may have an appropriated suffix appended
-by the
-<parameter>dbm_module</parameter>.)
-If
-<parameter>file</parameter>
-is not an absolute path name,
-the file is placed in the same directory as the top-level
-&SConstruct;
-file.
+Specify where to store the &SCons; file signature database,
+and which database format to use.
+This may be useful to specify alternate
+database files and/or file locations for different types of builds.
+</para>
+<para>
+The optional <parameter>name</parameter> argument
+is the base name of the database file(s).
+If not an absolute path name,
+these are placed relative to the directory containing the
+top-level &SConstruct; file.
+The default is
+<filename>.sconsign</filename>.
+The actual database file(s) stored on disk
+may have an appropriate suffix appended
+by the chosen
+<parameter>dbm_module</parameter>
+</para>
+<para>
+The optional <parameter>dbm_module</parameter>
+argument specifies which
+Python database module to use
+for reading/writing the file.
+The module must be imported first;
+then the imported module name
+is passed as the argument.
+The default is a custom
+<systemitem>SCons.dblite</systemitem>
+module that uses pickled
+Python data structures,
+which works on all Python versions.
+See documentation of the Python
+<systemitem>dbm</systemitem> module
+for other available types.
+</para>
+<para>
+If called with no arguments,
+the database will default to
+<filename>.sconsign.dblite</filename>
+in the top directory of the project,
+which is also the default if
+if &f-SConsignFile; is not called.
+</para>
+<para>
+The setting is global, so the only difference
+between the global function and the environment method form
+is variable expansion on <parameter>name</parameter>.
+There should only be one active call to this
+function/method in a given build setup.
</para>
-
<para>
If
-<parameter>file</parameter>
-is
+<parameter>name</parameter>
+is set to
<constant>None</constant>,
-then
&scons;
will store file signatures
in a separate
<filename>.sconsign</filename>
file in each directory,
-not in one global database file.
-(This was the default behavior
-prior to SCons 0.96.91 and 0.97.)
-</para>
-
-<para>
-The optional
-<parameter>dbm_module</parameter>
-argument can be used to specify
-which Python database module
-The default is to use a custom
-<filename>SCons.dblite</filename>
-module that uses pickled
-Python data structures,
-and which works on all Python versions.
+not in a single combined database file.
+This is a backwards-compatibility meaure to support
+what was the default behavior
+prior to &SCons; 0.97 (i.e. before 2008).
+Use of this mode is discouraged and may be
+deprecated in a future &SCons; release.
</para>
<para>
@@ -2803,20 +2821,25 @@ Examples:
<example_commands>
# Explicitly stores signatures in ".sconsign.dblite"
-# in the top-level SConstruct directory (the
-# default behavior).
+# in the top-level SConstruct directory (the default behavior).
SConsignFile()
# Stores signatures in the file "etc/scons-signatures"
# relative to the top-level SConstruct directory.
+# SCons will add a database suffix to this name.
SConsignFile("etc/scons-signatures")
# Stores signatures in the specified absolute file name.
+# SCons will add a database suffix to this name.
SConsignFile("/home/me/SCons/signatures")
# Stores signatures in a separate .sconsign file
# in each directory.
SConsignFile(None)
+
+# Stores signatures in a GNU dbm format .sconsign file
+import dbm.gnu
+SConsignFile(dbm_module=dbm.gnu)
</example_commands>
</summary>
</scons_function>
diff --git a/SCons/Node/FS.py b/SCons/Node/FS.py
index a1b1fa9..4eb658e 100644
--- a/SCons/Node/FS.py
+++ b/SCons/Node/FS.py
@@ -2693,11 +2693,13 @@ class File(Base):
def scanner_key(self):
return self.get_suffix()
- def get_contents(self):
+ def get_contents(self) -> bytes:
+ """Return the contents of the file as bytes."""
return SCons.Node._get_contents_map[self._func_get_contents](self)
- def get_text_contents(self):
- """
+ def get_text_contents(self) -> str:
+ """Return the contents of the file in text form.
+
This attempts to figure out what the encoding of the text is
based upon the BOM bytes, and then decodes the contents so that
it's a valid python string.
@@ -2723,13 +2725,12 @@ class File(Base):
except UnicodeDecodeError as e:
return contents.decode('utf-8', errors='backslashreplace')
-
- def get_content_hash(self):
+ def get_content_hash(self) -> str:
"""
Compute and return the hash for this file.
"""
if not self.rexists():
- return hash_signature('')
+ return hash_signature(SCons.Util.NOFILE)
fname = self.rfile().get_abspath()
try:
cs = hash_file_signature(fname, chunksize=File.hash_chunksize)
@@ -2740,7 +2741,7 @@ class File(Base):
return cs
@SCons.Memoize.CountMethodCall
- def get_size(self):
+ def get_size(self) -> int:
try:
return self._memo['get_size']
except KeyError:
@@ -2749,14 +2750,14 @@ class File(Base):
if self.rexists():
size = self.rfile().getsize()
else:
- size = 0
+ # sentinel value for doesn't exist, even in repository
+ size = -1
self._memo['get_size'] = size
-
return size
@SCons.Memoize.CountMethodCall
- def get_timestamp(self):
+ def get_timestamp(self) -> int:
try:
return self._memo['get_timestamp']
except KeyError:
@@ -2768,7 +2769,6 @@ class File(Base):
timestamp = 0
self._memo['get_timestamp'] = timestamp
-
return timestamp
convert_copy_attrs = [
@@ -2780,7 +2780,6 @@ class File(Base):
'ninfo',
]
-
convert_sig_attrs = [
'bsourcesigs',
'bimplicitsigs',
@@ -3173,7 +3172,7 @@ class File(Base):
# SIGNATURE SUBSYSTEM
#
- def get_max_drift_csig(self):
+ def get_max_drift_csig(self) -> str:
"""
Returns the content signature currently stored for this node
if it's been unmodified longer than the max_drift value, or the
@@ -3199,15 +3198,8 @@ class File(Base):
return None
- def get_csig(self):
- """
- Generate a node's content signature, the digested signature
- of its content.
-
- node - the node
- cache - alternate node to use for the signature cache
- returns - the content signature
- """
+ def get_csig(self) -> str:
+ """Generate a node's content signature."""
ninfo = self.get_ninfo()
try:
return ninfo.csig
@@ -3216,9 +3208,11 @@ class File(Base):
csig = self.get_max_drift_csig()
if csig is None:
-
try:
- if self.get_size() < File.hash_chunksize:
+ size = self.get_size()
+ if size == -1:
+ contents = SCons.Util.NOFILE
+ elif size < File.hash_chunksize:
contents = self.get_contents()
else:
csig = self.get_content_hash()
diff --git a/SCons/Node/FSTests.py b/SCons/Node/FSTests.py
index 457d199..d2a1ebe 100644
--- a/SCons/Node/FSTests.py
+++ b/SCons/Node/FSTests.py
@@ -2686,8 +2686,11 @@ class FileTestCase(_tempdirTestCase):
print("%15s -> csig:%s" % (i3.name, i3.ninfo.csig))
print("%15s -> csig:%s" % (i4.name, i4.ninfo.csig))
- self.assertEqual(i2.name, i2.ninfo.csig,
- "gamma.h's fake csig should equal gamma.h but equals:%s" % i2.ninfo.csig)
+ self.assertEqual(
+ i2.name,
+ i2.ninfo.csig,
+ "gamma.h's fake csig should equal gamma.h but equals:%s" % i2.ninfo.csig,
+ )
class GlobTestCase(_tempdirTestCase):
@@ -3673,7 +3676,8 @@ class CacheDirTestCase(unittest.TestCase):
f9 = fs.File('f9')
r = f9.get_cachedir_csig()
- assert r == 'd41d8cd98f00b204e9800998ecf8427e', r
+ exsig = SCons.Util.MD5signature(SCons.Util.NOFILE)
+ assert r == exsig, r
class clearTestCase(unittest.TestCase):
@@ -3722,6 +3726,13 @@ class clearTestCase(unittest.TestCase):
assert not f.exists()
assert not f.rexists()
assert str(f) == test.workpath('f'), str(f)
+ # Now verify clear() resets optional File-specific attributes
+ optional_attrs = ['cachedir_csig', 'cachesig', 'contentsig']
+ for attr in optional_attrs:
+ setattr(f, attr, 'xyz')
+ f.clear()
+ for attr in optional_attrs:
+ assert not hasattr(f, attr), attr
class disambiguateTestCase(unittest.TestCase):
diff --git a/SCons/Node/NodeTests.py b/SCons/Node/NodeTests.py
index 6e240d4..29a3887 100644
--- a/SCons/Node/NodeTests.py
+++ b/SCons/Node/NodeTests.py
@@ -1297,6 +1297,7 @@ class NodeTestCase(unittest.TestCase):
n.includes = 'testincludes'
n.Tag('found_includes', {'testkey':'testvalue'})
n.implicit = 'testimplicit'
+ n.cached = 1
x = MyExecutor()
n.set_executor(x)
@@ -1304,6 +1305,7 @@ class NodeTestCase(unittest.TestCase):
n.clear()
assert n.includes is None, n.includes
+ assert n.cached == 0, n.cached
assert x.cleaned_up
def test_get_subst_proxy(self):
diff --git a/SCons/Node/Python.py b/SCons/Node/Python.py
index 0eab05c..738682c 100644
--- a/SCons/Node/Python.py
+++ b/SCons/Node/Python.py
@@ -138,7 +138,8 @@ class Value(SCons.Node.Node):
###TODO: something reasonable about universal newlines
contents = str(self.value)
for kid in self.children(None):
- contents = contents + kid.get_contents().decode()
+ # Get csig() value of child as this is more efficent
+ contents = contents + kid.get_csig()
return contents
def get_contents(self) -> bytes:
diff --git a/SCons/Node/__init__.py b/SCons/Node/__init__.py
index 4a53c10..745875d 100644
--- a/SCons/Node/__init__.py
+++ b/SCons/Node/__init__.py
@@ -865,10 +865,12 @@ class Node(object, metaclass=NoSlotsPyPy):
self.clear_memoized_values()
self.ninfo = self.new_ninfo()
self.executor_cleanup()
- try:
- delattr(self, '_calculated_sig')
- except AttributeError:
- pass
+ for attr in ['cachedir_csig', 'cachesig', 'contentsig']:
+ try:
+ delattr(self, attr)
+ except AttributeError:
+ pass
+ self.cached = 0
self.includes = None
def clear_memoized_values(self):
diff --git a/SCons/Util.py b/SCons/Util.py
index 0422e60..b732fbc 100644
--- a/SCons/Util.py
+++ b/SCons/Util.py
@@ -35,6 +35,10 @@ from types import MethodType, FunctionType
PYPY = hasattr(sys, 'pypy_translation_info')
+# this string will be hashed if a Node refers to a file that doesn't exist
+# in order to distinguish from a file that exists but is empty.
+NOFILE = "SCONS_MAGIC_MISSING_FILE_STRING"
+
# unused?
def dictify(keys, values, result=None):
if result is None:
diff --git a/doc/man/sconsign.xml b/doc/man/sconsign.xml
index d2d14c7..726f86e 100644
--- a/doc/man/sconsign.xml
+++ b/doc/man/sconsign.xml
@@ -49,67 +49,58 @@
<refsect1 id='description'><title>DESCRIPTION</title>
-<para>The
-<command>sconsign</command>
-command
-displays the contents of one or more signature database
-(<firstterm>sconsign</firstterm>)
-files used by the <command>scons</command> build tool.
+<para>
+Displays the contents of one or more
+<firstterm>sconsign files</firstterm>,
+the signature database files
+used by the <application>SCons</application> build tool.
</para>
<para>By default,
<command>sconsign</command>
dumps the entire contents of the
sconsign file(s).
-Without the verbose option,
-each entry is printed in the following format:</para>
+Without options,
+individual dependency entries are printed in the following format:</para>
-<literallayout class="monospaced">
-file: signature timestamp length
- implicit_dependency_1: signature timestamp length
- implicit_dependency_2: signature timestamp length
+<screen>
+depfile: signature timestamp length
+ implicit_dependency_1: content_signature timestamp length
+ implicit_dependency_2: content_signature timestamp length
...
action_signature [action string]
-</literallayout>
+</screen>
<para><emphasis role="bold">None</emphasis>
-is printed
-in place of any missing timestamp, <firstterm>build signature</firstterm>
-(<emphasis role="bold">bsig</emphasis>),
-or <firstterm>content signature</firstterm>
+is printed in place of any missing timestamp,
+ <firstterm>content signature</firstterm>
(<emphasis role="bold">csig</emphasis>)
-values for
-any entry
+or
+<firstterm>build action signature</firstterm>
+values for any entry
or any of its dependencies.
If the entry has no implicit dependencies,
or no build action,
-the lines are simply omitted.</para>
-
-<para>
-The verbose option expands the display into a more human
-readable format.
-</para>
+those lines are omitted.</para>
<para>By default,
<command>sconsign</command>
assumes that any
<replaceable>file</replaceable>
arguments that end with a
-<filename>.dbm</filename>
+<filename>.dblite</filename>
suffix contains
signature entries for
more than one directory
(that is,
was specified by the
-<emphasis role="bold">SConsignFile</emphasis>
+<function>SConsignFile</function>
function).
Any
<replaceable>file</replaceable>
-argument that ends in
-<filename>.dblite</filename>
-is assumed to be a traditional
-sconsign
-file containing the signature entries
+argument that has no suffix
+is assumed to be an old-style
+sconsign file containing the signature entries
for a single directory.
If neither of those is true,
<command>sconsign</command>
@@ -127,7 +118,7 @@ If there are no
<replaceable>file</replaceable>
arguments, the name
<filename>.sconsign.dblite</filename>
-is assumed.
+is assumed by default.
</para>
</refsect1>
@@ -145,7 +136,7 @@ and the format:</para>
<option>--action</option>
</term>
<listitem>
-<para>Prints the build action information
+<para>Prints only the build action information
for all entries or the specified entries.</para>
</listitem>
@@ -156,7 +147,7 @@ for all entries or the specified entries.</para>
<option>--csig</option>
</term>
<listitem>
-<para>Prints the content signature (csig) information
+<para>Prints only the content signature (csig) information
for all entries or the specified entries.</para>
</listitem>
@@ -169,11 +160,11 @@ for all entries or the specified entries.</para>
<listitem>
<para>When the signatures are being
read from a
-<filename>.dbm</filename>
+<filename>.dblite</filename>
file, or the
-<option>-f dbm</option>
+<option>-f dblite</option>
or
-<option>--format=dbm</option>
+<option>--format=dblite</option>
options are used,
prints information about
only the signatures
@@ -208,15 +199,15 @@ options are specified on the command line.</para>
are in the specified
<replaceable>FORMAT</replaceable>.
Legal values are
-<emphasis role="bold">dbm</emphasis>
-(the DBM format used
-when the
-<emphasis role="bold">SConsignFile</emphasis>
-function is used)
-or
-<command>sconsign</command>
-(the default format
-used for an individual
+<emphasis role="bold">dblite</emphasis>
+(the SCons.dblite format used by default,
+as well as when the
+<function>SConsignFile</function>
+function is called, except when a filename argument
+of <constant>None</constant> is given)
+and
+<emphasis role="bold">sconsign</emphasis>
+(the format used for an individual
<filename>.sconsign</filename>
file in each directory).</para>
diff --git a/test/SConsignFile/default.py b/test/SConsignFile/default.py
index ed1ed56..868f9d7 100644
--- a/test/SConsignFile/default.py
+++ b/test/SConsignFile/default.py
@@ -1,6 +1,8 @@
#!/usr/bin/env python
#
-# __COPYRIGHT__
+# MIT License
+#
+# Copyright The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
@@ -20,13 +22,8 @@
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-"""
-Verify the default behavior of SConsignFile(), called with no arguments.
-"""
+"""Verify the default behavior of SConsignFile() called with no arguments."""
import TestSCons
@@ -46,12 +43,13 @@ sys.exit(0)
#
test.write('SConstruct', """
SConsignFile()
-B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES')
-env = Environment(BUILDERS = { 'B' : B })
-env.B(target = 'f1.out', source = 'f1.in')
-env.B(target = 'f2.out', source = 'f2.in')
-env.B(target = 'subdir/f3.out', source = 'subdir/f3.in')
-env.B(target = 'subdir/f4.out', source = 'subdir/f4.in')
+DefaultEnvironment(tools=[])
+B = Builder(action=r'%(_python_)s build.py $TARGETS $SOURCES')
+env = Environment(BUILDERS={'B': B}, tools=[])
+env.B(target='f1.out', source='f1.in')
+env.B(target='f2.out', source='f2.in')
+env.B(target='subdir/f3.out', source='subdir/f3.in')
+env.B(target='subdir/f4.out', source='subdir/f4.in')
""" % locals())
test.write('f1.in', "f1.in\n")
@@ -70,7 +68,7 @@ test.must_match('f2.out', "f2.in\n")
test.must_match(['subdir', 'f3.out'], "subdir/f3.in\n")
test.must_match(['subdir', 'f4.out'], "subdir/f4.in\n")
-test.up_to_date(arguments = '.')
+test.up_to_date(arguments='.')
test.must_exist(test.workpath('.sconsign.dblite'))
test.must_not_exist(test.workpath('.sconsign'))
diff --git a/test/SConsignFile/explicit-dbm-module.py b/test/SConsignFile/explicit-dbm-module.py
new file mode 100644
index 0000000..c093271
--- /dev/null
+++ b/test/SConsignFile/explicit-dbm-module.py
@@ -0,0 +1,85 @@
+#!/usr/bin/env python
+#
+# MIT License
+#
+# Copyright The SCons Foundation
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+"""Verify SConsignFile() when used with explicit SCons.dblite."""
+
+import TestSCons
+
+_python_ = TestSCons._python_
+
+test = TestSCons.TestSCons()
+
+use_db = 'SCons.dblite'
+
+test.subdir('subdir')
+
+test.write('build.py', r"""
+import sys
+with open(sys.argv[1], 'wb') as ofp, open(sys.argv[2], 'rb') as ifp:
+ ofp.write(ifp.read())
+sys.exit(0)
+""")
+
+test.write('SConstruct', """
+import %(use_db)s
+SConsignFile(dbm_module=%(use_db)s)
+DefaultEnvironment(tools=[])
+B = Builder(action=r'%(_python_)s build.py $TARGETS $SOURCES')
+env = Environment(BUILDERS={'B': B}, tools=[])
+env.B(target='f1.out', source='f1.in')
+env.B(target='f2.out', source='f2.in')
+env.B(target='subdir/f3.out', source='subdir/f3.in')
+env.B(target='subdir/f4.out', source='subdir/f4.in')
+""" % locals())
+
+test.write('f1.in', "f1.in\n")
+test.write('f2.in', "f2.in\n")
+test.write(['subdir', 'f3.in'], "subdir/f3.in\n")
+test.write(['subdir', 'f4.in'], "subdir/f4.in\n")
+
+test.run()
+
+test.must_exist(test.workpath('.sconsign.dblite'))
+test.must_not_exist(test.workpath('.sconsign'))
+test.must_not_exist(test.workpath('subdir', '.sconsign'))
+
+test.must_match('f1.out', "f1.in\n")
+test.must_match('f2.out', "f2.in\n")
+test.must_match(['subdir', 'f3.out'], "subdir/f3.in\n")
+test.must_match(['subdir', 'f4.out'], "subdir/f4.in\n")
+
+test.up_to_date(arguments='.')
+
+test.must_exist(test.workpath('.sconsign.dblite'))
+test.must_not_exist(test.workpath('.sconsign'))
+test.must_not_exist(test.workpath('subdir', '.sconsign'))
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/SConsignFile/explicit-file.py b/test/SConsignFile/explicit-file.py
index afb2dbd..850b0ef 100644
--- a/test/SConsignFile/explicit-file.py
+++ b/test/SConsignFile/explicit-file.py
@@ -1,6 +1,8 @@
#!/usr/bin/env python
#
-# __COPYRIGHT__
+# MIT License
+#
+# Copyright The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
@@ -20,13 +22,8 @@
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-"""
-Verify the default behavior of SConsignFile(), called with no arguments.
-"""
+"""Verify the behavior of env.SConsignFile() called with a subst-able path."""
import TestSCons
@@ -44,14 +41,15 @@ with open(sys.argv[1], 'wb') as ofp, open(sys.argv[2], 'rb') as ifp:
#
test.write('SConstruct', """
-e = Environment(XXX = 'scons')
+DefaultEnvironment(tools=[])
+e = Environment(XXX='scons', tools=[])
e.SConsignFile('my_${XXX}ign')
-B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES')
-env = Environment(BUILDERS = { 'B' : B })
-env.B(target = 'f5.out', source = 'f5.in')
-env.B(target = 'f6.out', source = 'f6.in')
-env.B(target = 'subdir/f7.out', source = 'subdir/f7.in')
-env.B(target = 'subdir/f8.out', source = 'subdir/f8.in')
+B = Builder(action=r'%(_python_)s build.py $TARGETS $SOURCES')
+env = Environment(BUILDERS={'B': B}, tools=[])
+env.B(target='f5.out', source='f5.in')
+env.B(target='f6.out', source='f6.in')
+env.B(target='subdir/f7.out', source='subdir/f7.in')
+env.B(target='subdir/f8.out', source='subdir/f8.in')
""" % locals())
test.write('f5.in', "f5.in\n")
@@ -70,7 +68,7 @@ test.must_match('f6.out', "f6.in\n")
test.must_match(['subdir', 'f7.out'], "subdir/f7.in\n")
test.must_match(['subdir', 'f8.out'], "subdir/f8.in\n")
-test.up_to_date(arguments = '.')
+test.up_to_date(arguments='.')
test.must_exist(test.workpath('my_sconsign.dblite'))
test.must_not_exist(test.workpath('.sconsign'))
diff --git a/test/SConsignFile/make-directory.py b/test/SConsignFile/make-directory.py
index 50bab79..264ee26 100644
--- a/test/SConsignFile/make-directory.py
+++ b/test/SConsignFile/make-directory.py
@@ -1,6 +1,8 @@
#!/usr/bin/env python
#
-# __COPYRIGHT__
+# MIT License
+#
+# Copyright The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
@@ -20,9 +22,6 @@
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
"""
Verify the ability to make a SConsignFile() in a non-existent
@@ -40,15 +39,17 @@ bar_foo_txt = os.path.join('bar', 'foo.txt')
test.write('SConstruct', """
import SCons.dblite
-env = Environment()
+DefaultEnvironment(tools=[])
+env = Environment(tools=[])
env.SConsignFile("sub/dir/sconsign", SCons.dblite)
env.Install('bar', 'foo.txt')
""")
test.write('foo.txt', "Foo\n")
-
-expect = test.wrap_stdout(read_str = 'Mkdir("%s")\n' % sub_dir,
- build_str = 'Install file: "foo.txt" as "%s"\n' % bar_foo_txt)
+expect = test.wrap_stdout(
+ read_str='Mkdir("%s")\n' % sub_dir,
+ build_str='Install file: "foo.txt" as "%s"\n' % bar_foo_txt,
+)
test.run(options='-n', stdout=expect)
diff --git a/test/SConsignFile/use-dbhash.py b/test/SConsignFile/use-dbhash.py
index e57e244..2968cd7 100644
--- a/test/SConsignFile/use-dbhash.py
+++ b/test/SConsignFile/use-dbhash.py
@@ -1,6 +1,8 @@
#!/usr/bin/env python
#
-# __COPYRIGHT__
+# MIT License
+#
+# Copyright The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
@@ -20,9 +22,6 @@
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
"""
Verify SConsignFile() when used with dbhash.
@@ -36,8 +35,9 @@ test = TestSCons.TestSCons()
try:
import dbm.bsd
+ use_dbm = 'dbm.bsd'
except ImportError:
- test.skip_test('No dbhash in this version of Python; skipping test.\n')
+ test.skip_test('No dbm.bsd in this version of Python; skipping test.\n')
test.subdir('subdir')
@@ -50,11 +50,11 @@ sys.exit(0)
#
test.write('SConstruct', """
-import sys
-import dbhash
-SConsignFile('.sconsign', dbhash)
+import %(use_dbm)s
+SConsignFile('.sconsign', %(use_dbm)s)
+DefaultEnvironment(tools=[])
B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES')
-env = Environment(BUILDERS = { 'B' : B })
+env = Environment(BUILDERS={'B': B}, tools=[])
env.B(target = 'f1.out', source = 'f1.in')
env.B(target = 'f2.out', source = 'f2.in')
env.B(target = 'subdir/f3.out', source = 'subdir/f3.in')
diff --git a/test/SConsignFile/use-dbm.py b/test/SConsignFile/use-dbm.py
index 5100916..a1ef1b2 100644
--- a/test/SConsignFile/use-dbm.py
+++ b/test/SConsignFile/use-dbm.py
@@ -1,6 +1,8 @@
#!/usr/bin/env python
#
-# __COPYRIGHT__
+# MIT License
+#
+# Copyright The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
@@ -20,9 +22,6 @@
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
"""
Verify SConsignFile() when used with dbm.
@@ -37,15 +36,9 @@ test = TestSCons.TestSCons()
try:
import dbm.ndbm
-
- use_db = 'dbm.ndbm'
+ use_dbm = 'dbm.ndbm'
except ImportError:
- try:
- import dbm
-
- use_db = 'dbm'
- except ImportError:
- test.skip_test('No dbm.ndbm in this version of Python; skipping test.\n')
+ test.skip_test('No dbm.ndbm in this version of Python; skipping test.\n')
test.subdir('subdir')
@@ -58,16 +51,15 @@ sys.exit(0)
#
test.write('SConstruct', """
-import sys
-import %(use_db)s
-SConsignFile('.sconsign', %(use_db)s)
-B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES')
+import %(use_dbm)s
+SConsignFile('.sconsign', %(use_dbm)s)
DefaultEnvironment(tools=[])
-env = Environment(BUILDERS = { 'B' : B }, tools=[])
-env.B(target = 'f1.out', source = 'f1.in')
-env.B(target = 'f2.out', source = 'f2.in')
-env.B(target = 'subdir/f3.out', source = 'subdir/f3.in')
-env.B(target = 'subdir/f4.out', source = 'subdir/f4.in')
+B = Builder(action=r'%(_python_)s build.py $TARGETS $SOURCES')
+env = Environment(BUILDERS={'B': B}, tools=[])
+env.B(target='f1.out', source='f1.in')
+env.B(target='f2.out', source='f2.in')
+env.B(target='subdir/f3.out', source='subdir/f3.in')
+env.B(target='subdir/f4.out', source='subdir/f4.in')
""" % locals())
test.write('f1.in', "f1.in\n")
@@ -80,8 +72,10 @@ test.run()
# We don't check for explicit .db or other file, because base "dbm"
# can use different file extensions on different implementations.
-test.fail_test(os.path.exists('.sconsign') and 'dbm' not in dbm.whichdb('.sconsign'),
- message=".sconsign existed and wasn't any type of dbm file")
+test.fail_test(
+ os.path.exists('.sconsign') and 'dbm' not in dbm.whichdb('.sconsign'),
+ message=".sconsign existed and wasn't any type of dbm file",
+)
test.must_not_exist(test.workpath('.sconsign.dblite'))
test.must_not_exist(test.workpath('subdir', '.sconsign'))
test.must_not_exist(test.workpath('subdir', '.sconsign.dblite'))
diff --git a/test/SConsignFile/use-dumbdbm.py b/test/SConsignFile/use-dumbdbm.py
index 22b0bff..875f3fc 100644
--- a/test/SConsignFile/use-dumbdbm.py
+++ b/test/SConsignFile/use-dumbdbm.py
@@ -1,6 +1,8 @@
#!/usr/bin/env python
#
-# __COPYRIGHT__
+# MIT License
+#
+# Copyright The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
@@ -20,9 +22,6 @@
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
"""
Verify SConsignFile() when used with dumbdbm.
@@ -36,7 +35,7 @@ test = TestSCons.TestSCons()
try:
import dbm.dumb
- use_dbm='dbm.dumb'
+ use_dbm = 'dbm.dumb'
except ImportError:
test.skip_test('No dbm.dumb in this version of Python; skipping test.\n')
@@ -51,15 +50,15 @@ sys.exit(0)
#
test.write('SConstruct', """
-import sys
import %(use_dbm)s
SConsignFile('.sconsign', %(use_dbm)s)
-B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES')
-env = Environment(BUILDERS = { 'B' : B })
-env.B(target = 'f1.out', source = 'f1.in')
-env.B(target = 'f2.out', source = 'f2.in')
-env.B(target = 'subdir/f3.out', source = 'subdir/f3.in')
-env.B(target = 'subdir/f4.out', source = 'subdir/f4.in')
+DefaultEnvironment(tools=[])
+B = Builder(action=r'%(_python_)s build.py $TARGETS $SOURCES')
+env = Environment(BUILDERS={'B': B}, tools=[])
+env.B(target='f1.out', source='f1.in')
+env.B(target='f2.out', source='f2.in')
+env.B(target='subdir/f3.out', source='subdir/f3.in')
+env.B(target='subdir/f4.out', source='subdir/f4.in')
""" % locals())
test.write('f1.in', "f1.in\n")
@@ -83,7 +82,7 @@ test.must_match('f2.out', "f2.in\n")
test.must_match(['subdir', 'f3.out'], "subdir/f3.in\n")
test.must_match(['subdir', 'f4.out'], "subdir/f4.in\n")
-test.up_to_date(arguments = '.')
+test.up_to_date(arguments='.')
test.must_exist(test.workpath('.sconsign.dat'))
test.must_exist(test.workpath('.sconsign.dir'))
diff --git a/test/SConsignFile/use-gdbm.py b/test/SConsignFile/use-gdbm.py
index 461a482..c1f0c4d 100644
--- a/test/SConsignFile/use-gdbm.py
+++ b/test/SConsignFile/use-gdbm.py
@@ -1,6 +1,8 @@
#!/usr/bin/env python
#
-# __COPYRIGHT__
+# MIT License
+#
+# Copyright The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
@@ -20,9 +22,6 @@
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
"""
Verify SConsignFile() when used with gdbm.
@@ -51,15 +50,15 @@ sys.exit(0)
#
test.write('SConstruct', """
-import sys
import %(use_dbm)s
SConsignFile('.sconsign', %(use_dbm)s)
-B = Builder(action = '%(_python_)s build.py $TARGETS $SOURCES')
-env = Environment(BUILDERS = { 'B' : B })
-env.B(target = 'f1.out', source = 'f1.in')
-env.B(target = 'f2.out', source = 'f2.in')
-env.B(target = 'subdir/f3.out', source = 'subdir/f3.in')
-env.B(target = 'subdir/f4.out', source = 'subdir/f4.in')
+DefaultEnvironment(tools=[])
+B = Builder(action='%(_python_)s build.py $TARGETS $SOURCES')
+env = Environment(BUILDERS={'B': B}, tools=[])
+env.B(target='f1.out', source='f1.in')
+env.B(target='f2.out', source='f2.in')
+env.B(target='subdir/f3.out', source='subdir/f3.in')
+env.B(target='subdir/f4.out', source='subdir/f4.in')
""" % locals())
test.write('f1.in', "f1.in\n")
@@ -79,7 +78,7 @@ test.must_match('f2.out', "f2.in\n")
test.must_match(['subdir', 'f3.out'], "subdir/f3.in\n")
test.must_match(['subdir', 'f4.out'], "subdir/f4.in\n")
-test.up_to_date(arguments = '.')
+test.up_to_date(arguments='.')
test.must_exist(test.workpath('.sconsign'))
test.must_not_exist(test.workpath('.sconsign.dblite'))
diff --git a/test/Value/GetContent.py b/test/Value/GetContent.py
new file mode 100644
index 0000000..8fbbf29
--- /dev/null
+++ b/test/Value/GetContent.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test the Value node as a build target
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.write('SConstruct', """
+import SCons.Script
+def null_build(target, source, env):
+ pass
+env = DefaultEnvironment()
+env['BUILDERS']['ValueBuilder'] = SCons.Builder.Builder(
+ action=SCons.Action.Action(null_build),
+ target_factory=SCons.Node.Python.Value,
+)
+v = env.ValueBuilder("myvalue",env.Dir("#"))
+v[0].get_text_contents()
+""")
+
+test.run()
+test.pass_test()
+