diff options
author | Ludwig Hähne <pankrat@tigris.org> | 2008-09-08 20:23:30 (GMT) |
---|---|---|
committer | Ludwig Hähne <pankrat@tigris.org> | 2008-09-08 20:23:30 (GMT) |
commit | 81e7f4fc4b7244507df996a5944743bb391781a8 (patch) | |
tree | df69a77b65c8cc4f4204d5f1870d2e35087cd78a /src | |
parent | 043febbaa29e21174ebf96ffe21cd91aca6cae95 (diff) | |
download | SCons-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.py | 12 | ||||
-rw-r--r-- | src/engine/SCons/Node/FS.py | 43 |
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() + |