summaryrefslogtreecommitdiff
path: root/src/solver.c
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2014-04-04 13:05:52 +0300
committerTimo Teräs <timo.teras@iki.fi>2014-04-04 13:05:52 +0300
commit06071700c5c30b37e3fa2f7cae73495c57c93249 (patch)
tree2e893267dd3d03dc643c6af2509513c2434d060c /src/solver.c
parentec1a3d57ab66e4b5159d280809e0e5f09867dcff (diff)
downloadapk-tools-06071700c5c30b37e3fa2f7cae73495c57c93249.tar.gz
apk-tools-06071700c5c30b37e3fa2f7cae73495c57c93249.tar.bz2
apk-tools-06071700c5c30b37e3fa2f7cae73495c57c93249.tar.xz
apk-tools-06071700c5c30b37e3fa2f7cae73495c57c93249.zip
solver: fix inherited flags/pinning for install_if packages
noticeable fixes upgrading of packages which get pulled in only by install_if rule. this also simplifies the inheritance calculation for packages, as well as the place where it is done for install_if triggered packages.
Diffstat (limited to 'src/solver.c')
-rw-r--r--src/solver.c84
1 files changed, 28 insertions, 56 deletions
diff --git a/src/solver.c b/src/solver.c
index 2318d72..31b3db7 100644
--- a/src/solver.c
+++ b/src/solver.c
@@ -39,7 +39,6 @@ struct apk_solver_state {
unsigned int solver_flags_inherit;
unsigned int pinning_inherit;
unsigned int default_repos;
- unsigned prefer_pinning : 1;
};
static struct apk_provider provider_none = {
@@ -78,29 +77,6 @@ static unsigned int get_pkg_repos(struct apk_database *db, struct apk_package *p
return pkg->repos | (pkg->ipkg ? db->repo_tags[pkg->ipkg->repository_tag].allowed_repos : 0);
}
-static void foreach_rinstall_if_pkg(
- struct apk_solver_state *ss, struct apk_package *pkg,
- void (*cb)(struct apk_solver_state *ss, struct apk_package *rinstall_if, struct apk_package *parent_pkg))
-{
- struct apk_name *name = pkg->name, *name0, **pname0;
- struct apk_dependency *dep;
- struct apk_provider *p0;
-
- foreach_array_item(pname0, pkg->name->rinstall_if) {
- name0 = *pname0;
- dbg_printf(PKG_VER_FMT ": rinstall_if %s\n", PKG_VER_PRINTF(pkg), name0->name);
- foreach_array_item(p0, name0->providers) {
- foreach_array_item(dep, p0->pkg->install_if) {
- if (dep->name == name && apk_dep_is_provided(dep, p0)) {
- /* pkg depends (via install_if) on pkg0 */
- cb(ss, p0->pkg, pkg);
- break;
- }
- }
- }
- }
-}
-
static void mark_error(struct apk_solver_state *ss, struct apk_package *pkg)
{
if (pkg == NULL || pkg->ss.error)
@@ -257,24 +233,35 @@ static void name_requirers_changed(struct apk_solver_state *ss, struct apk_name
queue_dirty(ss, name);
}
-static void inherit_pinning(struct apk_solver_state *ss, struct apk_package *pkg, unsigned int pinning, int prefer)
+static void inherit_pinning_and_flags(
+ struct apk_solver_state *ss, struct apk_package *pkg, struct apk_package *ppkg)
{
- unsigned int repo_mask = apk_db_get_pinning_mask_repos(ss->db, pinning);
unsigned int repos = get_pkg_repos(ss->db, pkg);
- pkg->ss.pinning_allowed |= pinning;
- pkg->ss.tag_ok |= !!(repos & repo_mask);
- if (prefer) {
- pkg->ss.pinning_preferred = pinning;
+ if (ppkg != NULL) {
+ /* inherited */
+ pkg->ss.solver_flags |= ppkg->ss.solver_flags_inheritable;
+ pkg->ss.solver_flags_inheritable |= ppkg->ss.solver_flags_inheritable;
+ pkg->ss.pinning_allowed |= ppkg->ss.pinning_allowed;
+ } else {
+ /* world dependency */
+ pkg->ss.solver_flags |= ss->solver_flags_inherit;
+ pkg->ss.solver_flags_inheritable |= ss->solver_flags_inherit;
+ pkg->ss.pinning_allowed |= ss->pinning_inherit;
+ /* also prefer main pinnings */
+ pkg->ss.pinning_preferred = ss->pinning_inherit;
pkg->ss.tag_preferred = !!(repos & apk_db_get_pinning_mask_repos(ss->db, pkg->ss.pinning_preferred));
}
+ pkg->ss.tag_ok |= !!(repos & apk_db_get_pinning_mask_repos(ss->db, pkg->ss.pinning_allowed));
+
+ dbg_printf(PKG_VER_FMT ": tag_ok=%d, tag_pref=%d\n",
+ PKG_VER_PRINTF(pkg), pkg->ss.tag_ok, pkg->ss.tag_preferred);
}
static void apply_constraint(struct apk_solver_state *ss, struct apk_package *ppkg, struct apk_dependency *dep)
{
struct apk_name *name = dep->name;
struct apk_provider *p0;
- unsigned int solver_flags_inherit = ss->solver_flags_inherit;
int is_provided;
dbg_printf(" apply_constraint: %s%s%s" BLOB_FMT "\n",
@@ -298,16 +285,8 @@ static void apply_constraint(struct apk_solver_state *ss, struct apk_package *pp
if (unlikely(pkg0->ss.pkg_selectable && pkg0->ss.conflicts))
disqualify_package(ss, pkg0, "conflicting dependency");
- if (is_provided) {
- pkg0->ss.solver_flags |= solver_flags_inherit;
- pkg0->ss.solver_flags_inheritable |= solver_flags_inherit;
- inherit_pinning(ss, pkg0, ss->pinning_inherit, ss->prefer_pinning);
-
- dbg_printf(PKG_VER_FMT ": tag_ok=%d, tag_pref=%d\n",
- PKG_VER_PRINTF(pkg0),
- pkg0->ss.tag_ok,
- pkg0->ss.tag_preferred);
- }
+ if (is_provided)
+ inherit_pinning_and_flags(ss, pkg0, ppkg);
}
}
@@ -401,6 +380,12 @@ static void reconsider_name(struct apk_solver_state *ss, struct apk_name *name)
}
}
}
+ if (reevaluate_iif && pkg->ss.iif_triggered) {
+ foreach_array_item(dep, pkg->install_if)
+ inherit_pinning_and_flags(ss, pkg, dep->name->ss.chosen.pkg);
+ }
+ dbg_printf(" "PKG_VER_FMT": iif_triggered=%d iif_failed=%d\n",
+ PKG_VER_PRINTF(pkg), pkg->ss.iif_triggered, pkg->ss.iif_failed);
has_iif |= pkg->ss.iif_triggered;
no_iif &= pkg->ss.iif_failed;
@@ -586,11 +571,6 @@ static int compare_providers(struct apk_solver_state *ss,
return ffs(pkgB->repos) - ffs(pkgA->repos);
}
-static void inherit_pinning_from_pkg(struct apk_solver_state *ss, struct apk_package *rinstall_if, struct apk_package *parent_pkg)
-{
- inherit_pinning(ss, rinstall_if, parent_pkg->ss.pinning_allowed, 0);
-}
-
static void assign_name(struct apk_solver_state *ss, struct apk_name *name, struct apk_provider p)
{
struct apk_provider *p0;
@@ -616,10 +596,6 @@ static void assign_name(struct apk_solver_state *ss, struct apk_name *name, stru
if (list_hashed(&name->ss.dirty_list))
list_del(&name->ss.dirty_list);
- /* propagate pinning to install_if candidates */
- if (p.pkg)
- foreach_rinstall_if_pkg(ss, p.pkg, inherit_pinning_from_pkg);
-
/* disqualify all conflicting packages */
foreach_array_item(p0, name->providers) {
if (p0->pkg == p.pkg)
@@ -643,6 +619,8 @@ static void select_package(struct apk_solver_state *ss, struct apk_name *name)
if (name->ss.requirers || name->ss.has_iif) {
foreach_array_item(p, name->providers) {
+ dbg_printf(" consider "PKG_VER_FMT" iif_triggered=%d, tag_ok=%d\n",
+ PKG_VER_PRINTF(p->pkg), p->pkg->ss.iif_triggered, p->pkg->ss.tag_ok);
/* Ensure valid pinning and install-if trigger */
if (name->ss.requirers == 0 &&
(!p->pkg->ss.iif_triggered ||
@@ -668,12 +646,8 @@ static void select_package(struct apk_solver_state *ss, struct apk_name *name)
foreach_array_item(d, pkg->provides)
assign_name(ss, d->name, APK_PROVIDER_FROM_PROVIDES(pkg, d));
- ss->solver_flags_inherit = pkg->ss.solver_flags_inheritable;
- ss->pinning_inherit = pkg->ss.pinning_allowed;
foreach_array_item(d, pkg->depends)
apply_constraint(ss, pkg, d);
- ss->solver_flags_inherit = 0;
- ss->pinning_inherit = 0;
} else {
dbg_printf("selecting: %s [unassigned]\n", name->name);
assign_name(ss, name, provider_none);
@@ -913,7 +887,6 @@ restart:
list_init(&ss->unresolved_head);
dbg_printf("discovering world\n");
- ss->prefer_pinning = 1;
ss->solver_flags_inherit = solver_flags;
foreach_array_item(d, world) {
if (!d->broken)
@@ -928,7 +901,6 @@ restart:
}
ss->solver_flags_inherit = 0;
ss->pinning_inherit = 0;
- ss->prefer_pinning = 0;
dbg_printf("applying world [finished]\n");
do {