diff options
author | Steven Knight <knight@baldmt.com> | 2001-09-17 04:57:00 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2001-09-17 04:57:00 (GMT) |
commit | 3c81bb2bd0e009c0ee81570e17b0f87ad8d034ab (patch) | |
tree | 1a08c189644909cdadc489cce0eaa487e2c6f578 /src/engine/SCons/Node | |
parent | e2faf9c21bc7712fcdc547b7df0f12a6b2177601 (diff) | |
download | SCons-3c81bb2bd0e009c0ee81570e17b0f87ad8d034ab.zip SCons-3c81bb2bd0e009c0ee81570e17b0f87ad8d034ab.tar.gz SCons-3c81bb2bd0e009c0ee81570e17b0f87ad8d034ab.tar.bz2 |
Run setup.py on the unpacked .tar.gz for testing.
Diffstat (limited to 'src/engine/SCons/Node')
-rw-r--r-- | src/engine/SCons/Node/.aeignore | 4 | ||||
-rw-r--r-- | src/engine/SCons/Node/FS.py | 139 | ||||
-rw-r--r-- | src/engine/SCons/Node/FS/.aeignore | 4 | ||||
-rw-r--r-- | src/engine/SCons/Node/FSTests.py | 109 | ||||
-rw-r--r-- | src/engine/SCons/Node/NodeTests.py | 45 | ||||
-rw-r--r-- | src/engine/SCons/Node/__init__.py | 22 |
6 files changed, 323 insertions, 0 deletions
diff --git a/src/engine/SCons/Node/.aeignore b/src/engine/SCons/Node/.aeignore new file mode 100644 index 0000000..43fe851 --- /dev/null +++ b/src/engine/SCons/Node/.aeignore @@ -0,0 +1,4 @@ +*,D +*.pyc +.*.swp +.consign diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py new file mode 100644 index 0000000..e7956c2 --- /dev/null +++ b/src/engine/SCons/Node/FS.py @@ -0,0 +1,139 @@ +"""SCons.Node.FS + +File system nodes. + +""" + +__revision__ = "Node/FS.py __REVISION__ __DATE__ __DEVELOPER__" + + + +import os +import os.path +import SCons.Node + + + +Top = None +Root = {} + + + +def init(path = None): + """Initialize the Node.FS subsystem. + + The supplied path is the top of the source tree, where we + expect to find the top-level build file. If no path is + supplied, the current directory is the default. + """ + global Top + if path == None: + path = os.getcwd() + Top = lookup(Dir, path, directory = None) + Top.path = '.' + +def lookup(fsclass, name, directory = Top): + """Look up a file system node for a path name. If the path + name is relative, it will be looked up relative to the + specified directory node, or to the top-level directory + if no node was specified. An initial '#' specifies that + the name will be looked up relative to the top-level directory, + regardless of the specified directory argument. Returns the + existing or newly-created node for the specified path name. + The node returned will be of the specified fsclass (Dir or + File). + """ + global Top + head, tail = os.path.split(name) + if not tail: + drive, path = os.path.splitdrive(head) + if not Root.has_key(drive): + Root[drive] = Dir(head, None) + Root[drive].abspath = head + Root[drive].path = head + return Root[drive] + if tail[0] == '#': + directory = Top + tail = tail[1:] + elif directory is None: + directory = Top + if head: + directory = lookup(Dir, head, directory) + try: + self = directory.entries[tail] + except AttributeError: + # There was no "entries" attribute on the directory, + # which essentially implies that it was a file. + # Return it as a more descriptive exception. + raise TypeError, directory + except KeyError: + # There was to entry for "tail," so create the new + # node and link it in to the existing structure. + self = fsclass(tail, directory) + self.name = tail + if self.path[0:2] == "./": + self.path = self.path[2:] + directory.entries[tail] = self + except: + raise + if self.__class__.__name__ != fsclass.__name__: + # Here, we found an existing node for this path, + # but it was the wrong type (a File when we were + # looking for a Dir, or vice versa). + raise TypeError, self + return self + + + +# XXX TODO? +# Annotate with the creator +# is_under +# rel_path +# srcpath / srcdir +# link / is_linked +# linked_targets +# is_accessible + +class Dir(SCons.Node.Node): + """A class for directories in a file system. + """ + + def __init__(self, name, directory): + self.entries = {} + self.entries['.'] = self + self.entries['..'] = directory + if not directory is None: + self.abspath = os.path.join(directory.abspath, name, '') + self.path = os.path.join(directory.path, name, '') + + def up(self): + return self.entries['..'] + + +# XXX TODO? +# rfile +# precious +# no_rfile +# rpath +# rsrcpath +# source_exists +# derived_exists +# is_on_rpath +# local +# base_suf +# suffix +# addsuffix +# accessible +# ignore +# build +# bind +# is_under +# relpath + +class File(SCons.Node.Node): + """A class for files in a file system. + """ + + def __init__(self, name, directory): + self.abspath = os.path.join(directory.abspath, name) + self.path = os.path.join(directory.path, name) diff --git a/src/engine/SCons/Node/FS/.aeignore b/src/engine/SCons/Node/FS/.aeignore new file mode 100644 index 0000000..43fe851 --- /dev/null +++ b/src/engine/SCons/Node/FS/.aeignore @@ -0,0 +1,4 @@ +*,D +*.pyc +.*.swp +.consign diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py new file mode 100644 index 0000000..aa8cf2a --- /dev/null +++ b/src/engine/SCons/Node/FSTests.py @@ -0,0 +1,109 @@ +__revision__ = "Node/FSTests.py __REVISION__ __DATE__ __DEVELOPER__" + +import os +import sys +import unittest + +import SCons.Node.FS + + + +built_it = None + +class Builder: + def execute(self, target = None, source = None): + global built_it + built_it = 1 + + + +class FSTestCase(unittest.TestCase): + def runTest(self): + """Test FS (file system) Node operations + + This test case handles all of the file system node + tests in one environment, so we don't have to set up a + complicated directory structure for each test individually. + """ + from TestCmd import TestCmd + + test = TestCmd(workdir = '') + test.subdir('sub', ['sub', 'dir']) + + wp = test.workpath('') + sub = test.workpath('sub', '') + sub_dir = test.workpath('sub', 'dir', '') + sub_dir_foo = test.workpath('sub', 'dir', 'foo', '') + sub_dir_foo_bar = test.workpath('sub', 'dir', 'foo', 'bar', '') + sub_foo = test.workpath('sub', 'foo', '') + + os.chdir(sub_dir) + + SCons.Node.FS.init() + + def Dir_test(lpath, path, abspath, up_path): + dir = SCons.Node.FS.lookup(SCons.Node.FS.Dir, lpath) + assert(dir.path == path) + assert(dir.abspath == abspath) + assert(dir.up().path == up_path) + + Dir_test('foo', 'foo/', sub_dir_foo, '.') + Dir_test('foo/bar', 'foo/bar/', sub_dir_foo_bar, 'foo/') + Dir_test('/foo', '/foo/', '/foo/', '/') + Dir_test('/foo/bar', '/foo/bar/', '/foo/bar/', '/foo/') + Dir_test('..', sub, sub, wp) + Dir_test('foo/..', '.', sub_dir, sub) + Dir_test('../foo', sub_foo, sub_foo, sub) + Dir_test('.', '.', sub_dir, sub) + Dir_test('./.', '.', sub_dir, sub) + Dir_test('foo/./bar', 'foo/bar/', sub_dir_foo_bar, 'foo/') + + d1 = SCons.Node.FS.lookup(SCons.Node.FS.Dir, 'd1') + + f1 = SCons.Node.FS.lookup(SCons.Node.FS.File, 'f1', directory = d1) + + assert(f1.path == 'd1/f1') + + try: + f2 = SCons.Node.FS.lookup(SCons.Node.FS.File, 'f1/f2', directory = d1) + except TypeError, x: + node = x.args[0] + assert(node.path == 'd1/f1') + assert(node.__class__.__name__ == 'File') + except: + raise + + try: + dir = SCons.Node.FS.lookup(SCons.Node.FS.Dir, 'd1/f1') + except TypeError, x: + node = x.args[0] + assert(node.path == 'd1/f1') + assert(node.__class__.__name__ == 'File') + except: + raise + + # Test for sub-classing of node building. + global built_it + + built_it = None + assert not built_it + d1.path = "d" # XXX FAKE SUBCLASS ATTRIBUTE + d1.sources = "d" # XXX FAKE SUBCLASS ATTRIBUTE + d1.builder_set(Builder()) + d1.build() + assert built_it + + built_it = None + assert not built_it + f1.path = "f" # XXX FAKE SUBCLASS ATTRIBUTE + f1.sources = "f" # XXX FAKE SUBCLASS ATTRIBUTE + f1.builder_set(Builder()) + f1.build() + assert built_it + + +if __name__ == "__main__": + suite = unittest.TestSuite() + suite.addTest(FSTestCase()) + if not unittest.TextTestRunner().run(suite).wasSuccessful(): + sys.exit(1) diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py new file mode 100644 index 0000000..2249a96 --- /dev/null +++ b/src/engine/SCons/Node/NodeTests.py @@ -0,0 +1,45 @@ +__revision__ = "Node/NodeTests.py __REVISION__ __DATE__ __DEVELOPER__" + +import os +import sys +import unittest + +import SCons.Node + + + +built_it = None + +class Builder: + def execute(self, target = None, source = None): + global built_it + built_it = 1 + + + +class NodeTestCase(unittest.TestCase): + + def test_build(self): + """Test building a node + """ + node = SCons.Node.Node() + node.builder_set(Builder()) + node.path = "xxx" # XXX FAKE SUBCLASS ATTRIBUTE + node.sources = "yyy" # XXX FAKE SUBCLASS ATTRIBUTE + node.build() + assert built_it + + def test_builder_set(self): + """Test setting a Node's Builder + """ + node = SCons.Node.Node() + b = Builder() + node.builder_set(b) + assert node.builder == b + + + +if __name__ == "__main__": + suite = unittest.makeSuite(NodeTestCase, 'test_') + 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 new file mode 100644 index 0000000..fb77c65 --- /dev/null +++ b/src/engine/SCons/Node/__init__.py @@ -0,0 +1,22 @@ +"""SCons.Node + +The Node package for the SCons software construction utility. + +""" + +__revision__ = "Node/__init__.py __REVISION__ __DATE__ __DEVELOPER__" + + + +class Node: + """The base Node class, for entities that we know how to + build, or use to build other Nodes. + """ + def build(self): + self.builder.execute(target = self.path, source = self.sources) + + def builder_set(self, builder): + self.builder = builder + + def env_set(self, env): + self.env = env |