diff options
author | Steven Knight <knight@baldmt.com> | 2005-05-13 01:44:10 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2005-05-13 01:44:10 (GMT) |
commit | f82f4ce830289473187299db9962f819ed74c877 (patch) | |
tree | f9abe466c67b9ca99adb91b2ff25529ca1096230 /src/engine/SCons | |
parent | f431ccfa16fad1d0db1009eacfdace4f80e9195e (diff) | |
download | SCons-f82f4ce830289473187299db9962f819ed74c877.zip SCons-f82f4ce830289473187299db9962f819ed74c877.tar.gz SCons-f82f4ce830289473187299db9962f819ed74c877.tar.bz2 |
Eliminate multiple calls to os.stat() to fetch file info.
Diffstat (limited to 'src/engine/SCons')
-rw-r--r-- | src/engine/SCons/Node/FS.py | 53 | ||||
-rw-r--r-- | src/engine/SCons/Node/FSTests.py | 78 | ||||
-rw-r--r-- | src/engine/SCons/Script/Main.py | 17 | ||||
-rw-r--r-- | src/engine/SCons/Script/SConscript.py | 5 | ||||
-rw-r--r-- | src/engine/SCons/Tool/zip.py | 2 |
5 files changed, 128 insertions, 27 deletions
diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 9d7086c..f2234f7 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -175,9 +175,8 @@ Unlink = SCons.Action.Action(UnlinkFunc, None) def MkdirFunc(target, source, env): t = target[0] - p = t.abspath - if not t.fs.exists(p): - t.fs.mkdir(p) + if not t.exists(): + t.fs.mkdir(t.abspath) return 0 Mkdir = SCons.Action.Action(MkdirFunc, None, presub=None) @@ -469,14 +468,39 @@ class Base(SCons.Node.Node): rstr = __str__ + def stat(self): + "__cacheable__" + try: return self.fs.stat(self.abspath) + except os.error: return None + def exists(self): "__cacheable__" - return self.fs.exists(self.abspath) + return not self.stat() is None def rexists(self): "__cacheable__" return self.rfile().exists() + def getmtime(self): + return self.stat()[stat.ST_MTIME] + + def isdir(self): + st = self.stat() + return not st is None and stat.S_ISDIR(st[stat.ST_MODE]) + + def isfile(self): + st = self.stat() + return not st is None and stat.S_ISREG(st[stat.ST_MODE]) + + if hasattr(os, 'symlink'): + def islink(self): + try: st = self.fs.lstat(self.abspath) + except os.error: return 0 + return stat.S_ISLNK(st[stat.ST_MODE]) + else: + def islink(self): + return 0 # no symlinks + def is_under(self, dir): if self is dir: return 1 @@ -563,7 +587,7 @@ class Entry(Base): class.""" def disambiguate(self): - if self.fs.isdir(self.abspath): + if self.isdir(): self.__class__ = Dir self._morph() else: @@ -594,15 +618,15 @@ class Entry(Base): Since this should return the real contents from the file system, we check to see into what sort of subclass we should morph this Entry.""" - if self.fs.isfile(self.abspath): + if self.isfile(): self.__class__ = File self._morph() return self.get_contents() - if self.fs.isdir(self.abspath): + if self.isdir(): self.__class__ = Dir self._morph() return self.get_contents() - if self.fs.islink(self.abspath): + if self.islink(): return '' # avoid errors for dangling symlinks raise AttributeError @@ -667,6 +691,8 @@ class LocalFS: return os.path.isfile(path) def link(self, src, dst): return os.link(src, dst) + def lstat(self, path): + return os.lstat(path) def listdir(self, path): return os.listdir(path) def makedirs(self, path): @@ -687,12 +713,9 @@ class LocalFS: if hasattr(os, 'symlink'): def islink(self, path): return os.path.islink(path) - def exists_or_islink(self, path): - return os.path.exists(path) or os.path.islink(path) else: def islink(self, path): return 0 # no symlinks - exists_or_islink = exists if not SCons.Memoize.has_metaclass: _FSBase = LocalFS @@ -1491,7 +1514,7 @@ class File(Base): def get_timestamp(self): if self.rexists(): - return self.fs.getmtime(self.rfile().abspath) + return self.rfile().getmtime() else: return 0 @@ -1593,13 +1616,13 @@ class File(Base): # Push this file out to cache before the superclass Node.built() # method has a chance to clear the build signature, which it # will do if this file has a source scanner. - if self.fs.CachePath and self.fs.exists(self.path): + if self.fs.CachePath and self.exists(): CachePush(self, [], None) self.fs.clear_cache() SCons.Node.Node.built(self) def visited(self): - if self.fs.CachePath and self.fs.cache_force and self.fs.exists(self.path): + if self.fs.CachePath and self.fs.cache_force and self.exists(): CachePush(self, None, None) def has_src_builder(self): @@ -1664,7 +1687,7 @@ class File(Base): def remove(self): """Remove this file.""" - if self.fs.exists_or_islink(self.path): + if self.exists() or self.islink(): self.fs.unlink(self.path) return 1 return None diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index 935f0a2..8626185 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -605,6 +605,83 @@ class BuildDirTestCase(unittest.TestCase): self.failIf(errors) +class BaseTestCase(_tempdirTestCase): + def test_stat(self): + """Test the Base.stat() method""" + test = self.test + test.write("e1", "e1\n") + fs = SCons.Node.FS.FS() + + e1 = fs.Entry('e1') + s = e1.stat() + assert not s is None, s + + e2 = fs.Entry('e2') + s = e2.stat() + assert s is None, s + + def test_getmtime(self): + """Test the Base.getmtime() method""" + test = self.test + test.write("file", "file\n") + fs = SCons.Node.FS.FS() + + file = fs.Entry('file') + assert file.getmtime() + + def test_isdir(self): + """Test the Base.isdir() method""" + test = self.test + test.subdir('dir') + test.write("file", "file\n") + fs = SCons.Node.FS.FS() + + dir = fs.Entry('dir') + assert dir.isdir() + + file = fs.Entry('file') + assert not file.isdir() + + nonexistent = fs.Entry('nonexistent') + assert not nonexistent.isdir() + + def test_isfile(self): + """Test the Base.isfile() method""" + test = self.test + test.subdir('dir') + test.write("file", "file\n") + fs = SCons.Node.FS.FS() + + dir = fs.Entry('dir') + assert not dir.isfile() + + file = fs.Entry('file') + assert file.isfile() + + nonexistent = fs.Entry('nonexistent') + assert not nonexistent.isfile() + + if hasattr(os, 'symlink'): + def test_islink(self): + """Test the Base.islink() method""" + test = self.test + test.subdir('dir') + test.write("file", "file\n") + test.symlink("symlink", "symlink") + fs = SCons.Node.FS.FS() + + dir = fs.Entry('dir') + assert not dir.islink() + + file = fs.Entry('file') + assert not file.islink() + + symlink = fs.Entry('symlink') + assert symlink.islink() + + nonexistent = fs.Entry('nonexistent') + assert not nonexistent.islink() + class FSTestCase(_tempdirTestCase): def test_runTest(self): """Test FS (file system) Node operations @@ -2625,6 +2702,7 @@ if __name__ == "__main__": suite.addTest(SpecialAttrTestCase()) suite.addTest(SaveStringsTestCase()) tclasses = [ + BaseTestCase, FSTestCase, DirTestCase, RepositoryTestCase, diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index fd2a914..7dcb987 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -191,16 +191,17 @@ class BuildTask(SCons.Taskmaster.Task): class CleanTask(SCons.Taskmaster.Task): """An SCons clean task.""" def show(self): - if (self.targets[0].has_builder() or self.targets[0].side_effect) \ - and not os.path.isdir(str(self.targets[0])): - display("Removed " + str(self.targets[0])) - if SCons.Environment.CleanTargets.has_key(self.targets[0]): - files = SCons.Environment.CleanTargets[self.targets[0]] + target = self.targets[0] + if (target.has_builder() or target.side_effect) and not target.isdir(): + display("Removed " + str(target)) + if SCons.Environment.CleanTargets.has_key(target): + files = SCons.Environment.CleanTargets[target] for f in files: SCons.Util.fs_delete(str(f), 0) def remove(self): - if self.targets[0].has_builder() or self.targets[0].side_effect: + target = self.targets[0] + if target.has_builder() or target.side_effect: for t in self.targets: try: removed = t.remove() @@ -209,8 +210,8 @@ class CleanTask(SCons.Taskmaster.Task): else: if removed: display("Removed " + str(t)) - if SCons.Environment.CleanTargets.has_key(self.targets[0]): - files = SCons.Environment.CleanTargets[self.targets[0]] + if SCons.Environment.CleanTargets.has_key(target): + files = SCons.Environment.CleanTargets[target] for f in files: SCons.Util.fs_delete(str(f)) diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index 7ca9993..af9d492 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -184,9 +184,8 @@ def _SConscript(fs, *files, **kw): # during the actual build phase. f.build() f.builder_set(None) - s = str(f) - if os.path.exists(s): - _file_ = open(s, "r") + if f.exists(): + _file_ = open(str(f), "r") if _file_: # Chdir to the SConscript directory. Use a path # name relative to the SConstruct file so that if diff --git a/src/engine/SCons/Tool/zip.py b/src/engine/SCons/Tool/zip.py index fe9ce32..f0d4ed0 100644 --- a/src/engine/SCons/Tool/zip.py +++ b/src/engine/SCons/Tool/zip.py @@ -56,7 +56,7 @@ if internal_zip: compression = env.get('ZIPCOMPRESSION', 0) zf = zipfile.ZipFile(str(target[0]), 'w', compression) for s in source: - if os.path.isdir(str(s)): + if s.isdir(): os.path.walk(str(s), visit, zf) else: zf.write(str(s)) |