# 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 ...")
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 ...")
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);
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");
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 */
}
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);
+}
*/
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
*/