diff --git a/src/solver.c b/src/solver.c index c4adf967c64c07f22b69dca9e598a0c47da1edd1..4c7c24ad400114183837d6cc32f1644b51634343 100644 --- a/src/solver.c +++ b/src/solver.c @@ -878,13 +878,25 @@ static void cset_check_by_reverse_iif(struct apk_solver_state *ss, struct apk_pa static void cset_gen_name_remove_orphan(struct apk_solver_state *ss, struct apk_name *name) { - struct apk_package *pkg = name->ss.chosen.pkg; + struct apk_provider *p; if (name->ss.in_changeset) return; name->ss.in_changeset = 1; - if ((!pkg || pkg->name != name) && name->ss.installed_pkg) + dbg_printf("cset_gen_name_remove_orphans: %s\n", name->name); + + /* Remove the package providing this name previously if it was provided + * by a package with different name. */ + if (name->ss.installed_pkg && (!name->ss.chosen.pkg || name->ss.chosen.pkg->name != name)) cset_gen_name_remove(ss, name->ss.installed_pkg); + + /* Remove any package that provides this name and is due to be deleted */ + foreach_array_item(p, name->providers) { + struct apk_package *pkg0 = p->pkg; + struct apk_name *name0 = pkg0->name; + if (name0->ss.installed_pkg == pkg0 && name0->ss.chosen.pkg == NULL) + cset_gen_name_remove(ss, pkg0); + } } static void cset_gen_name_change(struct apk_solver_state *ss, struct apk_name *name) @@ -894,6 +906,7 @@ static void cset_gen_name_change(struct apk_solver_state *ss, struct apk_name *n if (name->ss.in_changeset) return; + dbg_printf("cset_gen: processing: %s\n", name->name); cset_gen_name_remove_orphan(ss, name); pkg = name->ss.chosen.pkg; @@ -910,7 +923,7 @@ static void cset_gen_name_change(struct apk_solver_state *ss, struct apk_name *n foreach_array_item(d, pkg->depends) cset_gen_dep(ss, pkg, d); - dbg_printf("Selecting: "PKG_VER_FMT"%s\n", PKG_VER_PRINTF(pkg), pkg->ss.pkg_selectable ? "" : " [NOT SELECTABLE]"); + dbg_printf("cset_gen: selecting: "PKG_VER_FMT"%s\n", PKG_VER_PRINTF(pkg), pkg->ss.pkg_selectable ? "" : " [NOT SELECTABLE]"); record_change(ss, opkg, pkg); cset_check_by_reverse_iif(ss, pkg, cset_check_install_by_iif); diff --git a/test/conflict.installed b/test/conflict.installed new file mode 100644 index 0000000000000000000000000000000000000000..60cdd3baa70b7b1dd4fd2cb244a06a2def9c6ccd --- /dev/null +++ b/test/conflict.installed @@ -0,0 +1,14 @@ +C:Q1hdUpqRv5mYgJEqW52UmVsvmyysE= +P:foo +V:1 +S:1 +I:1 +D:cmd:b + +C:Q1hdOpqRv6mYgJEqW52UmVsvmyysE= +P:bar +V:1 +S:1 +I:1 +p:cmd:b=2 + diff --git a/test/conflict2.repo b/test/conflict2.repo new file mode 100644 index 0000000000000000000000000000000000000000..99cb0dfdd4ac91e7f0cf31f1c887f42f4ce59b20 --- /dev/null +++ b/test/conflict2.repo @@ -0,0 +1,20 @@ +C:Q1hdUpqRv5mYgJEqW52UmVsvmyysE= +P:foo +V:1 +S:1 +I:1 +D:cmd:b + +C:Q1hdOpqRv6mYgJEqW52UmVsvmyysE= +P:bar +V:1 +S:1 +I:1 +p:cmd:b=2 + +C:Q1hdOpqRv7mYgJEqW52UmVsvmyysE= +P:baz +V:1 +S:1 +I:1 +p:cmd:b=1 diff --git a/test/conflict3.test b/test/conflict3.test new file mode 100644 index 0000000000000000000000000000000000000000..c39aa35117cbdabf078a012c8dd7dd46f712892f --- /dev/null +++ b/test/conflict3.test @@ -0,0 +1,9 @@ +@ARGS +--test-repo conflict2.repo +--test-instdb conflict.installed +--test-world foo +add baz +@EXPECT +(1/2) Purging bar (1) +(2/2) Installing baz (1) +OK: 0 MiB in 2 packages