Re: [sabayon] new function in storage module to get a path to a file/directory in uncompressed temp profile
- From: Mark McLoughlin <markmc redhat com>
- To: John Dennis <jdennis redhat com>
- Cc: sabayon-list <sabayon-list gnome org>
- Subject: Re: [sabayon] new function in storage module to get a path to a file/directory in uncompressed temp profile
- Date: Tue, 21 Jun 2005 09:00:08 +0100
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]