Add diff function to compute the difference between two package sets.
authorKristian Høgsberg <krh@redhat.com>
Fri, 5 Oct 2007 20:26:27 +0000 (16:26 -0400)
committerKristian Høgsberg <krh@redhat.com>
Fri, 5 Oct 2007 20:26:27 +0000 (16:26 -0400)
main.c
razor.c
razor.h

diff --git a/main.c b/main.c
index 87c3a54..67242ba 100644 (file)
--- a/main.c
+++ b/main.c
@@ -7,7 +7,8 @@
 #include "razor.h"
 
 static const char *repo_filename = "system.repo";
-static const char rawhide_repo_filename[] = "rawhide.repo";
+static const char *rawhide_repo_filename = "rawhide.repo";
+static const char *updated_repo_filename = "system-updated.repo";
 
 static int
 command_list(int argc, const char *argv[])
@@ -123,7 +124,7 @@ command_update(int argc, const char *argv[])
        if (set == NULL || upstream == NULL)
                return 1;
        set = razor_set_update(set, upstream, argc - 2, argv + 2);
-       razor_set_write(set, "system-updated.repo");
+       razor_set_write(set, updated_repo_filename);
        razor_set_destroy(set);
        razor_set_destroy(upstream);
        printf("wrote system-updated.repo\n");
@@ -131,6 +132,34 @@ command_update(int argc, const char *argv[])
        return 0;
 }
 
+static void
+print_diff(const char *name,
+          const char *old_version, const char *new_version, void *data)
+{
+       if (old_version)
+               printf("removing %s %s\n", name, old_version);
+       else
+               printf("install %s %s\n", name, new_version);
+}
+
+static int
+command_diff(int argc, const char *argv[])
+{
+       struct razor_set *set, *updated;
+
+       set = razor_set_open(repo_filename);
+       updated = razor_set_open(updated_repo_filename);
+       if (set == NULL || updated == NULL)
+               return 1;
+
+       razor_set_diff(set, updated, print_diff, NULL); 
+
+       razor_set_destroy(set);
+       razor_set_destroy(updated);
+
+       return 0;
+}
+
 static struct {
        const char *name;
        const char *description;
@@ -144,7 +173,8 @@ static struct {
        { "import-yum", "import yum filelist.xml on stdin", command_import_yum },
        { "import-rpmdb", "import the system rpm database", command_import_rpmdb },
        { "validate", "validate a package set", command_validate },
-       { "update", "update all or specified packages", command_update }
+       { "update", "update all or specified packages", command_update },
+       { "diff", "show diff between two package sets", command_diff }
 };
 
 static int
diff --git a/razor.c b/razor.c
index 9154b88..99ccb2a 100644 (file)
--- a/razor.c
+++ b/razor.c
@@ -1385,3 +1385,48 @@ razor_set_update(struct razor_set *set, struct razor_set *upstream,
        return set;
 }
 
+/* The diff order matters.  We should sort the packages so that a
+ * REMOVE of a package comes before the INSTALL, and so that all
+ * requires for a package have been installed before the package.
+ **/
+
+void
+razor_set_diff(struct razor_set *set, struct razor_set *upstream,
+              razor_package_callback_t callback, void *data)
+{
+       struct razor_package *p, *pend, *u, *uend;
+       char *ppool, *upool;
+       int res = 0;
+
+       p = set->packages.data;
+       pend = set->packages.data + set->packages.size;
+       ppool = set->string_pool.data;
+
+       u = upstream->packages.data;
+       uend = upstream->packages.data + upstream->packages.size;
+       upool = upstream->string_pool.data;
+
+       while (p < pend || u < uend) {
+               if (p < pend && u < uend) {
+                       res = strcmp(&ppool[p->name], &upool[u->name]);
+                       if (res == 0)
+                               res = versioncmp(&ppool[p->version],
+                                                &upool[u->version]);
+               }
+
+               if (u == uend || res < 0) {
+                       callback(&ppool[p->name], &ppool[p->version],
+                                NULL, data);
+                       p++;
+                       continue;
+               } else if (p == pend || res > 0) {
+                       callback(&upool[u->name], NULL, &upool[u->version],
+                                data);
+                       u++;
+                       continue;
+               } else {
+                       p++;
+                       u++;
+               }
+       }
+}
diff --git a/razor.h b/razor.h
index f295532..3b0b6ef 100644 (file)
--- a/razor.h
+++ b/razor.h
@@ -24,6 +24,18 @@ struct razor_set *razor_set_update(struct razor_set *set,
                                   struct razor_set *upstream,
                                   int count, const char **packages);
 
+typedef void (*razor_package_callback_t)(const char *name,
+                                        const char *old_version,
+                                        const char *new_version,
+                                        void *data);
+void
+razor_set_diff(struct razor_set *set, struct razor_set *upstream,
+              razor_package_callback_t callback, void *data);
+
+
+/* Importer interface; for building a razor set from external sources,
+ * like yum, rpmdb or razor package files. */
+
 struct razor_importer;
 
 struct razor_importer *razor_importer_new(void);