Commits

Gary Oberbrunner committed 7289f29

Fix #2708 by making Delete able to delete broken symlinks and dir symlinks.
Thanks to David Garcia Garzon for the patch.

Comments (0)

Files changed (2)

src/engine/SCons/Defaults.py

         dest = [dest]
     for entry in dest:
         entry = str(entry)
-        if not must_exist and not os.path.exists(entry):
+        # os.path.exists returns False with broken links that exist
+        entry_exists = os.path.exists(entry) or os.path.islink(entry)
+        if not entry_exists and not must_exist:
             continue
-        if not os.path.exists(entry) or os.path.isfile(entry):
-            os.unlink(entry)
-            continue
-        else:
+        # os.path.isdir returns True when entry is a link to a dir
+        if os.path.isdir(entry) and not os.path.islink(entry):
             shutil.rmtree(entry, 1)
             continue
+        os.unlink(entry)
 
 def delete_strfunc(dest, must_exist=0):
     return 'Delete(%s)' % get_paths_str(dest)
 test.write('SConstruct', """
 Execute(Delete('f1'))
 Execute(Delete('d2'))
+Execute(Delete('symlinks/filelink'))
+Execute(Delete('symlinks/brokenlink'))
+Execute(Delete('symlinks/dirlink'))
+
 def cat(env, source, target):
     target = str(target[0])
     f = open(target, "wb")
 test.write('f14', "f14\n")
 test.subdir('d15')
 test.write('f16.in', "f16.in\n")
+test.subdir('symlinks')
+test.subdir('symlinks/dirtarget')
+test.write('symlinks/dirtarget/dircontent', 'dircontent content\n')
+test.write('symlinks/filetarget', 'filetarget content\n')
+test.symlink('filetarget', 'symlinks/filelink')
+test.symlink('dirtarget', 'symlinks/dirlink')
+test.symlink('brokentarget', 'symlinks/brokenlink')
 
 expect = test.wrap_stdout(read_str = """\
 Delete("f1")
 Delete("d2")
+Delete("symlinks/filelink")
+Delete("symlinks/brokenlink")
+Delete("symlinks/dirlink")
 """,
                           build_str = """\
 Delete("d11-nonexistent.out")
 test.must_exist('f14')
 test.must_exist('d15')
 test.must_not_exist('f16.out')
+test.must_exist('symlinks')
+test.must_exist('symlinks/dirtarget')
+test.must_exist('symlinks/dirtarget/dircontent')
+test.must_exist('symlinks/filetarget')
+test.must_exist('symlinks/filelink')
+test.must_exist('symlinks/brokenlink')
+test.must_exist('symlinks/dirlink')
 
 test.run()
 
 test.must_not_exist('f14')
 test.must_not_exist('d15')
 test.must_match('f16.out', "f16.in\n")
+test.must_exist('symlinks')
+test.must_exist('symlinks/dirtarget')
+test.must_exist('symlinks/dirtarget/dircontent')
+test.must_exist('symlinks/filetarget')
+test.must_not_exist('symlinks/filelink')
+test.must_not_exist('symlinks/brokenlink')
+test.must_not_exist('symlinks/dirlink')
 
 test.write("SConstruct", """\
 def cat(env, source, target):