Add cr_repomd_sort_records() function.
authorTomas Mlcoch <tmlcoch@redhat.com>
Mon, 14 Oct 2013 14:54:43 +0000 (16:54 +0200)
committerTomas Mlcoch <tmlcoch@redhat.com>
Mon, 14 Oct 2013 14:54:43 +0000 (16:54 +0200)
deltarepo/deltarepo/applicator.py
deltarepo/deltarepo/generator.py
src/createrepo_c.c
src/python/repomd-py.c
src/repomd.c
src/repomd.h

index 110bbf1..a5bfa6e 100644 (file)
@@ -282,6 +282,7 @@ class DeltaRepoApplicator(LoggingInterface):
         # Prepare and write out the new repomd.xml
         self._debug("Preparing repomd.xml ...")
         self.new_repomd.set_repoid(self.new_id, self.repoid_type_str)
+        self.new_repomd.sort_records()
         new_repomd_xml = self.new_repomd.xml_dump()
 
         self._debug("Writing repomd.xml ...")
index d89d924..d69e69d 100644 (file)
@@ -295,6 +295,7 @@ class DeltaRepoGenerator(LoggingInterface):
         deltarepoid = "{0}-{1}".format(self.bundle["old_repoid"],
                                        self.bundle["new_repoid"])
         self.delta_repomd.set_repoid(deltarepoid, self.repoid_type_str)
+        self.delta_repomd.sort_records()
         delta_repomd_xml = self.delta_repomd.xml_dump()
 
         self._debug("Writing repomd.xml ...")
index 497d7af..9f52838 100644 (file)
@@ -1391,6 +1391,8 @@ main(int argc, char **argv)
     if (cmd_options->revision)
         cr_repomd_set_revision(repomd_obj, cmd_options->revision);
 
+    cr_repomd_sort_records(repomd_obj);
+
     char *repomd_xml = cr_xml_dump_repomd(repomd_obj, &tmp_err);
     assert(repomd_xml || tmp_err);
     cr_repomd_free(repomd_obj);
index 3bdd79d..25b8a1c 100644 (file)
@@ -213,6 +213,18 @@ add_content_tag(_RepomdObject *self, PyObject *args)
     Py_RETURN_NONE;
 }
 
+PyDoc_STRVAR(sort_records__doc__,
+"sort_records() -> str\n\n"
+"Sort repomd records to the createrepo_c prefered order");
+
+static PyObject *
+sort_records(_RepomdObject *self, void *nothing)
+{
+    CR_UNUSED(nothing);
+    cr_repomd_sort_records(self->repomd);
+    Py_RETURN_NONE;
+}
+
 PyDoc_STRVAR(xml_dump__doc__,
 "xml_dump() -> str\n\n"
 "Generate xml representation of the repomd");
@@ -246,6 +258,8 @@ static struct PyMethodDef repomd_methods[] = {
         add_repo_tag__doc__},
     {"add_content_tag", (PyCFunction)add_content_tag, METH_VARARGS,
         add_content_tag__doc__},
+    {"sort_records", (PyCFunction)sort_records, METH_NOARGS,
+        sort_records__doc__},
     {"xml_dump", (PyCFunction)xml_dump, METH_NOARGS,
         xml_dump__doc__},
     {NULL} /* sentinel */
index 63ef93d..1f3b98e 100644 (file)
@@ -704,3 +704,54 @@ cr_repomd_get_record(cr_Repomd *repomd, const char *type)
     }
     return NULL;
 }
+
+static gint
+record_type_value(const char *type) {
+    if (!g_strcmp0(type, "primary"))
+        return 1;
+    if (!g_strcmp0(type, "filelists"))
+        return 2;
+    if (!g_strcmp0(type, "other"))
+        return 3;
+    if (!g_strcmp0(type, "primary_db"))
+        return 4;
+    if (!g_strcmp0(type, "filelists_db"))
+        return 5;
+    if (!g_strcmp0(type, "other_db"))
+        return 6;
+    return 7;
+}
+
+static gint
+record_cmp(gconstpointer _a, gconstpointer _b)
+{
+    const cr_RepomdRecord *a = _a;
+    const cr_RepomdRecord *b = _b;
+
+    gint a_val = record_type_value(a->type);
+    gint b_val = record_type_value(b->type);
+
+    // Keep base metadata files sorted by logical order (primary, filelists, ..)
+    if (a_val < b_val) return -1;
+    if (a_val > b_val) return 1;
+
+    // Other metadta sort by the type
+    gint ret = g_strcmp0(a->type, b->type);
+    if (ret)
+        return ret;
+
+    // If even the type is not sufficient, use location href
+    ret = g_strcmp0(a->location_href, b->location_href);
+
+    // If even the location href is not sufficient, use the location base
+    return ret ? ret : g_strcmp0(a->location_base, b->location_base);
+}
+
+void
+cr_repomd_sort_records(cr_Repomd *repomd)
+{
+    if (!repomd)
+        return;
+
+    repomd->records = g_slist_sort(repomd->records, record_cmp);
+}
index 2b056c7..442a679 100644 (file)
@@ -238,6 +238,13 @@ cr_RepomdRecord *cr_repomd_get_record(cr_Repomd *repomd, const char *type);
  */
 void cr_repomd_detach_record(cr_Repomd *repomd, cr_RepomdRecord *rec);
 
+/** Records are stored in order they were added to the repomd.
+ * Because sometimes deterministic output is desirable this function
+ * exists.
+ * @param repomd                cr_Repomd object
+ */
+void cr_repomd_sort_records(cr_Repomd *repomd);
+
 /** Frees cr_Repomd object and all its cr_RepomdRecord objects
  * @param repomd                cr_Repomd object
  */