Re: [sabayon] new function in storage module to get a path to a file/directory in uncompressed temp profile



Hi John,

On Mon, 2005-06-20 at 14:46 -0400, John Dennis wrote:
> On Mon, 2005-06-20 at 17:19 +0100, Mark McLoughlin wrote:
> > On Mon, 2005-06-20 at 10:14 +0100, Mark McLoughlin wrote:
> > 
> > >   4) The copy_tree (foo, bar, "") thing is making me nervous too. 
> > 
> > 	I just noticed "apps" and "desktop" directories in the home directory
> > of a protosession. It looks we're not extracting the GConf tree in ~/
> > rather than ~/.gconf. I'd guess that this is the cause.
> 
> O.K. just checked a fix into CVS. I added a utility function to util.py
> called split_path() that splits a path depending on whether a head or
> tail of the path is passed to it. extract now uses that function to
> split the path returned by get_extract_src_path() into the storage
> directory (head) and the path requested for extracting (tail), these are
> then passed to copy_tree(). Also get_extract_src_path() now returns just
> a path instead of a tuple.

	It seems a little strange to combine the elements of the path and then
try and extract them again. I think this is especially difficult because
the basename of the destination path of a directory differs from the
basename of the source path if its in the %revisions% directory of the
profile.

	e.g. you have to copy from an extract_src_path of 

  /tmp/foo/%revisions%/.gconf.xml.defaults/2

	to a destination of

  /home/foo/.gconf.xml.defaults

	So, you need the 4th argument of copy_tree() to be "2" and the 3rd to
be ".gconf.xml.defaults".

	May I suggest the patch attached?

> Testing has been limited, but it seems to work.

	If you run "./unittests.py storage" in the lib directory it tests the
code pretty extensively. Its triggering some issues at the moment.

Cheers,
Mark.
Index: storage.py
===================================================================
RCS file: /cvs/gnome/sabayon/lib/storage.py,v
retrieving revision 1.26
diff -u -p -r1.26 storage.py
--- storage.py	20 Jun 2005 18:39:19 -0000	1.26
+++ storage.py	21 Jun 2005 07:48:05 -0000
@@ -598,20 +598,8 @@ class ProfileStorage:
                     os.path.join (self.revisions_path, path, item_revision))
 
         self.needs_saving = True
-        
-    def get_extract_src_path (self, path, revision = None):
-        """Return the src path of a file or directory for extraction from the profile.
 
-        @path: the relative path of the file or directory to extract.
-        This is the same path used with ProfileStorage::add().
-        @revision: an (optional) revision identifier which specifies
-        the revision of the file or directory which should be extracted.
-        The revision identifier must have been returned from
-        ProfileStorage::get_revisions() and may be a profile or file
-        revision.
-        """
-        extract_src_path = item_type = item_revison = None
-        
+    def __get_item_type_and_revision (self, path, revision):
         self.__unpack ()
 
         if not revision:
@@ -639,20 +627,31 @@ class ProfileStorage:
                 item_type     = item.prop ("type")
                 item_revision = item.prop ("revision")
 
-        if self.__item_revision_is_current (path, item_type, item_revision):
-            if item_type == "directory":
-                extract_src_path = os.path.join (self.temp_path, path)
-            else:
-                extract_src_path = os.path.join (self.temp_path, path)
+        return (item_type,
+                item_revision,
+                self.__item_revision_is_current (path, item_type, item_revision))
+        
+    def get_extract_src_path (self, path, revision = None):
+        """Return the src path of a file or directory for extraction from the profile.
+
+        @path: the relative path of the file or directory to extract.
+        This is the same path used with ProfileStorage::add().
+        @revision: an (optional) revision identifier which specifies
+        the revision of the file or directory which should be extracted.
+        The revision identifier must have been returned from
+        ProfileStorage::get_revisions() and may be a profile or file
+        revision.
+        """
+        (item_type, item_revision, is_current) = self.__get_item_type_and_revision (path, revision)
+        
+        if is_current:
+            extract_src_path = os.path.join (self.temp_path, path)
         else:
