fetch: ignore conflicts when solving --recursive fetches

cute-signatures
Timo Teräs 2018-06-14 20:40:05 +03:00
parent 611172b7a9
commit 7561a501b4
3 changed files with 25 additions and 9 deletions

View File

@ -34,6 +34,7 @@ struct apk_changeset {
#define APK_SOLVERF_AVAILABLE 0x0002 #define APK_SOLVERF_AVAILABLE 0x0002
#define APK_SOLVERF_REINSTALL 0x0004 #define APK_SOLVERF_REINSTALL 0x0004
#define APK_SOLVERF_LATEST 0x0008 #define APK_SOLVERF_LATEST 0x0008
#define APK_SOLVERF_IGNORE_CONFLICT 0x0010
void apk_solver_set_name_flags(struct apk_name *name, void apk_solver_set_name_flags(struct apk_name *name,
unsigned short solver_flags, unsigned short solver_flags,

View File

@ -240,7 +240,7 @@ static void mark_names_recursive(struct apk_database *db, struct apk_string_arra
struct apk_change *change; struct apk_change *change;
int r; int r;
r = apk_solver_solve(db, 0, ctx->world, &changeset); r = apk_solver_solve(db, APK_SOLVERF_IGNORE_CONFLICT, ctx->world, &changeset);
if (r == 0) { if (r == 0) {
foreach_array_item(change, changeset.changes) foreach_array_item(change, changeset.changes)
mark_package(ctx, change->new_pkg); mark_package(ctx, change->new_pkg);

View File

@ -39,6 +39,7 @@ struct apk_solver_state {
unsigned int solver_flags_inherit; unsigned int solver_flags_inherit;
unsigned int pinning_inherit; unsigned int pinning_inherit;
unsigned int default_repos; unsigned int default_repos;
unsigned ignore_conflict : 1;
}; };
static struct apk_provider provider_none = { static struct apk_provider provider_none = {
@ -156,6 +157,9 @@ static int dependency_satisfiable(struct apk_solver_state *ss, struct apk_depend
struct apk_name *name = dep->name; struct apk_name *name = dep->name;
struct apk_provider *p; struct apk_provider *p;
if (dep->conflict && ss->ignore_conflict)
return TRUE;
if (name->ss.locked) if (name->ss.locked)
return apk_dep_is_provided(dep, &name->ss.chosen); return apk_dep_is_provided(dep, &name->ss.chosen);
@ -284,6 +288,9 @@ static void apply_constraint(struct apk_solver_state *ss, struct apk_package *pp
apk_version_op_string(dep->result_mask), apk_version_op_string(dep->result_mask),
BLOB_PRINTF(*dep->version)); BLOB_PRINTF(*dep->version));
if (dep->conflict && ss->ignore_conflict)
return;
name->ss.requirers += !dep->conflict; name->ss.requirers += !dep->conflict;
if (name->ss.requirers == 1 && !dep->conflict) if (name->ss.requirers == 1 && !dep->conflict)
name_requirers_changed(ss, name); name_requirers_changed(ss, name);
@ -309,7 +316,7 @@ static void exclude_non_providers(struct apk_solver_state *ss, struct apk_name *
struct apk_provider *p; struct apk_provider *p;
struct apk_dependency *d; struct apk_dependency *d;
if (name == must_provide) if (name == must_provide || ss->ignore_conflict)
return; return;
dbg_printf("%s must provide %s (skip_virtuals=%d)\n", name->name, must_provide->name, skip_virtuals); dbg_printf("%s must provide %s (skip_virtuals=%d)\n", name->name, must_provide->name, skip_virtuals);
@ -624,6 +631,8 @@ static void assign_name(struct apk_solver_state *ss, struct apk_name *name, stru
if (p.version == &apk_null_blob && if (p.version == &apk_null_blob &&
name->ss.chosen.version == &apk_null_blob) name->ss.chosen.version == &apk_null_blob)
return; return;
if (ss->ignore_conflict)
return;
/* Conflict: providing same name */ /* Conflict: providing same name */
mark_error(ss, p.pkg, "conflict: same name provided"); mark_error(ss, p.pkg, "conflict: same name provided");
mark_error(ss, name->ss.chosen.pkg, "conflict: same name provided"); mark_error(ss, name->ss.chosen.pkg, "conflict: same name provided");
@ -641,13 +650,15 @@ static void assign_name(struct apk_solver_state *ss, struct apk_name *name, stru
list_del(&name->ss.dirty_list); list_del(&name->ss.dirty_list);
/* disqualify all conflicting packages */ /* disqualify all conflicting packages */
foreach_array_item(p0, name->providers) { if (!ss->ignore_conflict) {
if (p0->pkg == p.pkg) foreach_array_item(p0, name->providers) {
continue; if (p0->pkg == p.pkg)
if (p.version == &apk_null_blob && continue;
p0->version == &apk_null_blob) if (p.version == &apk_null_blob &&
continue; p0->version == &apk_null_blob)
disqualify_package(ss, p0->pkg, "conflicting provides"); continue;
disqualify_package(ss, p0->pkg, "conflicting provides");
}
} }
reevaluate_reverse_deps(ss, name); reevaluate_reverse_deps(ss, name);
reevaluate_reverse_installif(ss, name); reevaluate_reverse_installif(ss, name);
@ -880,6 +891,9 @@ static void cset_gen_dep(struct apk_solver_state *ss, struct apk_package *ppkg,
struct apk_name *name = dep->name; struct apk_name *name = dep->name;
struct apk_package *pkg = name->ss.chosen.pkg; struct apk_package *pkg = name->ss.chosen.pkg;
if (dep->conflict && ss->ignore_conflict)
return;
if (!apk_dep_is_provided(dep, &name->ss.chosen)) if (!apk_dep_is_provided(dep, &name->ss.chosen))
mark_error(ss, ppkg, "unfulfilled dependency"); mark_error(ss, ppkg, "unfulfilled dependency");
@ -974,6 +988,7 @@ restart:
ss->db = db; ss->db = db;
ss->changeset = changeset; ss->changeset = changeset;
ss->default_repos = apk_db_get_pinning_mask_repos(db, APK_DEFAULT_PINNING_MASK); ss->default_repos = apk_db_get_pinning_mask_repos(db, APK_DEFAULT_PINNING_MASK);
ss->ignore_conflict = !!(solver_flags & APK_SOLVERF_IGNORE_CONFLICT);
list_init(&ss->dirty_head); list_init(&ss->dirty_head);
list_init(&ss->unresolved_head); list_init(&ss->unresolved_head);