diff options
-rwxr-xr-x | CHANGES.txt | 25 | ||||
-rw-r--r-- | SCons/Environment.xml | 107 | ||||
-rw-r--r-- | SCons/Node/FS.py | 42 | ||||
-rw-r--r-- | SCons/Node/FSTests.py | 17 | ||||
-rw-r--r-- | SCons/Node/NodeTests.py | 2 | ||||
-rw-r--r-- | SCons/Node/Python.py | 3 | ||||
-rw-r--r-- | SCons/Node/__init__.py | 10 | ||||
-rw-r--r-- | SCons/Util.py | 4 | ||||
-rw-r--r-- | doc/man/sconsign.xml | 85 | ||||
-rw-r--r-- | test/SConsignFile/default.py | 26 | ||||
-rw-r--r-- | test/SConsignFile/explicit-dbm-module.py | 85 | ||||
-rw-r--r-- | test/SConsignFile/explicit-file.py | 28 | ||||
-rw-r--r-- | test/SConsignFile/make-directory.py | 17 | ||||
-rw-r--r-- | test/SConsignFile/use-dbhash.py | 18 | ||||
-rw-r--r-- | test/SConsignFile/use-dbm.py | 40 | ||||
-rw-r--r-- | test/SConsignFile/use-dumbdbm.py | 25 | ||||
-rw-r--r-- | test/SConsignFile/use-gdbm.py | 23 | ||||
-rw-r--r-- | test/Value/GetContent.py | 50 |
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() + |