createrepo/deltarpms.py createrepo/__init__.py

[email protected]
Newsgroups gmane.linux.rpm.metadata
Message-ID <[email protected]>
 createrepo/__init__.py  |  130 ++++++++++++++++++++++++------------------------
 createrepo/deltarpms.py |   14 +++--
 2 files changed, 76 insertions(+), 68 deletions(-)

New commits:
commit f5a630e337f4790735525db50aa543d2fb7c1998
Author: Seth Vidal <[email protected]>
Date:   Mon Feb 9 18:20:53 2009 -0500

    when we process the rpms only do the drpm creation.
    after we're done take the drpms and generate the metadata from there

diff --git a/createrepo/__init__.py b/createrepo/__init__.py
index 970ccb2..dcf08b1 100644
--- a/createrepo/__init__.py
+++ b/createrepo/__init__.py
@@ -498,9 +498,7 @@ class MetaDataGenerator:
                         self.callback.errorlog("\nError %s: %s\n" % (pkg, e))
                         continue
                     # we can use deltas:
-                    presto_md = self._do_delta_rpm_package(po)
-                    if presto_md:
-                        self.deltafile.write(presto_md)
+                    self._do_delta_rpm_package(po)
 
                 else:
                     po = pkg
@@ -578,6 +576,7 @@ class MetaDataGenerator:
         if self.conf.deltas:
             if not self.conf.quiet:
                 self.callback.log(_('Saving delta metadata'))
+            self.deltafile.write(self.generate_delta_xml())
             self.deltafile.write('\n</prestodelta>')
             self.deltafile.close()
 
