import SCons.Node.FS
import SCons.Scanner
+def only_dirs(nodes):
+ is_Dir = lambda n: isinstance(n.disambiguate(), SCons.Node.FS.Dir)
+ return filter(is_Dir, nodes)
+
def DirScanner(**kw):
"""Return a prototype Scanner instance for scanning
directories for on-disk files"""
- def only_dirs(nodes):
- return filter(lambda n: isinstance(n.disambiguate(),
- SCons.Node.FS.Dir),
- nodes)
kw['node_factory'] = SCons.Node.FS.Entry
kw['recursive'] = only_dirs
- ds = apply(SCons.Scanner.Base, (scan, "DirScanner"), kw)
- return ds
+ return apply(SCons.Scanner.Base, (scan_on_disk, "DirScanner"), kw)
+
+def DirEntryScanner(**kw):
+ """Return a prototype Scanner instance for "scanning"
+ directory Nodes for their in-memory entries"""
+ kw['node_factory'] = SCons.Node.FS.Entry
+ kw['recursive'] = only_dirs
+ return apply(SCons.Scanner.Base, (scan_in_memory, "DirEntryScanner"), kw)
skip_entry = {
'.' : 1,
'.sconsign.dblite' : 1,
}
-def scan(node, env, path=()):
+do_not_scan = lambda k: not skip_entry.has_key(k)
+
+def scan_on_disk(node, env, path=()):
"""
- This scanner scans a directory for on-disk files and directories therein.
+ Scans a directory for on-disk files and directories therein.
+
+ Looking up the entries will add these to the in-memory Node tree
+ representation of the file system, so all we have to do is just
+ that and then call the in-memory scanning function.
"""
try:
flist = node.fs.listdir(node.abspath)
except (IOError, OSError):
return []
- dont_scan = lambda k: not skip_entry.has_key(k)
- flist = filter(dont_scan, flist)
- flist.sort()
- # Add ./ to the beginning of the file name so that if it begins with a
- # '#' we don't look it up relative to the top-level directory.
- return map(lambda f, node=node: node.Entry('./'+f), flist)
+ e = node.Entry
+ for f in filter(do_not_scan, flist):
+ # Add ./ to the beginning of the file name so if it begins with a
+ # '#' we don't look it up relative to the top-level directory.
+ e('./' + f)
+ return scan_in_memory(node, env, path)
+
+def scan_in_memory(node, env, path=()):
+ """
+ "Scans" a Node.FS.Dir for its in-memory entries.
+ """
+ entry_list = filter(do_not_scan, node.entries.keys())
+ entry_list.sort()
+ return map(lambda n, e=node.entries: e[n], entry_list)
import SCons.Node.FS
import SCons.Scanner.Dir
-test = TestCmd.TestCmd(workdir = '')
-
-test.subdir('dir', ['dir', 'sub'])
-
-test.write(['dir', 'f1'], "dir/f1\n")
-test.write(['dir', 'f2'], "dir/f2\n")
-test.write(['dir', '.sconsign'], "dir/.sconsign\n")
-test.write(['dir', '.sconsign.dblite'], "dir/.sconsign.dblite\n")
-test.write(['dir', 'sub', 'f3'], "dir/sub/f3\n")
-test.write(['dir', 'sub', 'f4'], "dir/sub/f4\n")
-test.write(['dir', 'sub', '.sconsign'], "dir/.sconsign\n")
-test.write(['dir', 'sub', '.sconsign.dblite'], "dir/.sconsign.dblite\n")
-
-class DummyNode:
- def __init__(self, name, fs):
- self.name = name
- self.abspath = test.workpath(name)
- self.fs = fs
- def __str__(self):
- return self.name
- def Entry(self, name):
- return self.fs.Entry(name)
+#class DummyNode:
+# def __init__(self, name, fs):
+# self.name = name
+# self.abspath = test.workpath(name)
+# self.fs = fs
+# def __str__(self):
+# return self.name
+# def Entry(self, name):
+# return self.fs.Entry(name)
class DummyEnvironment:
- def __init__(self):
- self.fs = SCons.Node.FS.FS()
+ def __init__(self, root):
+ self.fs = SCons.Node.FS.FS(root)
+ def Dir(self, name):
+ return self.fs.Dir(name)
def Entry(self, name):
- node = DummyNode(name, self.fs)
- return node
+ return self.fs.Entry(name)
def get_factory(self, factory):
return factory or self.fs.Entry
-class DirScannerTestCase1(unittest.TestCase):
+class DirScannerTestBase(unittest.TestCase):
+ def setUp(self):
+ self.test = TestCmd.TestCmd(workdir = '')
+
+ self.test.subdir('dir', ['dir', 'sub'])
+
+ self.test.write(['dir', 'f1'], "dir/f1\n")
+ self.test.write(['dir', 'f2'], "dir/f2\n")
+ self.test.write(['dir', '.sconsign'], "dir/.sconsign\n")
+ self.test.write(['dir', '.sconsign.dblite'], "dir/.sconsign.dblite\n")
+ self.test.write(['dir', 'sub', 'f3'], "dir/sub/f3\n")
+ self.test.write(['dir', 'sub', 'f4'], "dir/sub/f4\n")
+ self.test.write(['dir', 'sub', '.sconsign'], "dir/.sconsign\n")
+ self.test.write(['dir', 'sub', '.sconsign.dblite'], "dir/.sconsign.dblite\n")
+
+class DirScannerTestCase1(DirScannerTestBase):
def runTest(self):
- env = DummyEnvironment()
+ env = DummyEnvironment(self.test.workpath())
s = SCons.Scanner.Dir.DirScanner()
- deps = s(env.Entry('dir'), env, ())
+ deps = s(env.Dir('dir'), env, ())
+ sss = map(str, deps)
+ assert sss == ['dir/f1', 'dir/f2', 'dir/sub'], sss
+
+ deps = s(env.Dir('dir/sub'), env, ())
+ sss = map(str, deps)
+ assert sss == ['dir/sub/f3', 'dir/sub/f4'], sss
+
+class DirScannerTestCase2(DirScannerTestBase):
+ def runTest(self):
+ env = DummyEnvironment(self.test.workpath())
+
+ s = SCons.Scanner.Dir.DirEntryScanner()
+
+ deps = s(env.Dir('dir'), env, ())
sss = map(str, deps)
- assert sss == ['f1', 'f2', 'sub'], sss
+ assert sss == [], sss
- deps = s(env.Entry('dir/sub'), env, ())
+ deps = s(env.Dir('dir/sub'), env, ())
sss = map(str, deps)
- assert sss == ['f3', 'f4'], sss
+ assert sss == [], sss
def suite():
suite = unittest.TestSuite()
suite.addTest(DirScannerTestCase1())
+ suite.addTest(DirScannerTestCase2())
return suite
if __name__ == "__main__":