summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2006-01-22 03:13:50 (GMT)
committerSteven Knight <knight@baldmt.com>2006-01-22 03:13:50 (GMT)
commite74b9f5c157debd627779d45833348cb16fd7b72 (patch)
treefd403afaf18556a1607fcc9d729719d3c2e5ddcb
parent6fdb91f7abaaf0823070d17c8afcde6ca35d3549 (diff)
downloadSCons-e74b9f5c157debd627779d45833348cb16fd7b72.zip
SCons-e74b9f5c157debd627779d45833348cb16fd7b72.tar.gz
SCons-e74b9f5c157debd627779d45833348cb16fd7b72.tar.bz2
Refactor NodeInfo and BuildInfo handling to prepare for signature refactoring.
-rw-r--r--src/engine/SCons/Node/Alias.py10
-rw-r--r--src/engine/SCons/Node/AliasTests.py22
-rw-r--r--src/engine/SCons/Node/FS.py35
-rw-r--r--src/engine/SCons/Node/FSTests.py82
-rw-r--r--src/engine/SCons/Node/NodeTests.py52
-rw-r--r--src/engine/SCons/Node/Python.py10
-rw-r--r--src/engine/SCons/Node/PythonTests.py21
-rw-r--r--src/engine/SCons/Node/__init__.py24
-rw-r--r--src/engine/SCons/SConf.py4
9 files changed, 184 insertions, 76 deletions
diff --git a/src/engine/SCons/Node/Alias.py b/src/engine/SCons/Node/Alias.py
index e023ab7..6d4440b 100644
--- a/src/engine/SCons/Node/Alias.py
+++ b/src/engine/SCons/Node/Alias.py
@@ -56,7 +56,17 @@ class AliasNameSpace(UserDict.UserDict):
except KeyError:
return None
+class AliasNodeInfo(SCons.Node.NodeInfoBase):
+ pass
+
+class AliasBuildInfo(SCons.Node.BuildInfoBase):
+ pass
+
class Alias(SCons.Node.Node):
+
+ NodeInfo = AliasNodeInfo
+ BuildInfo = AliasBuildInfo
+
def __init__(self, name):
SCons.Node.Node.__init__(self)
self.name = name
diff --git a/src/engine/SCons/Node/AliasTests.py b/src/engine/SCons/Node/AliasTests.py
index 9a12766..755cf75 100644
--- a/src/engine/SCons/Node/AliasTests.py
+++ b/src/engine/SCons/Node/AliasTests.py
@@ -94,9 +94,29 @@ class AliasTestCase(unittest.TestCase):
assert not a1 is a2
assert a1.name == a2.name
+class AliasNodeInfoTestCase(unittest.TestCase):
+ def test___init__(self):
+ """Test AliasNodeInfo initialization"""
+ ans = SCons.Node.Alias.AliasNameSpace()
+ aaa = ans.Alias('aaa')
+ ni = SCons.Node.Alias.AliasNodeInfo(aaa)
+class AliasBuildInfoTestCase(unittest.TestCase):
+ def test___init__(self):
+ """Test AliasBuildInfo initialization"""
+ ans = SCons.Node.Alias.AliasNameSpace()
+ aaa = ans.Alias('aaa')
+ bi = SCons.Node.Alias.AliasBuildInfo(aaa)
if __name__ == "__main__":
- suite = unittest.makeSuite(AliasTestCase, 'test_')
+ suite = unittest.TestSuite()
+ tclasses = [
+ AliasTestCase,
+ AliasBuildInfoTestCase,
+ AliasNodeInfoTestCase,
+ ]
+ for tclass in tclasses:
+ names = unittest.getTestCaseNames(tclass, 'test_')
+ suite.addTests(map(tclass, names))
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py
index 3d70c7c..1260602 100644
--- a/src/engine/SCons/Node/FS.py
+++ b/src/engine/SCons/Node/FS.py
@@ -1156,10 +1156,19 @@ class FS(LocalFS):
message = fmt % string.join(map(str, targets))
return targets, message
+class DirNodeInfo(SCons.Node.NodeInfoBase):
+ pass
+
+class DirBuildInfo(SCons.Node.BuildInfoBase):
+ pass
+
class Dir(Base):
"""A class for directories in a file system.
"""
+ NodeInfo = DirNodeInfo
+ BuildInfo = DirBuildInfo
+
def __init__(self, name, directory, fs):
if __debug__: logInstanceCreation(self, 'Node.FS.Dir')
Base.__init__(self, name, directory, fs)
@@ -1579,7 +1588,10 @@ class RootDir(Dir):
def src_builder(self):
return _null
-class NodeInfo(SCons.Node.NodeInfo):
+class FileNodeInfo(SCons.Node.NodeInfoBase):
+ def __init__(self, node):
+ SCons.Node.NodeInfoBase.__init__(self, node)
+ self.update(node)
def __cmp__(self, other):
try: return cmp(self.bsig, other.bsig)
except AttributeError: return 1
@@ -1587,9 +1599,9 @@ class NodeInfo(SCons.Node.NodeInfo):
self.timestamp = node.get_timestamp()
self.size = node.getsize()
-class BuildInfo(SCons.Node.BuildInfo):
+class FileBuildInfo(SCons.Node.BuildInfoBase):
def __init__(self, node):
- SCons.Node.BuildInfo.__init__(self, node)
+ SCons.Node.BuildInfoBase.__init__(self, node)
self.node = node
def convert_to_sconsign(self):
"""Convert this BuildInfo object for writing to a .sconsign file
@@ -1635,10 +1647,19 @@ class BuildInfo(SCons.Node.BuildInfo):
result.append(str(bkids[i]) + ': ' + bkidsigs[i].format())
return string.join(result, '\n')
+class NodeInfo(FileNodeInfo):
+ pass
+
+class BuildInfo(FileBuildInfo):
+ pass
class File(Base):
"""A class for files in a file system.
"""
+
+ NodeInfo = FileNodeInfo
+ BuildInfo = FileBuildInfo
+
def diskcheck_match(self):
diskcheck_match(self, self.fs.isdir,
"Directory %s found where file expected.")
@@ -1920,14 +1941,6 @@ class File(Base):
# SIGNATURE SUBSYSTEM
#
- def new_binfo(self):
- return BuildInfo(self)
-
- def new_ninfo(self):
- ninfo = NodeInfo()
- ninfo.update(self)
- return ninfo
-
def get_csig(self, calc=None):
"""
Generate a node's content signature, the digested signature
diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py
index 96fa490..12be4b9 100644
--- a/src/engine/SCons/Node/FSTests.py
+++ b/src/engine/SCons/Node/FSTests.py
@@ -698,16 +698,33 @@ class BaseTestCase(_tempdirTestCase):
nonexistent = fs.Entry('nonexistent')
assert not nonexistent.islink()
-class NodeInfoTestCase(_tempdirTestCase):
+class DirNodeInfoTestCase(_tempdirTestCase):
def test___init__(self):
- """Test NodeInfo initialization"""
- ni = SCons.Node.FS.NodeInfo()
- assert not hasattr(ni, 'bsig')
+ """Test DirNodeInfo initialization"""
+ ddd = self.fs.Dir('ddd')
+ ni = SCons.Node.FS.DirNodeInfo(ddd)
+
+class DirBuildInfoTestCase(_tempdirTestCase):
+ def test___init__(self):
+ """Test DirBuildInfo initialization"""
+ ddd = self.fs.Dir('ddd')
+ bi = SCons.Node.FS.DirBuildInfo(ddd)
+
+class FileNodeInfoTestCase(_tempdirTestCase):
+ def test___init__(self):
+ """Test FileNodeInfo initialization"""
+ fff = self.fs.File('fff')
+ ni = SCons.Node.FS.FileNodeInfo(fff)
+ assert hasattr(ni, 'timestamp')
+ assert hasattr(ni, 'size')
def test___cmp__(self):
- """Test comparing NodeInfo objects"""
- ni1 = SCons.Node.FS.NodeInfo()
- ni2 = SCons.Node.FS.NodeInfo()
+ """Test comparing File.NodeInfo objects"""
+ f1 = self.fs.File('f1')
+ f2 = self.fs.File('f2')
+
+ ni1 = SCons.Node.FS.FileNodeInfo(f1)
+ ni2 = SCons.Node.FS.FileNodeInfo(f2)
msg = "cmp(%s, %s) returned %s, not %s"
@@ -731,22 +748,29 @@ class NodeInfoTestCase(_tempdirTestCase):
assert c == -1, msg % (ni1.bsig, ni2.bsig, c, -1)
def test_update(self):
- """Test updating a NodeInfo with on-disk information"""
+ """Test updating a File.NodeInfo with on-disk information"""
test = self.test
- test.write('fff', "fff\n")
fff = self.fs.File('fff')
- ni = SCons.Node.FS.NodeInfo()
- assert not hasattr(ni, 'timestamp')
- assert not hasattr(ni, 'size')
+ ni = SCons.Node.FS.FileNodeInfo(fff)
+ import time
+ time.sleep(2)
+
+ test.write('fff', "fff\n")
+
+ assert ni.timestamp != os.path.getmtime('fff'), ni.timestamp
+ assert ni.size != os.path.getsize('fff'), ni.size
+
+ fff.clear()
ni.update(fff)
+
assert ni.timestamp == os.path.getmtime('fff'), ni.timestamp
assert ni.size == os.path.getsize('fff'), ni.size
-class BuildInfoTestCase(_tempdirTestCase):
+class FileBuildInfoTestCase(_tempdirTestCase):
def test___init__(self):
- """Test BuildInfo initialization"""
+ """Test File.BuildInfo initialization"""
fff = self.fs.File('fff')
bi = SCons.Node.FS.BuildInfo(fff)
assert bi.node is fff, bi.node
@@ -762,11 +786,11 @@ class BuildInfoTestCase(_tempdirTestCase):
f1 = self.fs.File('f1')
bi1 = SCons.Node.FS.BuildInfo(f1)
- s1sig = SCons.Node.FS.NodeInfo()
+ s1sig = SCons.Node.FS.FileNodeInfo(self.fs.File('n1'))
s1sig.a = 1
- d1sig = SCons.Node.FS.NodeInfo()
+ d1sig = SCons.Node.FS.FileNodeInfo(self.fs.File('n2'))
d1sig.a = 2
- i1sig = SCons.Node.FS.NodeInfo()
+ i1sig = SCons.Node.FS.FileNodeInfo(self.fs.File('n3'))
i1sig.a = 3
bi1.bsources = [self.fs.File('s1')]
@@ -776,8 +800,16 @@ class BuildInfoTestCase(_tempdirTestCase):
bi1.bdependsigs = [d1sig]
bi1.bimplicitsigs = [i1sig]
+ expect_lines = [
+ 'None 0',
+ 's1: 1 None 0',
+ 'd1: 2 None 0',
+ 'i1: 3 None 0',
+ ]
+
+ expect = string.join(expect_lines, '\n')
format = bi1.format()
- assert format == 'None 0\ns1: 1\nd1: 2\ni1: 3', repr(format)
+ assert format == expect, (repr(format), repr(expect))
class FSTestCase(_tempdirTestCase):
def test_runTest(self):
@@ -2584,7 +2616,7 @@ class CacheDirTestCase(unittest.TestCase):
SCons.Sig.MD5.collect = my_collect
try:
f5 = fs.File("cd.f5")
- f5.binfo = f5.new_binfo()
+ f5.binfo = f5.BuildInfo(f5)
f5.binfo.ninfo.bsig = 'a_fake_bsig'
cp = f5.cachepath()
dirname = os.path.join('cache', 'A')
@@ -2595,7 +2627,7 @@ class CacheDirTestCase(unittest.TestCase):
# Verify that no bsig raises an InternalERror
f6 = fs.File("cd.f6")
- f6.binfo = f6.new_binfo()
+ f6.binfo = f6.BuildInfo(f6)
exc_caught = 0
try:
cp = f6.cachepath()
@@ -2619,7 +2651,7 @@ class CacheDirTestCase(unittest.TestCase):
cd_f7 = test.workpath("cd.f7")
test.write(cd_f7, "cd.f7\n")
f7 = fs.File(cd_f7)
- f7.binfo = f7.new_binfo()
+ f7.binfo = f7.BuildInfo(f7)
f7.binfo.ninfo.bsig = 'f7_bsig'
warn_caught = 0
@@ -2980,12 +3012,14 @@ if __name__ == "__main__":
suite.addTest(SaveStringsTestCase())
tclasses = [
BaseTestCase,
- BuildInfoTestCase,
+ DirTestCase,
+ DirBuildInfoTestCase,
+ DirNodeInfoTestCase,
EntryTestCase,
FileTestCase,
- NodeInfoTestCase,
+ FileBuildInfoTestCase,
+ FileNodeInfoTestCase,
FSTestCase,
- DirTestCase,
RepositoryTestCase,
]
for tclass in tclasses:
diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py
index 1cd5201..4f7b65a 100644
--- a/src/engine/SCons/Node/NodeTests.py
+++ b/src/engine/SCons/Node/NodeTests.py
@@ -214,12 +214,12 @@ class Calculator:
-class NodeInfoTestCase(unittest.TestCase):
+class NodeInfoBaseTestCase(unittest.TestCase):
def test___cmp__(self):
- """Test comparing NodeInfo objects"""
- ni1 = SCons.Node.NodeInfo()
- ni2 = SCons.Node.NodeInfo()
+ """Test comparing NodeInfoBase objects"""
+ ni1 = SCons.Node.NodeInfoBase(SCons.Node.Node())
+ ni2 = SCons.Node.NodeInfoBase(SCons.Node.Node())
assert ni1 == ni2, "%s != %s" % (ni1.__dict__, ni2.__dict__)
@@ -233,9 +233,9 @@ class NodeInfoTestCase(unittest.TestCase):
assert ni1 == ni2, "%s != %s" % (ni1.__dict__, ni2.__dict__)
def test_merge(self):
- """Test merging NodeInfo attributes"""
- ni1 = SCons.Node.NodeInfo()
- ni2 = SCons.Node.NodeInfo()
+ """Test merging NodeInfoBase attributes"""
+ ni1 = SCons.Node.NodeInfoBase(SCons.Node.Node())
+ ni2 = SCons.Node.NodeInfoBase(SCons.Node.Node())
ni1.a1 = 1
ni1.a2 = 2
@@ -248,12 +248,12 @@ class NodeInfoTestCase(unittest.TestCase):
def test_update(self):
"""Test the update() method"""
- ni = SCons.Node.NodeInfo()
+ ni = SCons.Node.NodeInfoBase(SCons.Node.Node())
ni.update(SCons.Node.Node())
def test_format(self):
- """Test the NodeInfo.format() method"""
- ni1 = SCons.Node.NodeInfo()
+ """Test the NodeInfoBase.format() method"""
+ ni1 = SCons.Node.NodeInfoBase(SCons.Node.Node())
ni1.xxx = 'x'
ni1.yyy = 'y'
ni1.zzz = 'z'
@@ -268,23 +268,23 @@ class NodeInfoTestCase(unittest.TestCase):
-class BuildInfoTestCase(unittest.TestCase):
+class BuildInfoBaseTestCase(unittest.TestCase):
def test___init__(self):
- """Test BuildInfo initialization"""
- bi = SCons.Node.BuildInfo(SCons.Node.Node())
+ """Test BuildInfoBase initialization"""
+ bi = SCons.Node.BuildInfoBase(SCons.Node.Node())
assert hasattr(bi, 'ninfo')
class MyNode(SCons.Node.Node):
- def new_ninfo(self):
+ def NodeInfo(self, node):
return 'ninfo initialization'
- bi = SCons.Node.BuildInfo(MyNode())
+ bi = SCons.Node.BuildInfoBase(MyNode())
assert bi.ninfo == 'ninfo initialization', bi.ninfo
def test___cmp__(self):
- """Test comparing BuildInfo objects"""
- bi1 = SCons.Node.BuildInfo(SCons.Node.Node())
- bi2 = SCons.Node.BuildInfo(SCons.Node.Node())
+ """Test comparing BuildInfoBase objects"""
+ bi1 = SCons.Node.BuildInfoBase(SCons.Node.Node())
+ bi2 = SCons.Node.BuildInfoBase(SCons.Node.Node())
assert bi1 == bi2, "%s != %s" % (bi1.__dict__, bi2.__dict__)
@@ -301,9 +301,9 @@ class BuildInfoTestCase(unittest.TestCase):
assert bi1 == bi2, "%s != %s" % (bi1.__dict__, bi2.__dict__)
def test_merge(self):
- """Test merging BuildInfo attributes"""
- bi1 = SCons.Node.BuildInfo(SCons.Node.Node())
- bi2 = SCons.Node.BuildInfo(SCons.Node.Node())
+ """Test merging BuildInfoBase attributes"""
+ bi1 = SCons.Node.BuildInfoBase(SCons.Node.Node())
+ bi2 = SCons.Node.BuildInfoBase(SCons.Node.Node())
bi1.a1 = 1
bi1.a2 = 2
@@ -617,7 +617,7 @@ class NodeTestCase(unittest.TestCase):
node = SCons.Node.Node()
binfo = node.get_binfo()
- assert isinstance(binfo, SCons.Node.BuildInfo), binfo
+ assert isinstance(binfo, SCons.Node.BuildInfoBase), binfo
node.binfo = 777
binfo = node.get_binfo()
@@ -633,7 +633,7 @@ class NodeTestCase(unittest.TestCase):
node.implicit = [i]
node.gen_binfo(Calculator(666))
binfo = node.binfo
- assert isinstance(binfo, SCons.Node.BuildInfo), binfo
+ assert isinstance(binfo, SCons.Node.BuildInfoBase), binfo
assert hasattr(binfo, 'bsources')
assert hasattr(binfo, 'bsourcesigs')
assert binfo.bdepends == [d]
@@ -1276,7 +1276,7 @@ class NodeTestCase(unittest.TestCase):
"""Test the new_binfo() method"""
n = SCons.Node.Node()
result = n.new_binfo()
- assert isinstance(result, SCons.Node.BuildInfo), result
+ assert isinstance(result, SCons.Node.BuildInfoBase), result
def test_get_suffix(self):
"""Test the base Node get_suffix() method"""
@@ -1342,8 +1342,8 @@ class NodeListTestCase(unittest.TestCase):
if __name__ == "__main__":
suite = unittest.TestSuite()
- tclasses = [ BuildInfoTestCase,
- NodeInfoTestCase,
+ tclasses = [ BuildInfoBaseTestCase,
+ NodeInfoBaseTestCase,
NodeTestCase,
NodeListTestCase ]
for tclass in tclasses:
diff --git a/src/engine/SCons/Node/Python.py b/src/engine/SCons/Node/Python.py
index 0e1c985..99dc5b0 100644
--- a/src/engine/SCons/Node/Python.py
+++ b/src/engine/SCons/Node/Python.py
@@ -31,10 +31,20 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import SCons.Node
+class ValueNodeInfo(SCons.Node.NodeInfoBase):
+ pass
+
+class ValueBuildInfo(SCons.Node.BuildInfoBase):
+ pass
+
class Value(SCons.Node.Node):
"""A class for Python variables, typically passed on the command line
or generated by a script, but not from a file or some other source.
"""
+
+ NodeInfo = ValueNodeInfo
+ BuildInfo = ValueBuildInfo
+
def __init__(self, value):
SCons.Node.Node.__init__(self)
self.value = value
diff --git a/src/engine/SCons/Node/PythonTests.py b/src/engine/SCons/Node/PythonTests.py
index 78cbf68..0801fb3 100644
--- a/src/engine/SCons/Node/PythonTests.py
+++ b/src/engine/SCons/Node/PythonTests.py
@@ -60,8 +60,27 @@ class ValueTestCase(unittest.TestCase):
csig = v3.get_csig(None)
assert csig == 'None', csig
+class ValueNodeInfoTestCase(unittest.TestCase):
+ def test___init__(self):
+ """Test ValueNodeInfo initialization"""
+ vvv = SCons.Node.Python.Value('vvv')
+ ni = SCons.Node.Python.ValueNodeInfo(vvv)
+
+class ValueBuildInfoTestCase(unittest.TestCase):
+ def test___init__(self):
+ """Test ValueBuildInfo initialization"""
+ vvv = SCons.Node.Python.Value('vvv')
+ bi = SCons.Node.Python.ValueBuildInfo(vvv)
if __name__ == "__main__":
- suite = unittest.makeSuite(ValueTestCase, 'test_')
+ suite = unittest.TestSuite()
+ tclasses = [
+ ValueTestCase,
+ ValueBuildInfoTestCase,
+ ValueNodeInfoTestCase,
+ ]
+ for tclass in tclasses:
+ names = unittest.getTestCaseNames(tclass, 'test_')
+ suite.addTests(map(tclass, names))
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py
index 250c714..6a0a238 100644
--- a/src/engine/SCons/Node/__init__.py
+++ b/src/engine/SCons/Node/__init__.py
@@ -97,15 +97,14 @@ Annotate = do_nothing
# Classes for signature info for Nodes.
-class NodeInfo:
+class NodeInfoBase:
"""
- A generic class for signature information for a Node.
+ The generic base class for signature information for a Node.
- We actually expect that modules containing Node subclasses will also
- subclass NodeInfo, to provide their own logic for dealing with their
- own Node-specific signature information.
+ Node subclasses should subclass NodeInfoBase to provide their own
+ logic for dealing with their own Node-specific signature information.
"""
- def __init__(self):
+ def __init__(self, node):
"""A null initializer so that subclasses have a superclass
initialization method to call for future use.
"""
@@ -132,9 +131,9 @@ class NodeInfo:
fields.append(str(f))
return string.join(fields, " ")
-class BuildInfo:
+class BuildInfoBase:
"""
- The generic build information for a Node.
+ The generic base clasee for build information for a Node.
This is what gets stored in a .sconsign file for each target file.
It contains a NodeInfo instance for this node (signature information
@@ -143,7 +142,7 @@ class BuildInfo:
implicit dependencies, and action information.
"""
def __init__(self, node):
- self.ninfo = node.new_ninfo()
+ self.ninfo = node.NodeInfo(node)
self.bsourcesigs = []
self.bdependsigs = []
self.bimplicitsigs = []
@@ -592,6 +591,9 @@ class Node:
# SIGNATURE SUBSYSTEM
#
+ NodeInfo = NodeInfoBase
+ BuildInfo = BuildInfoBase
+
def calculator(self):
import SCons.Defaults
@@ -618,10 +620,10 @@ class Node:
return self.get_csig(calc)
def new_ninfo(self):
- return NodeInfo()
+ return self.NodeInfo(self)
def new_binfo(self):
- return BuildInfo(self)
+ return self.BuildInfo(self)
def get_binfo(self):
try:
diff --git a/src/engine/SCons/SConf.py b/src/engine/SCons/SConf.py
index ddc4ad9..6dfb843 100644
--- a/src/engine/SCons/SConf.py
+++ b/src/engine/SCons/SConf.py
@@ -150,7 +150,7 @@ def _stringSource( target, source, env ):
BooleanTypes = [types.IntType]
if hasattr(types, 'BooleanType'): BooleanTypes.append(types.BooleanType)
-class SConfBuildInfo(SCons.Node.FS.BuildInfo):
+class SConfBuildInfo(SCons.Node.FS.FileBuildInfo):
"""
Special build info for targets of configure tests. Additional members
are result (did the builder succeed last time?) and string, which
@@ -160,7 +160,7 @@ class SConfBuildInfo(SCons.Node.FS.BuildInfo):
string = None # the stdout / stderr output when building the target
def __init__(self, node, result, string, sig):
- SCons.Node.FS.BuildInfo.__init__(self, node)
+ SCons.Node.FS.FileBuildInfo.__init__(self, node)
self.result = result
self.string = string
self.ninfo.bsig = sig