@@ -586,76 +585,81 @@ class MetaDataGenerator:
            returns the presto/delta xml metadata as a string
         """
 
-        results = u""
-        thisdeltastart = u"""  <newpackage name="%s" epoch="%s" version="%s" release="%s" arch="%s">\n""" % (pkg.name,
-                                     pkg.epoch, pkg.ver, pkg.release, pkg.arch)
-        thisdeltaend = u"""  </newpackage>\n"""
-
         # generate a list of all the potential 'old rpms'
-        opl = self._get_old_package_list()
-        # get list of potential candidates which are likely to match
-        pot_cand = []
-        for fn in opl:
-            if os.path.basename(fn).startswith(pkg.name):
-                pot_cand.append(fn)
+        opd = self._get_old_package_dict() # yes I could make this a property but <shrug>
         
-        candidates = []
-        for fn in pot_cand:
-            try:
-                thispo = yumbased.CreateRepoPackage(self.ts, fn)
-            except Errors.MiscError, e:
-                continue
-            if (thispo.name, thispo.arch) != (pkg.name, pkg.arch):
-                # not the same, doesn't matter
-                continue
-            if thispo == pkg: #exactly the same, doesn't matter
-                continue
-            if thispo.EVR >= pkg.EVR: # greater or equal, doesn't matter
-                continue
-            candidates.append(thispo)
-            candidates.sort()
-            candidates.reverse()
-
-        drpm_results = u""
-        for delta_p in candidates[0:self.conf.num_deltas]:
-            #make drpm of pkg and delta_p
-            drpmfn = deltarpms.create_drpm(delta_p, pkg, self.conf.deltadir)
-
-            if drpmfn:
-                # TODO more sanity check the drpm for size, etc
-                # make xml of drpm
+        # for each of our old_package_paths - make a drpm from the newest of that pkg
+        # get list of potential candidates which are likely to match
+        for d in self.conf.oldpackage_paths:
+            pot_cand = []
+            for fn in opd[d]:
+                if os.path.basename(fn).startswith(pkg.name):
+                    pot_cand.append(fn)
+            
+            candidates = []
+            for fn in pot_cand:
                 try:
-                    drpm_po = yumbased.CreateRepoPackage(self.ts, drpmfn)
+                    thispo = yumbased.CreateRepoPackage(self.ts, fn)
                 except Errors.MiscError, e:
-                    os.unlink(drpmfn)
                     continue
-                rel_drpmfn = drpmfn.replace(self.conf.outputdir, '')
-                if rel_drpmfn[0] == '/':
-                    rel_drpmfn = rel_drpmfn[1:]
-                if not self.conf.quiet:
-                    if self.conf.verbose:
-                        self.callback.log('created drpm from %s to %s: %s' % (
-                            delta_p, pkg, drpmfn))
-
-                drpm = deltarpms.DeltaRPMPackage(drpm_po, self.conf.outputdir, rel_drpmfn)
-                drpm_results += to_unicode(drpm.xml_dump_metadata())
-        
-        if drpm_results:
-            results = thisdeltastart + drpm_results + thisdeltaend
-        
-        return results
-
-    def _get_old_package_list(self):
-        if hasattr(self, '_old_package_list'):
-            return self._old_package_list
+                if (thispo.name, thispo.arch) != (pkg.name, pkg.arch):
+                    # not the same, doesn't matter
+                    continue
+                if thispo == pkg: #exactly the same, doesn't matter
+                    continue
+                if thispo.EVR >= pkg.EVR: # greater or equal, doesn't matter
+                    continue
+                candidates.append(thispo)
+                candidates.sort()
+                candidates.reverse()
+
+            for delta_p in candidates[0:self.conf.num_deltas]:
+                #make drpm of pkg and delta_p
+                drpmfn = deltarpms.create_drpm(delta_p, pkg, self.conf.deltadir)
+                self.callback.log('created drpm from %s to %s: %s' % (
+                        delta_p, pkg, drpmfn))
+
+    def _get_old_package_dict(self):
+        if hasattr(self, '_old_package_dict'):
+            return self._old_package_dict
         
+        self._old_package_dict = {}
         opl = []
         for d in self.conf.oldpackage_paths:
             for f in self.getFileList(d, 'rpm'):
-                opl.append(d + '/' + f)
+                if not self._old_package_dict.has_key(d):
+                    self._old_package_dict[d] = []
+                self._old_package_dict[d].append(d + '/' + f)
                     
-        self._old_package_list = opl
-        return self._old_package_list
+        return self._old_package_dict
+
+    def generate_delta_xml(self):
+        """take the delta rpm output dir, process all the drpm files
+           produce the text output for the presto/delta xml metadata"""
+        # go through the drpm dir
+        # for each file -store the drpm info in a dict based on its target. Just
+        # appending the output. for each of the keys in the dict, return
+        # the tag for the target + each of the drpm infos + closure for the target
+        # tag
+        targets = {}
+        result = u''
+        for drpm_fn in self.getFileList(self.conf.deltadir, 'drpm'):
+            drpm_rel_fn = os.path.normpath(self.conf.delta_relative + '/' + drpm_fn) # this is annoying
+            drpm_po = yumbased.CreateRepoPackage(self.ts, self.conf.deltadir + '/' + drpm_fn)
+            
+            drpm = deltarpms.DeltaRPMPackage(drpm_po, self.conf.outputdir, drpm_rel_fn)
+            if not targets.has_key(drpm_po.pkgtup):
+                targets[drpm_po.pkgtup] = u''
+            targets[drpm_po.pkgtup] += drpm.xml_dump_metadata()
+        
+        for (n,e,v,r,a) in targets.keys():
+            result += """  <newpackage name="%s" epoch="%s" version="%s" release="%s" arch="%s"\n""" % (
+                    n,e,v,r,a)
+            for src in targets[(n,e,v,r,a)]:
+                result += src
+            result += """   </newpackage>\n"""
+
+        return result
 
     def addArbitraryMetadata(self, mdfile, mdtype, xml_node, compress=True, 
                                              compress_type='gzip', attribs={}):
diff --git a/createrepo/deltarpms.py b/createrepo/deltarpms.py
index 4b4acaf..f201ab7 100644
--- a/createrepo/deltarpms.py
+++ b/createrepo/deltarpms.py
@@ -19,6 +19,8 @@ import os.path
 import commands
 from yum import misc
 import gzip
+import yumbased
+from utils import _, errorprint, MDError
 
 class DeltaRPMPackage:
     """each drpm is one object, you pass it a drpm file
@@ -27,17 +29,17 @@ class DeltaRPMPackage:
 
     mode_cache = {}
 
-    def __init__(self, pkgobj, basedir, filename):
+    def __init__(self, po, basedir, filename):
         try:
             stats = os.stat(os.path.join(basedir, filename))
             self.size = stats[6]
             self.mtime = stats[8]
             del stats
         except OSError, e:
-            raise MDError, "Error Stat'ing file %s %s" % (basedir, filename)
+            raise MDError, "Error Stat'ing file %s%s" % (basedir, filename)
         self.csum_type = 'sha256'
         self.relativepath = filename
-        self.po  = pkgobj
+        self.po  = po
 
         fd = os.open(self.po.localpath, os.O_RDONLY)
         os.lseek(fd, 0, 0)
@@ -110,8 +112,7 @@ class DeltaRPMPackage:
         (oldname, oldepoch, oldver, oldrel) = self.oldnevr
         sequence = "%s-%s" % (self.oldnevrstring, self.sequence)
 
-        delta_tag = """
-    <delta oldepoch="%s" oldversion="%s" oldrelease="%s">
+        delta_tag = """    <delta oldepoch="%s" oldversion="%s" oldrelease="%s">
       <filename>%s</filename>
       <sequence>%s</sequence>
       <size>%s</size>
@@ -138,3 +139,6 @@ def create_drpm(old_pkg, new_pkg, destdir):
             return None
     
     return delta_rpm_path
+
+
+
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.