summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAbdo Roig-Maranges <abdo.roig@gmail.com>2013-02-10 11:59:09 +0100
committerAbdo Roig-Maranges <abdo.roig@gmail.com>2013-02-12 12:08:44 +0100
commit94bf56dd024b4fa33b5ae4c80f5091fec0995d1c (patch)
tree419756254da363b35116af708c3779805a959d35
parente6b847b34d2f48a60dabde39d96d227f1f818c6c (diff)
downloadranger-94bf56dd024b4fa33b5ae4c80f5091fec0995d1c.tar.gz
Support for extracting metadata from version control systems
  * Makes fsobject aware of vcs.
  * Makes directory get vcs status data when loading content.
  * Adds a config option to enable/disable the vcs info feature.
-rw-r--r--ranger/fsobject/directory.py29
-rw-r--r--ranger/fsobject/file.py3
-rw-r--r--ranger/fsobject/fsobject.py40
3 files changed, 71 insertions, 1 deletions
diff --git a/ranger/fsobject/directory.py b/ranger/fsobject/directory.py
index 2aa47a64..fa5db6cf 100644
--- a/ranger/fsobject/directory.py
+++ b/ranger/fsobject/directory.py
@@ -72,6 +72,8 @@ class Directory(FileSystemObject, Accumulator, Loadable, SettingsAware):
     content_outdated = False
     content_loaded = False
 
+    has_vcschild=False
+
     _cumulative_size_calculated = False
 
     sort_dict = {
@@ -224,6 +226,10 @@ class Directory(FileSystemObject, Accumulator, Loadable, SettingsAware):
 
                 files = []
                 disk_usage = 0
+
+                self.has_vcschild = False
+                self.load_vcs()
+
                 for name in filenames:
                     try:
                         file_lstat = os_lstat(name)
@@ -248,10 +254,33 @@ class Directory(FileSystemObject, Accumulator, Loadable, SettingsAware):
                         item = File(name, preload=stats, path_is_abs=True)
                         item.load()
                         disk_usage += item.size
+
+                    # Load vcs data
+                    if self.settings.vcs_aware:
+                        item.load_vcs()
+                        if item.vcs and item.vcs.vcsname in self.settings.vcs_backends:
+                            self.has_vcschild = True
+                            try:
+                                if self.vcs_outdated or item.vcs_outdated:
+                                    item.vcs_outdated = False
+                                    item.vcs.get_status()  # caches the file status for get_file_status()
+                                    item.vcsbranch = item.vcs.get_branch()
+                                    item.vcshead = item.vcs.get_info(item.vcs.HEAD)
+                                    if item.path == item.vcs.root:
+                                        item.vcsremotestatus = item.vcs.get_remote_status()
+                                else:
+                                    item.vcsbranch = self.vcsbranch
+                                    item.vcshead = self.vcshead
+                                item.vcsfilestatus = item.vcs.get_file_status(item.path)
+                            except:
+                                raise
+                                self.fm.notify("Can not load vcs data on %s" % item.path, bad=True)
+
                     files.append(item)
                     self.percent = 100 * len(files) // len(filenames)
                     yield
                 self.disk_usage = disk_usage
+                self.vcs_outdated = False
 
                 self.filenames = filenames
                 self.files = files
diff --git a/ranger/fsobject/file.py b/ranger/fsobject/file.py
index 5831ed3f..8d75e740 100644
--- a/ranger/fsobject/file.py
+++ b/ranger/fsobject/file.py
@@ -3,6 +3,7 @@
 
 import re
 from ranger.fsobject import FileSystemObject
+from ranger.core.shared import SettingsAware
 
 N_FIRST_BYTES = 256
 control_characters = set(chr(n) for n in
@@ -37,7 +38,7 @@ PREVIEW_WHITELIST = re.compile(r"""
         $
 """, re.VERBOSE | re.IGNORECASE)
 
-class File(FileSystemObject):
+class File(FileSystemObject, SettingsAware):
     is_file = True
     preview_data = None
     preview_known = False
diff --git a/ranger/fsobject/fsobject.py b/ranger/fsobject/fsobject.py
index 02b32958..c044dbdb 100644
--- a/ranger/fsobject/fsobject.py
+++ b/ranger/fsobject/fsobject.py
@@ -18,6 +18,7 @@ from ranger.ext.shell_escape import shell_escape
 from ranger.ext.spawn import spawn
 from ranger.ext.lazy_property import lazy_property
 from ranger.ext.human_readable import human_readable
+from ranger.vcs import Vcs
 
 if hasattr(str, 'maketrans'):
     maketrans = str.maketrans
@@ -67,6 +68,13 @@ class FileSystemObject(FileManagerAware):
 
     size = 0
 
+    (vcs,
+     vcsfilestatus,
+     vcsremotestatus,
+     vcsbranch,
+     vcshead) = (None,) * 5
+
+    vcs_outdated = False
 
     def __init__(self, path, preload=None, path_is_abs=False):
         if not path_is_abs:
@@ -185,6 +193,38 @@ class FileSystemObject(FileManagerAware):
                 return None  # it is impossible to get the link destination
         return self.path
 
+    def load_vcs(self):
+        """
+        Reads data regarding the version control system the object is on.
+        Does not load content specific data.
+        """
+
+        vcs = Vcs(self.path)
+
+        # Not under vcs
+        if vcs.root == None:
+            return
+
+        # Already know about the right vcs
+        elif self.vcs and abspath(vcs.root) == abspath(self.vcs.root):
+            self.vcs.update()
+
+        # Need new Vcs object and self.path is the root
+        elif self.vcs == None and abspath(vcs.root) == abspath(self.path):
+            self.vcs = vcs
+            self.vcs_outdated = True
+
+        # Otherwise, find the root, and try to get the Vcs object from there
+        else:
+            rootdir = self.fm.get_directory(vcs.root)
+            rootdir.load_if_outdated()
+
+            # Get the Vcs object from rootdir
+            rootdir.load_vcs()
+            self.vcs = rootdir.vcs
+            if rootdir.vcs_outdated:
+                self.vcs_outdated = True
+
     def load(self):
         """
         reads useful information about the filesystem-object from the