[Zope3-checkins] CVS: Zope3/src/zope/fssync - fsmerger.py:1.7

Guido van Rossum guido@python.org
Tue, 3 Jun 2003 14:25:05 -0400


Update of /cvs-repository/Zope3/src/zope/fssync
In directory cvs.zope.org:/tmp/cvs-serv31236/zope/fssync

Modified Files:
	fsmerger.py 
Log Message:
I discovered a cluster of cases that weren't handled correctly, where
a remote directory tree was removed.  Unit tests for these cases were
conspicuously absent!  Fixed all that.  Also renamed some unit tests:
'tree' now refers to a non-empty directory tree, 'dir' refers to an
empty directory.



=== Zope3/src/zope/fssync/fsmerger.py 1.6 => 1.7 ===
--- Zope3/src/zope/fssync/fsmerger.py:1.6	Thu May 29 11:07:29 2003
+++ Zope3/src/zope/fssync/fsmerger.py	Tue Jun  3 14:24:35 2003
@@ -17,6 +17,7 @@
 """
 
 import os
+import shutil
 
 from os.path import exists, isfile, isdir, split, join
 from os.path import realpath, normcase, normpath
@@ -118,12 +119,7 @@
                 return
 
             if not rentry:
-                try:
-                    os.rmdir(localdir)
-                except os.error:
-                    pass
-                self.reportdir("D", localdir)
-                lentry.clear()
+                self.clear_dir(localdir)
                 return
 
         if exists(localdir):
@@ -134,11 +130,23 @@
                 else:
                     self.reportdir("A", localdir)
             else:
-                self.reportdir("/", localdir)
+                if rentry or exists(remotedir):
+                    self.reportdir("/", localdir)
+                else:
+                    # Tree removed remotely, must recurse down locally
+                    for name in lentrynames:
+                        self.merge(join(localdir, name), join(remotedir, name))
+                    self.clear_dir(localdir)
+                    return
+
             lnames = dict([(normcase(name), name)
                            for name in os.listdir(localdir)])
         else:
-            if lentry.get("flag") != "removed" and (rentry or rentrynames):
+            flag = lentry.get("flag")
+            if flag == "removed":
+                self.reportdir("R", localdir)
+                return # There's no point in recursing down!
+            if rentry or rentrynames:
                 fsutil.ensuredir(localdir)
                 lentry.update(rentry)
                 self.reportdir("N", localdir)
@@ -167,6 +175,19 @@
         for ncname in ncnames:
             name = names[ncname]
             self.merge(join(localdir, name), join(remotedir, name))
+
+    def clear_dir(self, localdir):
+        lentry = self.metadata.getentry(localdir)
+        lentry.clear()
+        localzopedir = join(localdir, "@@Zope")
+        if os.path.isdir(localzopedir):
+            shutil.rmtree(localzopedir)
+        try:
+            os.rmdir(localdir)
+        except os.error:
+            self.reportdir("?", localdir)
+        else:
+            self.reportdir("D", localdir)
 
     def reportdir(self, letter, localdir):
         """Helper to report something for a directory.