[meld] vc: Move repository root finding to class and adjust subclasses



commit a7b58ac64848c1fa51d53e35ee3f7a0af4d1002c
Author: Kai Willadsen <kai willadsen gmail com>
Date:   Sun Aug 18 09:45:07 2013 +1000

    vc: Move repository root finding to class and adjust subclasses
    
    The way Meld has previously dealt with figuring out whether a path is
    a valid repository is to try to create the Vc, and then catch the
    resulting explosion if it fails. While this works, it ends up having
    some very weird side effects in VcView, and makes for some overly
    complicated logic when figuring out what VC to use.

 meld/vc/_vc.py    |   55 +++++++++++++++++++++++++++-------------------------
 meld/vc/fossil.py |    7 ++---
 meld/vc/git.py    |    5 +--
 meld/vc/svk.py    |    7 ++---
 4 files changed, 37 insertions(+), 37 deletions(-)
---
diff --git a/meld/vc/_vc.py b/meld/vc/_vc.py
index 34b5223..1fd9bc9 100644
--- a/meld/vc/_vc.py
+++ b/meld/vc/_vc.py
@@ -105,21 +105,16 @@ class Vc(object):
 
     VC_COLUMNS = (DATA_NAME, DATA_STATE)
 
-    def __init__(self, location):
+    def __init__(self, path):
         # Save the requested comparison location. The location may be a
         # sub-directory of the repository we are diffing and can be useful in
         # limiting meld's output to the requested location.
         #
         # If the location requested is a file (e.g., a single-file command line
         # comparison) then the location is set to the containing directory.
-        if not os.path.isdir(location):
-            location = os.path.dirname(location)
-        self.location = location
-
-        if self.VC_ROOT_WALK:
-            self.root = self.find_repo_root(self.location)
-        else:
-            self.root = self.check_repo_root(self.location)
+        self.root, self.location = self.is_in_repo(path)
+        if not self.root:
+            raise ValueError
 
     def commit_command(self, message):
         raise NotImplementedError()
@@ -187,23 +182,6 @@ class Vc(object):
         """
         raise NotImplementedError()
 
-    def check_repo_root(self, location):
-        if not os.path.isdir(os.path.join(location, self.VC_DIR)):
-            raise ValueError
-        return location
-
-    def find_repo_root(self, location):
-        while True:
-            try:
-                return self.check_repo_root(location)
-            except ValueError:
-                pass
-            tmp = os.path.dirname(location)
-            if tmp == location:
-                break
-            location = tmp
-        raise ValueError()
-
     def get_working_directory(self, workdir):
         return workdir
 
@@ -272,6 +250,31 @@ class Vc(object):
         except:
             return False
 
+    @classmethod
+    def is_in_repo(cls, path):
+        root = None
+        location = path if os.path.isdir(path) else os.path.dirname(path)
+
+        if cls.VC_ROOT_WALK:
+            root = cls.find_repo_root(location)
+        elif cls.check_repo_root(location):
+            root = location
+        return root, location
+
+    @classmethod
+    def check_repo_root(cls, location):
+        return os.path.isdir(os.path.join(location, cls.VC_DIR))
+
+    @classmethod
+    def find_repo_root(cls, location):
+        while location:
+            if cls.check_repo_root(location):
+                return location
+
+            location, old = os.path.dirname(location), location
+            if location == old:
+                break
+
 
 class CachedVc(Vc):
 
diff --git a/meld/vc/fossil.py b/meld/vc/fossil.py
index 664008c..c29411c 100644
--- a/meld/vc/fossil.py
+++ b/meld/vc/fossil.py
@@ -71,12 +71,11 @@ class Vc(_vc.CachedVc):
         else:
             return True
 
+    @classmethod
     def check_repo_root(self, location):
         # Fossil uses a file -- not a directory
-        for metafile in self.VC_METADATA:
-            if os.path.isfile(os.path.join(location, metafile)):
-                return location
-        raise ValueError
+        return any(os.path.isfile(os.path.join(location, m))
+                   for m in self.VC_METADATA)
 
     def get_working_directory(self, workdir):
         return self.root
diff --git a/meld/vc/git.py b/meld/vc/git.py
index ca06e0e..22e0364 100644
--- a/meld/vc/git.py
+++ b/meld/vc/git.py
@@ -79,11 +79,10 @@ class Vc(_vc.CachedVc):
         except:
             return False
 
+    @classmethod
     def check_repo_root(self, location):
         # Check exists instead of isdir, since .git might be a git-file
-        if not os.path.exists(os.path.join(location, self.VC_DIR)):
-            raise ValueError
-        return location
+        return os.path.exists(os.path.join(location, self.VC_DIR))
 
     def commit_command(self, message):
         return [self.CMD, "commit", "-m", message]
diff --git a/meld/vc/svk.py b/meld/vc/svk.py
index e7b7e86..96cbf0a 100644
--- a/meld/vc/svk.py
+++ b/meld/vc/svk.py
@@ -50,6 +50,7 @@ class Vc(svn.Vc):
     CMD = "svk"
     NAME = "SVK"
 
+    @classmethod
     def check_repo_root(self, location):
         try:
             # `svk info` may be interactive. It can ask to create its repository, we
@@ -60,7 +61,5 @@ class Vc(svn.Vc):
             # stream redirected to a newly created pipe, restore sanity manually
             cmdout(['stty', 'sane'], stdout=NULL, stderr=NULL, stdin=None)
         except OSError:
-            raise ValueError()
-        if status != 0:
-            raise ValueError()
-        return location
+            return False
+        return status == 0


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]