Patch: weak dependencies for createrepo

Michael Schroeder <[email protected]> Tue, 25 Feb 2014 14:36:54 +0100
Newsgroups gmane.linux.rpm.metadata
Message-ID <[email protected]>
--J2SCkAp4GZ/dPZZf
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline


Hi repomd folks,

attached is what I currently use to have createrepo emit weak dependencies.
Things are a bit complicated because I still need to support the old
tags, feel free to remove that part if you don't like it.

yum-metadata-parser-1.1.2-weakdeps.patch:
    'createrepo --update' needs to parse the old metadata, and since
    some time it uses the yum-metadata-parser (aka sqlitecache) package
    to do the job. Thus we need to support weak dependencies here as well.

yum-3.4.3-suse-missing-tags.patch:
    adds support for the new tags. The old tags are not exported, so
    I had to use the numeric values here.

Feel free to beatify my code ;)

Cheers,
  Michael.

-- 
Michael Schroeder                                   [email protected]
SUSE LINUX Products GmbH,  GF Jeff Hawn, HRB 16746 AG Nuernberg
main(_){while(_=~getchar())putchar(~_-1/(~(_|32)/13*2-11)*13);}

--J2SCkAp4GZ/dPZZf
Content-Type: text/x-patch; charset=us-ascii
Content-Disposition: attachment; filename="yum-metadata-parser-1.1.2-weakdeps.patch"

