summaryrefslogtreecommitdiffstats
path: root/pym
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2008-07-01 08:10:17 +0000
committerZac Medico <zmedico@gentoo.org>2008-07-01 08:10:17 +0000
commit27c45c6b94e642f5914a9e592b18fba4ffdec1f6 (patch)
treef8fc8b28a3e66b71a39b9c0cb3696a0125e02ba0 /pym
parent28fbecadc0b0fce93df1cc7f7c7b5bf2e4b8fc73 (diff)
downloadportage-27c45c6b94e642f5914a9e592b18fba4ffdec1f6.tar.gz
portage-27c45c6b94e642f5914a9e592b18fba4ffdec1f6.tar.bz2
portage-27c45c6b94e642f5914a9e592b18fba4ffdec1f6.zip
Split out a write_contents() function and a vardbapi.removeFromContents()
function. This is refactoring of code from the blocker file collision contents handling in dblink.treewalk(). Also, there is a new dblink._match_contents() method derived from isowner(). It returns the exact path from the contents file that matches the given path, regardless of path differences due to things such as symlinks. svn path=/main/trunk/; revision=10864
Diffstat (limited to 'pym')
-rw-r--r--pym/portage/dbapi/vartree.py98
1 files changed, 68 insertions, 30 deletions
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
index cd1e1ddca..d508d46c9 100644
--- a/pym/portage/dbapi/vartree.py
+++ b/pym/portage/dbapi/vartree.py
@@ -891,6 +891,35 @@ class vardbapi(dbapi):
return dblink(category, pf, self.root,
self.settings, vartree=self.vartree)
+ def removeFromContents(self, pkg, paths, relative_paths=True):
+ """
+ @param pkg: cpv for an installed package
+ @type pkg: string
+ @param paths: paths of files to remove from contents
+ @type paths: iterable
+ """
+ if not hasattr(pkg, "getcontents"):
+ pkg = self._dblink(pkg)
+ root = self.root
+ root_len = len(root) - 1
+ new_contents = pkg.getcontents().copy()
+ contents_key = None
+
+ for filename in paths:
+ filename = normalize_path(filename)
+ if relative_paths:
+ relative_filename = filename
+ else:
+ relative_filename = filename[root_len:]
+ contents_key = pkg._match_contents(relative_filename, root)
+ if contents_key:
+ del new_contents[contents_key]
+
+ if contents_key:
+ f = atomic_ofstream(os.path.join(pkg.dbdir, "CONTENTS"))
+ write_contents(new_contents, root, f)
+ f.close()
+
class _owners_cache(object):
"""
This class maintains an hash table that serves to index package
@@ -1922,7 +1951,7 @@ class dblink(object):
#remove self from vartree database so that our own virtual gets zapped if we're the last node
self.vartree.zap(self.mycpv)
- def isowner(self,filename, destroot):
+ def isowner(self, filename, destroot):
"""
Check if a file belongs to this package. This may
result in a stat call for the parent directory of
@@ -1941,12 +1970,25 @@ class dblink(object):
1. True if this package owns the file.
2. False if this package does not own the file.
"""
+ return bool(self._match_contents(filename, destroot))
+
+ def _match_contents(self, filename, destroot):
+ """
+ The matching contents entry is returned, which is useful
+ since the path may differ from the one given by the caller,
+ due to symlinks.
+
+ @rtype: String
+ @return: the contents entry corresponding to the given path, or False
+ if the file is not owned by this package.
+ """
+
destfile = normalize_path(
os.path.join(destroot, filename.lstrip(os.path.sep)))
pkgfiles = self.getcontents()
if pkgfiles and destfile in pkgfiles:
- return True
+ return destfile
if pkgfiles:
basename = os.path.basename(destfile)
if self._contents_basenames is None:
@@ -1996,7 +2038,7 @@ class dblink(object):
for p_path in p_path_list:
x = os.path.join(p_path, basename)
if x in pkgfiles:
- return True
+ return x
return False
@@ -2661,33 +2703,8 @@ class dblink(object):
contents = self.getcontents()
destroot_len = len(destroot) - 1
for blocker in blockers:
- blocker_contents = blocker.getcontents()
- collisions = []
- for filename in blocker_contents:
- relative_filename = filename[destroot_len:]
- if self.isowner(relative_filename, destroot):
- collisions.append(filename)
- if not collisions:
- continue
- for filename in collisions:
- del blocker_contents[filename]
- f = atomic_ofstream(os.path.join(blocker.dbdir, "CONTENTS"))
- for filename in sorted(blocker_contents):
- entry_data = blocker_contents[filename]
- entry_type = entry_data[0]
- relative_filename = filename[destroot_len:]
- if entry_type == "obj":
- entry_type, mtime, md5sum = entry_data
- line = "%s %s %s %s\n" % \
- (entry_type, relative_filename, md5sum, mtime)
- elif entry_type == "sym":
- entry_type, mtime, link = entry_data
- line = "%s %s -> %s %s\n" % \
- (entry_type, relative_filename, link, mtime)
- else: # dir, dev, fif
- line = "%s %s\n" % (entry_type, relative_filename)
- f.write(line)
- f.close()
+ self.vartree.dbapi.removeFromContents(blocker, iter(contents),
+ relative_paths=False)
self.vartree.dbapi._add(self)
contents = self.getcontents()
@@ -3098,6 +3115,27 @@ class dblink(object):
"Is this a regular package (does it have a CATEGORY file? A dblink can be virtual *and* regular)"
return os.path.exists(os.path.join(self.dbdir, "CATEGORY"))
+def write_contents(contents, root, f):
+ """
+ Write contents to any file like object. The file will be left open.
+ """
+ root_len = len(root) - 1
+ for filename in sorted(contents):
+ entry_data = contents[filename]
+ entry_type = entry_data[0]
+ relative_filename = filename[root_len:]
+ if entry_type == "obj":
+ entry_type, mtime, md5sum = entry_data
+ line = "%s %s %s %s\n" % \
+ (entry_type, relative_filename, md5sum, mtime)
+ elif entry_type == "sym":
+ entry_type, mtime, link = entry_data
+ line = "%s %s -> %s %s\n" % \
+ (entry_type, relative_filename, link, mtime)
+ else: # dir, dev, fif
+ line = "%s %s\n" % (entry_type, relative_filename)
+ f.write(line)
+
def tar_contents(contents, root, tar, protect=None, onProgress=None):
from portage.util import normalize_path
import tarfile