def prepareSrc(self, dict):
src = VarInterpolator.prepareSrc(self, dict)
-
- def prepare(x, self=self):
- if isinstance(x, SCons.Node.Node):
- return [x]
- elif str(x):
- if os.path.isabs(str(x)):
- return [self.fs.Dir(str(x), directory=self.dir)]
- else:
- return map(lambda d, s=str(x), fs=self.fs:
- fs.Dir(s, directory=d),
- [self.dir] + self.fs.Repositories)
- else:
- return []
-
- return reduce(lambda x, y: x+y, map(prepare, src), [])
+ def path_dirs(path, fs = self.fs, dir = self.dir):
+ return fs.Dir(path, directory = dir)
+ return self.fs.Rsearchall(src, path_dirs)
def instance(self, dir, fs):
try:
def _my_normcase(x):
return string.upper(x)
+
+def exists_path(path):
+ """Return a path if it's already a Node or it exists in the
+ real filesystem."""
+ if os.path.exists(path):
+ return path
+ return None
+
+
class FS:
def __init__(self, path = None):
"""Initialize the Node.FS subsystem.
for d in dirs:
self.Repositories.append(self.Dir(d))
- def Rsearch(self, path, func = os.path.exists):
- """Search for something in a repository."""
- for dir in self.Repositories:
- t = os.path.join(dir.path, path)
- if func(t):
- return t
+ def Rsearch(self, path, func = exists_path):
+ """Search for something in a repository. Returns the first
+ one found in the list, or None if there isn't one."""
+ if isinstance(path, SCons.Node.Node):
+ return path
+ else:
+ n = func(path)
+ if n:
+ return n
+ for dir in self.Repositories:
+ n = func(os.path.join(dir.path, path))
+ if n:
+ return n
return None
+ def Rsearchall(self, pathlist, func = exists_path):
+ """Search for a list of somethings in the repository list."""
+ ret = []
+ if SCons.Util.is_String(pathlist):
+ pathlist = string.split(pathlist, os.pathsep)
+ for path in pathlist:
+ if isinstance(path, SCons.Node.Node):
+ ret.append(path)
+ else:
+ n = func(path)
+ if n:
+ ret.append(n)
+ if not os.path.isabs(path):
+ for dir in self.Repositories:
+ n = func(os.path.join(dir.path, path))
+ if n:
+ ret.append(n)
+ return ret
+
class Entry(SCons.Node.Node):
"""A generic class for file system entries. This class if for
self.__doSrcpath(self.duplicate)
self.srcpath_ = self.srcpath
self.cwd = None # will hold the SConscript directory for target nodes
- self._rfile = None
def get_dir(self):
return self.dir
def __init__(self, name, directory):
Entry.__init__(self, name, directory)
self._morph()
- self._rfile = None
def _morph(self):
"""Turn a file system node (either a freshly initialized
# XXX TODO?
# rfile
# precious
-# no_rfile
# rpath
# rsrcpath
# source_exists
self.__createDir()
def rfile(self):
- if not self._rfile:
+ if not hasattr(self, '_rfile'):
self._rfile = self
if not os.path.isabs(self.path) and not os.path.isfile(self.path):
- t = self.fs.Rsearch(self.path, os.path.isfile)
- if t:
- self._rfile = self.fs.File(t)
+ def file_node(path, fs = self.fs):
+ if os.path.isfile(path):
+ return fs.File(path)
+ return None
+ n = self.fs.Rsearch(self.path, file_node)
+ if n:
+ self._rfile = n
return self._rfile
def rstr(self):
assert len(fs.Repositories) == 4, fs.Repositories
r = map(lambda x, np=os.path.normpath: np(str(x)), fs.Repositories)
- assert r == ['foo', 'foo/bar', 'bar/foo', 'bar'], r
+ assert r == ['foo',
+ os.path.join('foo', 'bar'),
+ os.path.join('bar', 'foo'),
+ 'bar'], r
test = TestCmd(workdir = '')
test.subdir('rep1', 'rep2', 'rep3', 'work')
fs = SCons.Node.FS.FS()
fs.Repository(rep1, rep2, rep3)
- wf = fs.File(os.path.join('f1'))
- assert wf.rfile() is wf
+ f1 = fs.File(os.path.join('f1'))
+ assert f1.rfile() is f1
test.write([rep1, 'f2'], "")
- wf = fs.File('f2')
- assert not wf.rfile() is wf, wf.rfile()
- assert str(wf.rfile()) == os.path.join(rep1, 'f2'), str(wf.rfile())
+ f2 = fs.File('f2')
+ assert not f2.rfile() is f2, f2.rfile()
+ assert str(f2.rfile()) == os.path.join(rep1, 'f2'), str(f2.rfile())
test.subdir([rep2, 'f3'])
test.write([rep3, 'f3'], "")
- wf = fs.File('f3')
- assert not wf.rfile() is wf, wf.rfile()
- assert wf.rstr() == os.path.join(rep3, 'f3'), wf.rstr()
+ f3 = fs.File('f3')
+ assert not f3.rfile() is f3, f3.rfile()
+ assert f3.rstr() == os.path.join(rep3, 'f3'), f3.rstr()
+
+ assert fs.Rsearch('f1') is None
+ assert fs.Rsearch('f2')
+ assert fs.Rsearch(f3) is f3
assert not fs.Rsearch('f1', os.path.exists)
assert fs.Rsearch('f2', os.path.exists)
assert fs.Rsearch('f3', os.path.exists)
+ list = fs.Rsearchall([fs.Dir('d1')])
+ assert len(list) == 1, list
+ assert list[0].path == 'd1', list[0].path
+
+ list = fs.Rsearchall('d2')
+ assert list == [], list
+
+ test.subdir(['work', 'd2'])
+ list = fs.Rsearchall('d2')
+ assert list == ['d2'], list
+
+ test.subdir(['rep2', 'd2'])
+ list = fs.Rsearchall('d2')
+ assert list == ['d2', test.workpath('rep2', 'd2')], list
+
+ test.subdir(['rep1', 'd2'])
+ list = fs.Rsearchall('d2')
+ assert list == ['d2',
+ test.workpath('rep1', 'd2'),
+ test.workpath('rep2', 'd2')], list
+
+ list = fs.Rsearchall(['d3', 'd4'])
+ assert list == [], list
+
+ test.subdir(['work', 'd3'])
+ list = fs.Rsearchall(['d3', 'd4'])
+ assert list == ['d3'], list
+
+ test.subdir(['rep3', 'd4'])
+ list = fs.Rsearchall(['d3', 'd4'])
+ assert list == ['d3', test.workpath('rep3', 'd4')], list
+
+ list = fs.Rsearchall(string.join(['d3', 'd4'], os.pathsep))
+ assert list == ['d3', test.workpath('rep3', 'd4')], list
+
+ work_d4 = fs.File(os.path.join('work', 'd4'))
+ list = fs.Rsearchall(['d3', work_d4])
+ assert list == ['d3', work_d4], list
class find_fileTestCase(unittest.TestCase):
def runTest(self):