--- ./db.c.orig	2014-02-24 16:09:28.394182339 +0000
+++ ./db.c	2014-02-24 16:10:48.672182197 +0000
@@ -398,7 +398,8 @@ yum_db_create_primary_tables (sqlite3 *d
         "  release TEXT,"
         "  pkgKey INTEGER %s)";
 
-    const char *deps[] = { "requires", "provides", "conflicts", "obsoletes", NULL };
+    const char *deps[] = { "requires", "provides", "conflicts", "obsoletes",
+			   "suggests", "enhances", "recommends", "supplements", NULL };
     int i;
 
     const char *pkgindexsql = "CREATE INDEX pkg%s on %s (pkgKey)";
@@ -456,6 +457,10 @@ yum_db_create_primary_tables (sqlite3 *d
         "    DELETE FROM provides WHERE pkgKey = old.pkgKey;"
         "    DELETE FROM conflicts WHERE pkgKey = old.pkgKey;"
         "    DELETE FROM obsoletes WHERE pkgKey = old.pkgKey;"
+        "    DELETE FROM suggests WHERE pkgKey = old.pkgKey;"
+        "    DELETE FROM enhances WHERE pkgKey = old.pkgKey;"
+        "    DELETE FROM recommends WHERE pkgKey = old.pkgKey;"
+        "    DELETE FROM supplements WHERE pkgKey = old.pkgKey;"
         "  END;";
 
     rc = sqlite3_exec (db, sql, NULL, NULL, NULL);
--- ./package.c.orig	2014-02-24 16:09:40.514182318 +0000
+++ ./package.c	2014-02-24 16:13:25.480181919 +0000
@@ -85,6 +85,26 @@ package_free (Package *package)
         g_slist_free (package->obsoletes);
     }
 
+    if (package->suggests) {
+        g_slist_foreach (package->suggests, (GFunc) g_free, NULL);
+        g_slist_free (package->suggests);
+    }
+
+    if (package->enhances) {
+        g_slist_foreach (package->enhances, (GFunc) g_free, NULL);
+        g_slist_free (package->enhances);
+    }
+
+    if (package->recommends) {
+        g_slist_foreach (package->recommends, (GFunc) g_free, NULL);
+        g_slist_free (package->recommends);
+    }
+
+    if (package->supplements) {
+        g_slist_foreach (package->supplements, (GFunc) g_free, NULL);
+        g_slist_free (package->supplements);
+    }
+
     if (package->files) {
         g_slist_foreach (package->files, (GFunc) g_free, NULL);
         g_slist_free (package->files);
--- ./package.h.orig	2014-02-24 16:09:34.890182327 +0000
+++ ./package.h	2014-02-24 16:11:09.288182160 +0000
@@ -72,6 +72,10 @@ typedef struct {
     GSList *provides;
     GSList *conflicts;
     GSList *obsoletes;
+    GSList *suggests;
+    GSList *enhances;
+    GSList *recommends;
+    GSList *supplements;
 
     GSList *files;
     GSList *changelogs;
--- ./sqlitecache.c.orig	2014-02-24 16:09:57.235182288 +0000
+++ ./sqlitecache.c	2014-02-24 16:17:07.753181526 +0000
@@ -152,6 +152,10 @@ typedef struct {
     sqlite3_stmt *provides_handle;
     sqlite3_stmt *conflicts_handle;
     sqlite3_stmt *obsoletes_handle;
+    sqlite3_stmt *suggests_handle;
+    sqlite3_stmt *enhances_handle;
+    sqlite3_stmt *recommends_handle;
+    sqlite3_stmt *supplements_handle;
     sqlite3_stmt *files_handle;
 } PackageWriterInfo;
 
@@ -175,6 +179,18 @@ package_writer_info_init (UpdateInfo *up
     info->obsoletes_handle = yum_db_dependency_prepare (db, "obsoletes", err);
     if (*err)
         return;
+    info->suggests_handle = yum_db_dependency_prepare (db, "suggests", err);
+    if (*err)
+        return;
+    info->enhances_handle = yum_db_dependency_prepare (db, "enhances", err);
+    if (*err)
+        return;
+    info->recommends_handle = yum_db_dependency_prepare (db, "recommends", err);
+    if (*err)
+        return;
+    info->supplements_handle = yum_db_dependency_prepare (db, "supplements", err);
+    if (*err)
+        return;
     info->files_handle = yum_db_file_prepare (db, err);
 }
 
@@ -226,6 +242,14 @@ write_package_to_db (UpdateInfo *update_
                 package->pkgKey, package->conflicts);
     write_deps (update_info->db, info->obsoletes_handle,
                 package->pkgKey, package->obsoletes);
+    write_deps (update_info->db, info->suggests_handle,
+                package->pkgKey, package->suggests);
+    write_deps (update_info->db, info->enhances_handle,
+                package->pkgKey, package->enhances);
+    write_deps (update_info->db, info->recommends_handle,
+                package->pkgKey, package->recommends);
+    write_deps (update_info->db, info->supplements_handle,
+                package->pkgKey, package->supplements);
 
     write_files (update_info->db, info->files_handle, package);
 }
@@ -245,6 +269,14 @@ package_writer_info_clean (UpdateInfo *u
         sqlite3_finalize (info->conflicts_handle);
     if (info->obsoletes_handle)
         sqlite3_finalize (info->obsoletes_handle);
+    if (info->suggests_handle)
+        sqlite3_finalize (info->suggests_handle);
+    if (info->enhances_handle)
+        sqlite3_finalize (info->enhances_handle);
+    if (info->recommends_handle)
+        sqlite3_finalize (info->recommends_handle);
+    if (info->supplements_handle)
+        sqlite3_finalize (info->supplements_handle);
     if (info->files_handle)
         sqlite3_finalize (info->files_handle);
 }
--- ./xml-parser.c.orig	2014-02-24 16:09:48.186182304 +0000
+++ ./xml-parser.c	2014-02-24 16:12:19.537182036 +0000
@@ -244,6 +244,18 @@ primary_parser_format_start (PrimarySAXC
     } else if (!strcmp (name, "rpm:conflicts")) {
         ctx->state = PRIMARY_PARSER_DEP;
         ctx->current_dep_list = &sctx->current_package->conflicts;
+    } else if (!strcmp (name, "rpm:suggests")) {
+        ctx->state = PRIMARY_PARSER_DEP;
+        ctx->current_dep_list = &sctx->current_package->suggests;
+    } else if (!strcmp (name, "rpm:enhances")) {
+        ctx->state = PRIMARY_PARSER_DEP;
+        ctx->current_dep_list = &sctx->current_package->enhances;
+    } else if (!strcmp (name, "rpm:recommends")) {
+        ctx->state = PRIMARY_PARSER_DEP;
+        ctx->current_dep_list = &sctx->current_package->recommends;
+    } else if (!strcmp (name, "rpm:supplements")) {
+        ctx->state = PRIMARY_PARSER_DEP;
+        ctx->current_dep_list = &sctx->current_package->supplements;
     }
 
     else if (!strcmp (name, "file")) {

--J2SCkAp4GZ/dPZZf
Content-Type: text/x-patch; charset=us-ascii
Content-Disposition: attachment; filename="yum-3.4.3-suse-missing-tags.patch"

--- ./yum/mdparser.py.orig	2014-02-25 11:04:36.905061790 +0000
+++ ./yum/mdparser.py	2014-02-25 11:04:45.009061775 +0000
@@ -155,7 +155,8 @@ class PrimaryEntry(BaseEntry):
                 p[name] = child.text
 
             elif name in ('provides', 'requires', 'conflicts', 
-                          'obsoletes'):
+                          'obsoletes',
+                          'suggests', 'enhances', 'recommends', 'supplements'):
                 self.prco[name] = self.getPrco(child)
 
             elif name == 'header-range':
--- ./yum/packages.py.orig	2014-02-25 11:04:36.910061790 +0000
+++ ./yum/packages.py	2014-02-25 12:31:03.379052610 +0000
@@ -54,6 +54,14 @@ except ImportError:
 import pwd
 import grp
 
+# check if rpm has the new weakdeps tags
+_new_weakdeps = False
+try:
+    if rpm.RPMTAG_ENHANCENAME:
+        _new_weakdeps = True
+except:
+    pass
+
 def comparePoEVR(po1, po2):
     """
     Compare two Package or PackageEVR objects.
@@ -412,6 +420,10 @@ class RpmBase(object):
         self.prco['conflicts'] = [] # (name, flag, (e,v,r))
         self.prco['requires'] = [] # (name, flag, (e,v,r))
         self.prco['provides'] = [] # (name, flag, (e,v,r))
+        self.prco['suggests'] = [] # (name, flag, (e,v,r))
+        self.prco['enhances'] = [] # (name, flag, (e,v,r))
+        self.prco['recommends'] = [] # (name, flag, (e,v,r))
+        self.prco['supplements'] = [] # (name, flag, (e,v,r))
         self.files = {}
         self.files['file'] = []
         self.files['dir'] = []
@@ -615,6 +627,10 @@ class RpmBase(object):
     provides = property(fget=lambda self: self.returnPrco('provides'))
     obsoletes = property(fget=lambda self: self.returnPrco('obsoletes'))
     conflicts = property(fget=lambda self: self.returnPrco('conflicts'))
+    suggests = property(fget=lambda self: self.returnPrco('suggests'))
+    enhances = property(fget=lambda self: self.returnPrco('enhances'))
+    recommends = property(fget=lambda self: self.returnPrco('recommends'))
+    supplements = property(fget=lambda self: self.returnPrco('supplements'))
     provides_names = property(fget=lambda self: self.returnPrcoNames('provides'))
     requires_names = property(fget=lambda self: self.returnPrcoNames('requires'))
     conflicts_names = property(fget=lambda self: self.returnPrcoNames('conflicts'))
@@ -1122,6 +1138,10 @@ class YumAvailablePackage(PackageObject,
         msg += self._dump_requires()
         msg += self._dump_pco('conflicts')         
         msg += self._dump_pco('obsoletes')         
+        msg += self._dump_pco('suggests')
+        msg += self._dump_pco('enhances')
+        msg += self._dump_pco('recommends')
+        msg += self._dump_pco('supplements')
         msg += self._dump_files(True)
         if msg[-1] != '\n':
             msg += """\n"""
@@ -1358,6 +1378,17 @@ class YumHeaderPackage(YumAvailablePacka
     def _get_hdr(self):
         return self.hdr
 
+    def _filter_deps(self, name, flag, vers, andmask, resmask):
+        newname = []
+        newflag = []
+        newvers = []
+        for (n, f, v) in zip(name, flag, vers):
+            if f & andmask == resmask:
+                newname.append(n)
+                newflag.append(f)
+                newvers.append(v)
+        return (newname, newflag, newvers)
+
     def _populatePrco(self):
         "Populate the package object with the needed PRCO interface."
 
@@ -1383,6 +1414,33 @@ class YumHeaderPackage(YumAvailablePacka
 
             prcotype = tag2prco[tag]
             self.prco[prcotype] = map(misc.share_data, zip(name,flag,vers))
+
+        tag2prco = { "SUGGEST":    ( misc.share_data("suggests"),    1156, 1157, 1158, 1 << 27, 0),
+                     "ENHANCE":    ( misc.share_data("enhances"),    1159, 1160, 1161, 1 << 27, 0),
+                     "RECOMMEND":  ( misc.share_data("recommends"),  1156, 1157, 1158, 1 << 27, 1 << 27),
+                     "SUPPLEMENT": ( misc.share_data("supplements"), 1159, 1160, 1161, 1 << 27, 1 << 27) }
+        for tag in tag2prco:
+            (prcotype, oldtagn, oldtagv, oldtagf, andmask, resmask) = tag2prco[tag]
+            name = None
+            if _new_weakdeps:
+                name = hdr[getattr(rpm, 'RPMTAG_%sNAME' % tag)]
+            if not name:
+                name = hdr[oldtagn]
+                if not name:
+                    continue
+                (name, flag, vers) = self._filter_deps(name, hdr[oldtagf], hdr[oldtagv], andmask, resmask)
+            else:
+                flag = hdr[getattr(rpm, 'RPMTAG_%sFLAGS' % tag)]
+                vers = hdr[getattr(rpm, 'RPMTAG_%sVERSION' % tag)]
+            name = map(misc.share_data, name)
+            if not name: # empty or none or whatever, doesn't matter
+                continue
+            flag = map(rpmUtils.miscutils.flagToString, flag)
+            flag = map(misc.share_data, flag)
+            vers = map(rpmUtils.miscutils.stringToVersion, vers)
+            vers = map(lambda x: (misc.share_data(x[0]), misc.share_data(x[1]),
+                                  misc.share_data(x[2])), vers)
+            self.prco[prcotype] = map(misc.share_data, zip(name,flag,vers))
     
     def tagByName(self, tag):
         warnings.warn("tagByName() will go away in a furture version of Yum.\n",
--- ./yum/sqlitesack.py.orig	2014-02-25 11:04:36.922061790 +0000
+++ ./yum/sqlitesack.py	2014-02-25 12:22:10.025053554 +0000
@@ -179,7 +179,11 @@ class YumAvailablePackageSqlite(YumAvail
         self.prco = { 'obsoletes': (),
                       'conflicts': (),
                       'requires': (),
-                      'provides': () }
+                      'provides': (),
+                      'suggests': (),
+                      'enhances': (),
+                      'recommends': (),
+                      'supplements': () }
         self.sack = repo.sack
         self.repoid = repo.id
         self.repo = repo

--J2SCkAp4GZ/dPZZf
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Rpm-metadata mailing list
[email protected]
http://lists.baseurl.org/mailman/listinfo/rpm-metadata

--J2SCkAp4GZ/dPZZf--