-            if item_type == "directory":
-                extract_src_path = os.path.join (self.revisions_path, path)
-            else:
-                extract_src_path = os.path.join (self.revisions_path, path, item_revision)
+            extract_src_path = os.path.join (self.revisions_path, path, item_revision)
 
-        extract_src_path = os.path.normpath(extract_src_path)
         dprint ("Extract src path for '%s', revision %s is '%s'" % (path, revision, extract_src_path))
-        return extract_src_path
+        
+        return os.path.normpath (extract_src_path)
 
     def extract (self, path, dst_dir, overwrite = False, revision = None):
         """Extract a file or directory from the profile.
@@ -670,19 +669,27 @@ class ProfileStorage:
         """
         dprint ("Extracting '%s' to '%s', revision %s" % (path, dst_dir, revision))
         
-        path = os.path.normpath(path)
-        extract_src_path = self.get_extract_src_path(path, revision)
+        (item_type, item_revision, is_current) = self.__get_item_type_and_revision (path, revision)
 
-        if os.path.isdir(extract_src_path):
-            (root, subdir) = util.split_path(extract_src_path, tail=path)
-            copy_tree (dst_dir, root, subdir, None, overwrite)
+        if item_type == "directory":
+            if is_current:
+                copy_tree (dst_dir, self.temp_path, path, None, overwrite)
+            else:
+                copy_tree (dst_dir,
+                           os.path.join (self.revisions_path, path),
+                           path,
+                           item_revision,
+                           overwrite)
         else:
             dst_path = os.path.join (dst_dir, path)
             if overwrite or not os.path.exists (dst_path):
                 dirname = os.path.dirname (dst_path)
                 if not os.path.exists (dirname):
                     os.makedirs (dirname)
-                shutil.copy2 (extract_src_path, dst_path)
+                if is_current:
+                    shutil.copy2 (os.path.join (self.temp_path, path), dst_path)
+                else:
+                    shutil.copy2 (os.path.join (self.revisions_path, path, item_revision), dst_path)
 
     def list (self, source = None, profile_revision = None):
         """List the current contents of the profile.
Index: util.py
===================================================================
RCS file: /cvs/gnome/sabayon/lib/util.py,v
retrieving revision 1.21
diff -u -p -r1.21 util.py
--- util.py	20 Jun 2005 18:39:19 -0000	1.21
+++ util.py	21 Jun 2005 07:48:05 -0000
@@ -144,45 +144,6 @@ def init_gettext ():
     locale.setlocale (locale.LC_ALL, "")
     gettext.install (PACKAGE, os.path.join (DATADIR, "locale"))
 
-def split_path(path, head=None, tail=None):
-    '''Given a path split it into a head and tail. If head is passed then
-    it is assumed to comprise the first part of the full path. If tail is
-    passed it is assumed to comprise the second part of the full path.
-    The path, head, and tail are made canonical via os.path.normpath prior
-    to the operations. ValueErrors are raised if head is not present at the
-    start of the path or if the path does not end with tail. The split must
-    occur on a directory separator boundary.
-
-    The return value is the tuple (head, tail) in canonical form.'''
-    path = os.path.normpath(path)
-
-    if tail is not None:
-        tail = os.path.normpath(tail)
-        if tail[0] == '/':
-            tail = tail[1:]
-        if not path.endswith(tail):
-            raise ValueError
-        path_len = len (path)
-        tail_len = len (tail)
-        dir_split = path_len - tail_len - 1
-        if path[dir_split] != '/':
-            raise ValueError
-        return (path[:dir_split], path[dir_split+1:])
-
-    if head is not None:
-        head = os.path.normpath(head)
-        if head[-1] == '/':
-            head = head[:-1]
-        if not path.startswith(head):
-            raise ValueError
-        head_len = len (head)
-        dir_split = head_len
-        if path[dir_split] != '/':
-            raise ValueError
-        return (path[:dir_split], path[dir_split+1:])
-        
-    raise ValueError
-
 #
 # os.spawn() doesn't handle EINTR from waitpid() on Linux:
 #  http://sourceforge.net/tracker/?group_id=5470&atid=105470&func=detail&aid=686667


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