From ca75f94e83c37ca03de9740bb141e442c53db235 Mon Sep 17 00:00:00 2001 From: Steven Knight Date: Thu, 24 Jan 2002 20:02:15 +0000 Subject: Add the Precious() method. --- src/CHANGES.txt | 3 + src/engine/SCons/Environment.py | 15 ++++- src/engine/SCons/EnvironmentTests.py | 20 ++++++- src/engine/SCons/Node/FS.py | 5 ++ src/engine/SCons/Node/FSTests.py | 6 ++ src/engine/SCons/Node/NodeTests.py | 9 +++ src/engine/SCons/Node/__init__.py | 11 ++++ test/Precious.py | 112 +++++++++++++++++++++++++++++++++++ 8 files changed, 175 insertions(+), 6 deletions(-) create mode 100644 test/Precious.py diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 9e2591b..cd3ebd4 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -54,6 +54,9 @@ RELEASE 0.04 - - Provide an error message when a nonexistent target is specified on the command line. + - Remove targets before building them, and add an Environment + Precious() method to override that. + From Steve Leblanc: - Add var=value command-line arguments. diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 3c1ee43..6373a55 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -66,9 +66,6 @@ def installFunc(env, target, source): InstallBuilder = SCons.Builder.Builder(name='Install', action=installFunc) -def InstallAs(): - pass # XXX - def our_deepcopy(x): """deepcopy lists and dictionaries, and just copy the reference for everything else.""" @@ -185,6 +182,18 @@ class Environment: tlist = tlist[0] return tlist + def Precious(self, *targets): + tlist = [] + for t in targets: + tlist.extend(SCons.Util.scons_str2nodes(t)) + + for t in tlist: + t.set_precious() + + if len(tlist) == 1: + tlist = tlist[0] + return tlist + def Dictionary(self, *args): if not args: return self._dict diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index 59f3c78..def5998 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -233,9 +233,6 @@ class EnvironmentTestCase(unittest.TestCase): assert paths == expect, paths for tnode in tgt: assert tnode.builder == InstallBuilder - - def test_InstallAs(self): - pass # XXX def test_Update(self): """Test updating an Environment with new construction variables @@ -269,6 +266,23 @@ class EnvironmentTestCase(unittest.TestCase): assert i.__class__.__name__ == 'File' assert i.path == 'dep.py' + def test_Precious(self): + """Test the Precious() method.""" + env = Environment() + t = env.Precious('a', 'b', ['c', 'd']) + assert t[0].__class__.__name__ == 'File' + assert t[0].path == 'a' + assert t[0].precious + assert t[1].__class__.__name__ == 'File' + assert t[1].path == 'b' + assert t[1].precious + assert t[2].__class__.__name__ == 'File' + assert t[2].path == 'c' + assert t[2].precious + assert t[3].__class__.__name__ == 'File' + assert t[3].path == 'd' + assert t[3].precious + def test_Command(self): """Test the Command() method.""" env = Environment() diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 2ce1151..7c19b81 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -566,5 +566,10 @@ class File(Entry): Entry.build(self) self.exists_flag = self.exists() + def remove(self): + """Remove this file.""" + if self.exists(): + os.unlink(self.path) + default_fs = FS() diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index 12dfdbe..2b3ba37 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -438,6 +438,12 @@ class FSTestCase(unittest.TestCase): nonexistent(fs.Dir, 'nonexistent') nonexistent(fs.Dir, 'nonexistent/foo') + test.write("remove_me", "\n") + assert os.path.exists(test.workpath("remove_me")) + f1 = fs.File(test.workpath("remove_me")) + f1.remove() + assert not os.path.exists(test.workpath("remove_me")) + #XXX test current() for directories #XXX test sconsign() for directories diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py index aa9dccb..bcaf1a0 100644 --- a/src/engine/SCons/Node/NodeTests.py +++ b/src/engine/SCons/Node/NodeTests.py @@ -206,6 +206,15 @@ class NodeTestCase(unittest.TestCase): node.set_csig('zzz') assert node.get_csig() == 'zzz' + def test_set_precious(self): + """Test setting a Node's precious value + """ + node = SCons.Node.Node() + node.set_precious() + assert node.precious + node.set_precious(7) + assert node.precious == 7 + def test_add_dependency(self): """Test adding dependencies to a Node's list. """ diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index 03705f7..02c14bb 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -70,11 +70,14 @@ class Node: self.bsig = None self.csig = None self.use_signature = 1 + self.precious = None def build(self): """Actually build the node. Return the status from the build.""" if not self.builder: return None + if not self.precious: + self.remove() try: stat = self.builder.execute(env = self.env.Dictionary(), target = self, source = self.sources) @@ -164,6 +167,14 @@ class Node: """Set the signature of the node's content.""" self.csig = csig + def set_precious(self, precious = 1): + """Set the Node's precious value.""" + self.precious = precious + + def remove(self): + """Remove this Node's external object: no-op by default.""" + pass + def add_dependency(self, depend): """Adds dependencies. The depend argument must be a list.""" self._add_child(self.depends, depend) diff --git a/test/Precious.py b/test/Precious.py new file mode 100644 index 0000000..4517198 --- /dev/null +++ b/test/Precious.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# +# Copyright (c) 2001 Steven Knight +# +# 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__" + +import os +import sys +import TestSCons + +python = sys.executable + +test = TestSCons.TestSCons() + +test.subdir('subdir') + +test.write('build.py', r""" +import sys +sys.exit(0) +""") + +test.write('SConstruct', """ +B = Builder(name = "B", action = r"%s build.py $TARGET $SOURCES") +env = Environment(BUILDERS = [B]) +f1 = env.B(target = 'f1.out', source = 'f1.in') +env.B(target = 'f2.out', source = 'f2.in') +env.B(target = 'f3.out', source = 'f3.in') +env.Precious(f1, 'f2.out') +SConscript('subdir/SConscript', "env") +""" % python) + +test.write(['subdir', 'SConscript'], """ +Import("env") +env.B(target = 'f4.out', source = 'f4.in') +f5 = env.B(target = 'f5.out', source = 'f5.in') +env.B(target = 'f6.out', source = 'f6.in') +env.Precious(['f4.out', f5]) +""") + +test.write('f1.in', "f1.in\n") +test.write('f2.in', "f2.in\n") +test.write('f3.in', "f3.in\n") + +test.write(['subdir', 'f4.in'], "subdir/f4.in\n") +test.write(['subdir', 'f5.in'], "subdir/f5.in\n") +test.write(['subdir', 'f6.in'], "subdir/f6.in\n") + +test.write('f1.out', "SHOULD NOT BE REMOVED\n") +test.write('f2.out', "SHOULD NOT BE REMOVED\n") +test.write('f3.out', "SHOULD BE REMOVED\n") + +test.write(['subdir', 'f4.out'], "SHOULD NOT BE REMOVED\n") +test.write(['subdir', 'f5.out'], "SHOULD NOT BE REMOVED\n") +test.write(['subdir', 'f6.out'], "SHOULD BE REMOVED\n") + +test.run(arguments = '.') + +test.fail_test(not os.path.exists(test.workpath('f1.out'))) +test.fail_test(not os.path.exists(test.workpath('f2.out'))) +test.fail_test(os.path.exists(test.workpath('f3.out'))) + +test.fail_test(not os.path.exists(test.workpath('subdir', 'f4.out'))) +test.fail_test(not os.path.exists(test.workpath('subdir', 'f5.out'))) +test.fail_test(os.path.exists(test.workpath('subdir', 'f6.out'))) + +test.write('f3.out', "SHOULD BE REMOVED\n") +test.write(['subdir', 'f6.out'], "SHOULD BE REMOVED\n") + +test.run(arguments = '.') + +test.fail_test(not os.path.exists(test.workpath('f1.out'))) +test.fail_test(not os.path.exists(test.workpath('f2.out'))) +test.fail_test(not os.path.exists(test.workpath('f3.out'))) + +test.fail_test(not os.path.exists(test.workpath('subdir', 'f4.out'))) +test.fail_test(not os.path.exists(test.workpath('subdir', 'f5.out'))) +test.fail_test(not os.path.exists(test.workpath('subdir', 'f6.out'))) + +test.write('f3.in', "f3.in 2\n") +test.write(['subdir', 'f6.in'], "subdir/f6.in 2\n") + +test.run(arguments = '.') + +test.fail_test(not os.path.exists(test.workpath('f1.out'))) +test.fail_test(not os.path.exists(test.workpath('f2.out'))) +test.fail_test(os.path.exists(test.workpath('f3.out'))) + +test.fail_test(not os.path.exists(test.workpath('subdir', 'f4.out'))) +test.fail_test(not os.path.exists(test.workpath('subdir', 'f5.out'))) +test.fail_test(os.path.exists(test.workpath('subdir', 'f6.out'))) + +test.pass_test() -- cgit v0.12