razor_file_iterator_destroy(fi);
}
-/* 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.
- **/
-
RAZOR_EXPORT void
razor_set_diff(struct razor_set *set, struct razor_set *upstream,
razor_diff_callback_t callback, void *data)
struct razor_set *set;
struct razor_set *next;
struct array actions;
- struct install_action *a, *end;
+ struct deque *order;
};
static void
struct razor_set *next)
{
struct razor_install_iterator *ii;
+ struct razor_property *prop;
+ /* A graph of the actions to be perfomed where
+ * A->B means action A should follow action B.
+ */
+ struct graph follows;
+ struct install_action *actions, *ai, *aj;
+ int i, j, count, vertex_added;
+ struct list *link;
+ struct razor_set *rs;
assert (set != NULL);
assert (next != NULL);
razor_set_diff(set, next, add_action, ii);
- ii->a = ii->actions.data;
- ii->end = ii->actions.data + ii->actions.size;
+ actions = ii->actions.data;
+ count = ii->actions.size / sizeof (struct install_action);
+
+ graph_init(&follows);
+
+ for(i = 0; i < count; i++) {
+ ai = actions + i;
+ rs = ai->action == RAZOR_INSTALL_ACTION_ADD ? next : set;
+ vertex_added = 0;
+ link = list_first(&ai->package->properties, &rs->property_pool);
+ for(; link; link = list_next(link)) {
+ prop = rs->properties.data;
+ prop += link->data;
+ switch(prop->flags & RAZOR_PROPERTY_TYPE_MASK) {
+ case RAZOR_PROPERTY_REQUIRES:
+ case RAZOR_PROPERTY_CONFLICTS:
+ for(j = 0; j < count; j++) {
+ if (j == i)
+ continue;
+ aj = actions + j;
+ if (aj->package->name == prop->name) {
+ if (ai->action ==
+ RAZOR_INSTALL_ACTION_ADD)
+ graph_add_edge(&follows,
+ i, j);
+ else
+ graph_add_edge(&follows,
+ j, i);
+ vertex_added++;
+ }
+ }
+ break;
+ }
+ }
+ if (ai->action == RAZOR_INSTALL_ACTION_ADD) {
+ for(j = 0; j < count; j++) {
+ if (j == i)
+ continue;
+ aj = actions + j;
+ if (aj->package == ai->package &&
+ aj->action == RAZOR_INSTALL_ACTION_REMOVE) {
+ graph_add_edge(&follows, i, j);
+ vertex_added++;
+ }
+ }
+ }
+ if (!vertex_added)
+ graph_add_edge(&follows, i, i);
+ }
- /* FIXME: We need to figure out the right install order here,
- * so the post and pre scripts can run. */
+ ii->order = graph_sort(&follows);
+ graph_release(&follows);
return ii;
}
enum razor_install_action *action,
int *count)
{
- if (ii->a == ii->end)
+ struct install_action *a;
+ if (deque_empty(ii->order))
return 0;
- switch (ii->a->action) {
+ a = (struct install_action *)ii->actions.data + deque_pop(ii->order);
+ switch (a->action) {
case RAZOR_INSTALL_ACTION_ADD:
*set = ii->next;
break;
break;
}
- *package = ii->a->package;
- *action = ii->a->action;
+ *package = a->package;
+ *action = a->action;
*count = 0;
- ii->a++;
return 1;
}
razor_install_iterator_destroy(struct razor_install_iterator *ii)
{
array_release(&ii->actions);
+ deque_free(ii->order);
free(ii);
}
%clean
+%pre -p <lua>
+function mkdir_missing(dir)
+ if posix.stat(dir)==nil then
+ posix.mkdir(dir)
+ end
+end
+prefix=posix.getenv("RPM_INSTALL_PREFIX0")
+if prefix==nil then
+ prefix="/usr"
+end
+if posix.stat(prefix.."/bin/zap")~=nil then
+ mkdir_missing(prefix.."/var")
+ mkdir_missing(prefix.."/var/lib")
+ posix.mkdir(prefix.."/var/lib/zip")
+ io.output(prefix.."/var/lib/zip/data.zap")
+ io.write("Important data\n");
+ io.close()
+end
+
+%postun -p <lua>
+print("zip: postun script\n");
+prefix=posix.getenv("RPM_INSTALL_PREFIX0")
+if prefix==nil then
+ prefix="/usr"
+end
+if posix.stat(prefix.."/bin/zap")~=nil then
+ os.remove(prefix.."/var/lib/zip/data.zap")
+ os.remove(prefix.."/var/lib/zip")
+end
+
%files
/usr/bin/zip
%clean
+%pre -p <lua>
+function mkdir_missing(dir)
+ if posix.stat(dir)==nil then
+ posix.mkdir(dir)
+ end
+end
+prefix=posix.getenv("RPM_INSTALL_PREFIX0")
+if prefix==nil then
+ prefix="/usr"
+end
+if posix.stat(prefix.."/bin/zip")~=nil then
+ mkdir_missing(prefix.."/var")
+ mkdir_missing(prefix.."/var/lib")
+ posix.mkdir(prefix.."/var/lib/zsh")
+ io.output(prefix.."/var/lib/zsh/data.zip")
+ io.write("Important data\n");
+ io.close()
+end
+
+%postun -p <lua>
+prefix=posix.getenv("RPM_INSTALL_PREFIX0")
+if prefix==nil then
+ prefix="/usr"
+end
+if posix.stat(prefix.."/bin/zip")~=nil then
+ os.remove(prefix.."/var/lib/zsh/data.zip")
+ os.remove(prefix.."/var/lib/zsh")
+end
+
%files
/usr/bin/zsh
/etc/zsh.conf