summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLudwig Hähne <pankrat@tigris.org>2008-09-08 20:23:30 (GMT)
committerLudwig Hähne <pankrat@tigris.org>2008-09-08 20:23:30 (GMT)
commit81e7f4fc4b7244507df996a5944743bb391781a8 (patch)
treedf69a77b65c8cc4f4204d5f1870d2e35087cd78a /src
parent043febbaa29e21174ebf96ffe21cd91aca6cae95 (diff)
downloadSCons-81e7f4fc4b7244507df996a5944743bb391781a8.zip
SCons-81e7f4fc4b7244507df996a5944743bb391781a8.tar.gz
SCons-81e7f4fc4b7244507df996a5944743bb391781a8.tar.bz2
Issue 1307: Invalidate node caches after Execute()
Diffstat (limited to 'src')
-rw-r--r--src/engine/SCons/Defaults.py12
-rw-r--r--src/engine/SCons/Node/FS.py43
2 files changed, 54 insertions, 1 deletions
diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py
index aebef39..067f22d 100644
--- a/src/engine/SCons/Defaults.py
+++ b/src/engine/SCons/Defaults.py
@@ -169,6 +169,7 @@ def get_paths_str(dest):
return '"' + str(dest) + '"'
def chmod_func(dest, mode):
+ SCons.Node.FS.invalidate_node_memos(dest)
if not SCons.Util.is_List(dest):
dest = [dest]
for element in dest:
@@ -180,6 +181,7 @@ def chmod_strfunc(dest, mode):
Chmod = ActionFactory(chmod_func, chmod_strfunc)
def copy_func(dest, src):
+ SCons.Node.FS.invalidate_node_memos(dest)
if SCons.Util.is_List(src) and os.path.isdir(dest):
for file in src:
shutil.copy2(file, dest)
@@ -194,6 +196,7 @@ Copy = ActionFactory(copy_func,
convert=str)
def delete_func(dest, must_exist=0):
+ SCons.Node.FS.invalidate_node_memos(dest)
if not SCons.Util.is_List(dest):
dest = [dest]
for entry in dest:
@@ -213,6 +216,7 @@ def delete_strfunc(dest, must_exist=0):
Delete = ActionFactory(delete_func, delete_strfunc)
def mkdir_func(dest):
+ SCons.Node.FS.invalidate_node_memos(dest)
if not SCons.Util.is_List(dest):
dest = [dest]
for entry in dest:
@@ -221,11 +225,17 @@ def mkdir_func(dest):
Mkdir = ActionFactory(mkdir_func,
lambda dir: 'Mkdir(%s)' % get_paths_str(dir))
-Move = ActionFactory(lambda dest, src: os.rename(src, dest),
+def move_func(dest, src):
+ SCons.Node.FS.invalidate_node_memos(dest)
+ SCons.Node.FS.invalidate_node_memos(src)
+ os.rename(src, dest)
+
+Move = ActionFactory(move_func,
lambda dest, src: 'Move("%s", "%s")' % (dest, src),
convert=str)
def touch_func(dest):
+ SCons.Node.FS.invalidate_node_memos(dest)
if not SCons.Util.is_List(dest):
dest = [dest]
for file in dest:
diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py
index 182acd2..a94171b 100644
--- a/src/engine/SCons/Node/FS.py
+++ b/src/engine/SCons/Node/FS.py
@@ -2994,3 +2994,46 @@ class FileFinder:
return result
find_file = FileFinder().find_file
+
+
+def invalidate_node_memos(targets):
+ """
+ Invalidate the memoized values of all Nodes (files or directories)
+ that are associated with the given entries. Has been added to
+ clear the cache of nodes affected by a direct execution of an
+ action (e.g. Delete/Copy/Chmod). Existing Node caches become
+ inconsistent if the action is run through Execute(). The argument
+ `targets` can be a single Node object or filename, or a sequence
+ of Nodes/filenames.
+ """
+ from traceback import extract_stack
+
+ # First check if the cache really needs to be flushed. Only
+ # actions run in the SConscript with Execute() seem to be
+ # affected. XXX The way to check if Execute() is in the stacktrace
+ # is a very dirty hack and should be replaced by a more sensible
+ # solution.
+ must_invalidate = 0
+ tb = extract_stack()
+ for f in tb:
+ if f[2] == 'Execute' and f[0][-14:] == 'Environment.py':
+ must_invalidate = 1
+ if not must_invalidate:
+ return
+
+ if not SCons.Util.is_List(targets):
+ targets = [targets]
+
+ for entry in targets:
+ # If the target is a Node object, clear the cache. If it is a
+ # filename, look up potentially existing Node object first.
+ try:
+ entry.clear_memoized_values()
+ except AttributeError:
+ # Not a Node object, try to look up Node by filename. XXX
+ # This creates Node objects even for those filenames which
+ # do not correspond to an existing Node object.
+ node = get_default_fs().Entry(entry)
+ if node:
+ node.clear_memoized_values()
+