diff options
author | Timo Teräs <timo.teras@iki.fi> | 2014-04-04 13:05:52 +0300 |
---|---|---|
committer | Timo Teräs <timo.teras@iki.fi> | 2014-04-04 13:05:52 +0300 |
commit | 06071700c5c30b37e3fa2f7cae73495c57c93249 (patch) | |
tree | 2e893267dd3d03dc643c6af2509513c2434d060c /src/solver.c | |
parent | ec1a3d57ab66e4b5159d280809e0e5f09867dcff (diff) | |
download | apk-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.c | 84 |
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 { |