From 7f1d72c184e5824bf15a593add8542de4c049d8a Mon Sep 17 00:00:00 2001 From: Steven Knight Date: Tue, 2 Dec 2008 18:58:29 +0000 Subject: Fix a Glob() exception (with stack trace) when an explicit Node exists in a repository directory without a corresponding on-disk file or directory. --- src/CHANGES.txt | 3 +++ src/engine/SCons/Node/FS.py | 6 +++++- src/engine/SCons/Node/FSTests.py | 33 ++++++++++++++++++++++++++------- test/Glob/Repository.py | 6 ++++++ 4 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 7fd865e..d7b1fac 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -54,6 +54,9 @@ RELEASE 1.X - XXX - Add support for using the Python "in" keyword on construction environments (for example, if "CPPPATH" in env: ...). + - Fix use of Glob() when a repository or source directory contains + an in-memory Node without a corresponding on-disk file or directory. + From Rob Managan: - Scan for TeX files in the paths specified in the $TEXINPUTS diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 03275da..790d840 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -1892,6 +1892,7 @@ class Dir(Base): for srcdir in self.srcdir_list(): search_dir_list.extend(srcdir.get_all_rdirs()) + selfEntry = self.Entry names = [] for dir in search_dir_list: # We use the .name attribute from the Node because the keys of @@ -1901,6 +1902,10 @@ class Dir(Base): entry_names = filter(lambda n: n not in ('.', '..'), dir.entries.keys()) node_names = map(lambda n, e=dir.entries: e[n].name, entry_names) names.extend(node_names) + if not strings: + # Make sure the working directory (self) actually has + # entries for all Nodes in repositories or variant dirs. + map(selfEntry, node_names) if ondisk: try: disk_names = os.listdir(dir.abspath) @@ -1921,7 +1926,6 @@ class Dir(Base): disk_names = filter(lambda x: x[0] != '.', disk_names) disk_names = fnmatch.filter(disk_names, pattern) dirEntry = dir.Entry - selfEntry = self.Entry for name in disk_names: # Add './' before disk filename so that '#' at # beginning of filename isn't interpreted. diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index 6566d59..bf6a300 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -2206,12 +2206,24 @@ class GlobTestCase(_tempdirTestCase): r = apply(self.fs.Glob, (input,), kwargs) if node_expect: r.sort(lambda a,b: cmp(a.path, b.path)) - result = node_expect + result = [] + for n in node_expect: + if type(n) == type(''): + n = self.fs.Entry(n) + result.append(n) + fmt = lambda n: "%s %s" % (repr(n), repr(str(n))) else: r = map(str, r) r.sort() result = string_expect - assert r == result, "Glob(%s) expected %s, got %s" % (input, map(str, result), map(str, r)) + fmt = lambda n: n + if r != result: + import pprint + print "Glob(%s) expected:" % repr(input) + pprint.pprint(map(fmt, result)) + print "Glob(%s) got:" % repr(input) + pprint.pprint(map(fmt, r)) + self.fail() def test_exact_match(self): """Test globbing for exact Node matches""" @@ -2249,8 +2261,8 @@ class GlobTestCase(_tempdirTestCase): self.do_cases(cases) - def test_asterisk(self): - """Test globbing for simple asterisk Node matches""" + def test_asterisk1(self): + """Test globbing for simple asterisk Node matches (1)""" cases = ( ('h*', ['hhh'], @@ -2263,14 +2275,16 @@ class GlobTestCase(_tempdirTestCase): 'ggg', 'hhh', 'iii', 'sub', 'subdir1', 'subdir2'], [self._both_hash, self._hash, - self.both_aaa, self.both_bbb, self.both_ccc, + self.both_aaa, self.both_bbb, self.both_ccc, 'both-hash', self.both_sub1, self.both_sub2, - self.ggg, self.hhh, self.iii, + self.ggg, 'hash', self.hhh, self.iii, self.sub, self.subdir1, self.subdir2]), ) self.do_cases(cases, ondisk=False) + def test_asterisk2(self): + """Test globbing for simple asterisk Node matches (2)""" cases = ( ('disk-b*', ['disk-bbb'], @@ -2283,7 +2297,12 @@ class GlobTestCase(_tempdirTestCase): 'disk-aaa', 'disk-bbb', 'disk-ccc', 'disk-sub', 'ggg', 'hhh', 'iii', 'sub', 'subdir1', 'subdir2'], - None), + ['./#both-hash', './#disk-hash', './#hash', + 'both-aaa', 'both-bbb', 'both-ccc', 'both-hash', + 'both-sub1', 'both-sub2', + 'disk-aaa', 'disk-bbb', 'disk-ccc', 'disk-sub', + 'ggg', 'hash', 'hhh', 'iii', + 'sub', 'subdir1', 'subdir2']), ) self.do_cases(cases) diff --git a/test/Glob/Repository.py b/test/Glob/Repository.py index 6cef443..bef9bda 100644 --- a/test/Glob/Repository.py +++ b/test/Glob/Repository.py @@ -55,6 +55,12 @@ def cat(env, source, target): f.write(open(src, "rb").read()) f.close() +# Verify that we can glob a repository-only Node that exists +# only in memory, not on disk. +File('../repository/mmm.in') +m = Glob('m*.in') +assert str(m[0]) == 'mmm.in' + env = Environment(BUILDERS={'Build':Builder(action=cat)}) env.Build('aaa.out', Glob('a*.in')) env.Build('bbb.out', Glob('b*.in')) -- cgit v0.12