1.1 --- a/main.c Wed Feb 20 16:54:03 2008 -0500
1.2 +++ b/main.c Thu Feb 21 12:09:13 2008 -0500
1.3 @@ -339,6 +339,22 @@
1.4 return 0;
1.5 }
1.6
1.7 +static int
1.8 +command_remove(int argc, const char *argv[])
1.9 +{
1.10 + struct razor_set *set;
1.11 +
1.12 + set = razor_set_open(repo_filename);
1.13 + if (set == NULL)
1.14 + return 1;
1.15 + set = razor_set_remove(set, argc, argv);
1.16 + razor_set_write(set, updated_repo_filename);
1.17 + razor_set_destroy(set);
1.18 + printf("wrote system-updated.repo\n");
1.19 +
1.20 + return 0;
1.21 +}
1.22 +
1.23 static void
1.24 print_diff(const char *name,
1.25 const char *old_version, const char *new_version, void *data)
1.26 @@ -483,6 +499,7 @@
1.27 { "import-rpms", "import rpms from the given directory", command_import_rpms },
1.28 { "validate", "validate a package set", command_validate },
1.29 { "update", "update all or specified packages", command_update },
1.30 + { "remove", "remove specified packages", command_remove },
1.31 { "diff", "show diff between two package sets", command_diff },
1.32 { "install", "install rpm", command_install }
1.33 };
2.1 --- a/razor.c Wed Feb 20 16:54:03 2008 -0500
2.2 +++ b/razor.c Thu Feb 21 12:09:13 2008 -0500
2.3 @@ -676,7 +676,7 @@
2.4 e = array_add(&importer->set->files, sizeof *e);
2.5 e->name = root.name;
2.6 e->flags = RAZOR_ENTRY_LAST;
2.7 - e->start = 1;
2.8 + e->start = importer->files.size ? 1 : 0;
2.9 list_set_empty(&e->packages);
2.10
2.11 serialize_files(importer->set, &root, &importer->set->files);
2.12 @@ -1093,12 +1093,10 @@
2.13 if (r->type != RAZOR_PROPERTY_REQUIRES)
2.14 continue;
2.15
2.16 - if (r->name != p->name) {
2.17 - p = r;
2.18 - while (p < end && p->name == r->name &&
2.19 - p->type == r->type)
2.20 - p++;
2.21 - }
2.22 + p = r;
2.23 + while (p < end && p->name == r->name &&
2.24 + p->type == r->type)
2.25 + p++;
2.26
2.27 /* If there is more than one version of a provides,
2.28 * seek to the end for the highest version. */
2.29 @@ -1396,6 +1394,7 @@
2.30 return e - (struct razor_entry *)merger->set->files.data;
2.31 }
2.32
2.33 +/* FIXME. Blah */
2.34 static int
2.35 fix_file_map(uint32_t *map,
2.36 struct razor_entry *files,
2.37 @@ -1534,22 +1533,31 @@
2.38 static void
2.39 merge_files(struct razor_merger *merger)
2.40 {
2.41 - struct razor_entry *root1, *root2;
2.42 + struct razor_entry *root;
2.43 struct merge_directory md;
2.44 uint32_t *map1, *map2;
2.45
2.46 map1 = merger->source1.file_map;
2.47 map2 = merger->source2.file_map;
2.48 - root1 = (struct razor_entry *) merger->source1.set->files.data;
2.49 - root2 = (struct razor_entry *) merger->source2.set->files.data;
2.50 -
2.51 - /* FIXME. Blah */
2.52 - fix_file_map(map1, root1, root1);
2.53 - fix_file_map(map2, root2, root2);
2.54
2.55 md.merged = add_file(merger, "");
2.56 - md.dir1 = root1->start;
2.57 - md.dir2 = root2->start;
2.58 +
2.59 + if (merger->source1.set->files.size) {
2.60 + root = (struct razor_entry *) merger->source1.set->files.data;
2.61 + if (root->start)
2.62 + fix_file_map(map1, root, root);
2.63 + md.dir1 = root->start;
2.64 + } else
2.65 + md.dir1 = 0;
2.66 +
2.67 + if (merger->source2.set->files.size) {
2.68 + root = (struct razor_entry *) merger->source2.set->files.data;
2.69 + if (root->start)
2.70 + fix_file_map(map2, root, root);
2.71 + md.dir2 = root->start;
2.72 + } else
2.73 + md.dir2 = 0;
2.74 +
2.75 merge_one_directory(merger, &md);
2.76 }
2.77
2.78 @@ -1644,35 +1652,8 @@
2.79 razor_merger_finish(struct razor_merger *merger)
2.80 {
2.81 struct razor_set *result;
2.82 -
2.83 - result = merger->set;
2.84 - hashtable_release(&merger->table);
2.85 - free(merger);
2.86 -
2.87 - return result;
2.88 -}
2.89 -
2.90 -/* Add packages from 'upstream' to 'set'. The packages to add are
2.91 - * specified by the 'packages' array, which is a sorted list of
2.92 - * package indexes. Returns a newly allocated package set. Does not
2.93 - * enforce validity of the resulting package set.
2.94 - *
2.95 - * This looks more complicated than it is. An easy way to merge two
2.96 - * package sets would be to just use a razor_importer, but that
2.97 - * requires resorting, and is thus O(n log n). We can do this in a
2.98 - * linear sweep, but it gets a little more complicated.
2.99 - */
2.100 -struct razor_set *
2.101 -razor_set_add(struct razor_set *set, struct razor_set *upstream,
2.102 - struct array *packages)
2.103 -{
2.104 - struct razor_merger *merger;
2.105 struct razor_package *p, *pend;
2.106
2.107 - merger = razor_merger_create(set, upstream);
2.108 -
2.109 - merge_packages(merger, packages);
2.110 -
2.111 /* As we built the package list, we filled out a bitvector of
2.112 * the properties that are referenced by the packages in the
2.113 * new set. Now we do a parallel loop through the properties
2.114 @@ -1710,6 +1691,33 @@
2.115 rebuild_property_package_lists(merger->set);
2.116 rebuild_file_package_lists(merger->set);
2.117
2.118 + result = merger->set;
2.119 + hashtable_release(&merger->table);
2.120 + free(merger);
2.121 +
2.122 + return result;
2.123 +}
2.124 +
2.125 +/* Add packages from 'upstream' to 'set'. The packages to add are
2.126 + * specified by the 'packages' array, which is a sorted list of
2.127 + * package indexes. Returns a newly allocated package set. Does not
2.128 + * enforce validity of the resulting package set.
2.129 + *
2.130 + * This looks more complicated than it is. An easy way to merge two
2.131 + * package sets would be to just use a razor_importer, but that
2.132 + * requires resorting, and is thus O(n log n). We can do this in a
2.133 + * linear sweep, but it gets a little more complicated.
2.134 + */
2.135 +struct razor_set *
2.136 +razor_set_add(struct razor_set *set, struct razor_set *upstream,
2.137 + struct array *packages)
2.138 +{
2.139 + struct razor_merger *merger;
2.140 +
2.141 + merger = razor_merger_create(set, upstream);
2.142 +
2.143 + merge_packages(merger, packages);
2.144 +
2.145 return razor_merger_finish(merger);
2.146 }
2.147
2.148 @@ -1839,6 +1847,108 @@
2.149 return set;
2.150 }
2.151
2.152 +static struct razor_set *
2.153 +razor_set_remove_internal(struct razor_set *set, struct array *list,
2.154 + struct array *unsatisfied)
2.155 +{
2.156 + struct razor_set *empty, *new;
2.157 + struct razor_merger *merger;
2.158 + struct razor_package *pkgs;
2.159 + int pkg_count, remove_count, p, r;
2.160 + struct array unsatisfied_before;
2.161 + uint32_t *u, *uend, *ub, *ubend;
2.162 + struct razor_property *props, *propsb;
2.163 + char *pool, *poolb;
2.164 +
2.165 + array_init(&unsatisfied_before);
2.166 + razor_set_validate(set, &unsatisfied_before);
2.167 +
2.168 + empty = razor_set_create();
2.169 + merger = razor_merger_create(set, empty);
2.170 +
2.171 + remove_count = list->size / sizeof (uint32_t);
2.172 + pkg_count = set->packages.size / sizeof (struct razor_package);
2.173 + pkgs = set->packages.data;
2.174 +
2.175 + for (p = 0; p < pkg_count; p++) {
2.176 + for (r = 0; r < remove_count; r++) {
2.177 + if (p == ((uint32_t *)list->data)[r])
2.178 + goto skip;
2.179 + }
2.180 +
2.181 + add_package(merger, &pkgs[p], &merger->source1, 0);
2.182 + skip:
2.183 + ;
2.184 + }
2.185 +
2.186 + new = razor_merger_finish(merger);
2.187 +
2.188 + razor_set_validate(new, unsatisfied);
2.189 +
2.190 + ubend = unsatisfied_before.data + unsatisfied_before.size;
2.191 + uend = unsatisfied->data + unsatisfied->size;
2.192 + props = new->properties.data;
2.193 + propsb = set->properties.data;
2.194 + pool = new->string_pool.data;
2.195 + poolb = set->string_pool.data;
2.196 +
2.197 + for (u = unsatisfied->data; u < uend; u++) {
2.198 + for (ub = unsatisfied_before.data; ub < ubend; ub++) {
2.199 + if (!strcmp (&pool[props[*u].name],
2.200 + &poolb[propsb[*ub].name]) &&
2.201 + props[*u].relation == propsb[*ub].relation &&
2.202 + !strcmp (&pool[props[*u].version],
2.203 + &poolb[propsb[*ub].version])) {
2.204 + *(u--) = *(--uend);
2.205 + break;
2.206 + }
2.207 + }
2.208 + }
2.209 +
2.210 + unsatisfied->size = (void *)uend - unsatisfied->data;
2.211 + return new;
2.212 +}
2.213 +
2.214 +struct razor_set *
2.215 +razor_set_remove(struct razor_set *set, int count, const char **packages)
2.216 +{
2.217 + struct razor_set *new;
2.218 + struct array list, unsatisfied;
2.219 + struct razor_property *props;
2.220 + uint32_t *u, *uend, *p;
2.221 + struct list *r;
2.222 +
2.223 + array_init(&list);
2.224 + find_packages(set, count, packages, &list);
2.225 +
2.226 + while (list.size > 0) {
2.227 + array_init(&unsatisfied);
2.228 + new = razor_set_remove_internal(set, &list, &unsatisfied);
2.229 + array_release(&list);
2.230 + razor_set_destroy(set);
2.231 + set = new;
2.232 +
2.233 + props = set->properties.data;
2.234 + array_init(&list);
2.235 + uend = unsatisfied.data + unsatisfied.size;
2.236 + for (u = unsatisfied.data; u < uend; u++) {
2.237 + if (props[*u].type == RAZOR_PROPERTY_REQUIRES) {
2.238 + r = list_first(&props[*u].packages, &set->package_pool);
2.239 + while (r) {
2.240 + p = array_add(&list, sizeof *p);
2.241 + *p = r->data;
2.242 + r = list_next(r);
2.243 + }
2.244 + }
2.245 + }
2.246 +
2.247 + array_release(&unsatisfied);
2.248 + }
2.249 +
2.250 + array_release(&list);
2.251 + return set;
2.252 +}
2.253 +
2.254 /* The diff order matters. We should sort the packages so that a
2.255 * REMOVE of a package comes before the INSTALL, and so that all
2.256 * requires for a package have been installed before the package.
3.1 --- a/razor.h Wed Feb 20 16:54:03 2008 -0500
3.2 +++ b/razor.h Thu Feb 21 12:09:13 2008 -0500
3.3 @@ -65,6 +65,8 @@
3.4 struct razor_set *razor_set_update(struct razor_set *set,
3.5 struct razor_set *upstream,
3.6 int count, const char **packages);
3.7 +struct razor_set *razor_set_remove(struct razor_set *set,
3.8 + int count, const char **packages);
3.9
3.10 typedef void (*razor_package_callback_t)(const char *name,
3.11 const char *old_version,
4.1 --- a/test-driver.c Wed Feb 20 16:54:03 2008 -0500
4.2 +++ b/test-driver.c Thu Feb 21 12:09:13 2008 -0500
4.3 @@ -209,11 +209,13 @@
4.4 static void
4.5 end_transaction(struct test_context *ctx)
4.6 {
4.7 - /* FIXME: removes */
4.8 ctx->system_set = razor_set_update(ctx->system_set,
4.9 ctx->repo_set,
4.10 ctx->n_install_pkgs,
4.11 (const char **)ctx->install_pkgs);
4.12 + ctx->system_set = razor_set_remove(ctx->system_set,
4.13 + ctx->n_remove_pkgs,
4.14 + (const char **)ctx->remove_pkgs);
4.15
4.16 while (ctx->n_install_pkgs--)
4.17 free(ctx->install_pkgs[ctx->n_install_pkgs]);
4.18 @@ -277,12 +279,6 @@
4.19 {
4.20 ctx->in_result = 0;
4.21
4.22 - /* FIXME */
4.23 - if (ctx->n_remove_pkgs) {
4.24 - printf (" (ignoring because of unimplemented remove)\n");
4.25 - return;
4.26 - }
4.27 -
4.28 if (ctx->system_set && ctx->result_set) {
4.29 ctx->result_errors = 0;
4.30 razor_set_diff(ctx->system_set, ctx->result_set,