summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2018-06-14 20:40:05 +0300
committerTimo Teräs <timo.teras@iki.fi>2018-06-14 20:40:05 +0300
commit7561a501b4336648cbed647d608320dad50b3dbc (patch)
tree2030974aaa65d4cf0d031596cb32f774ca0b455e
parent611172b7a92d1a9e635655cfdeec5b8c0be556e7 (diff)
fetch: ignore conflicts when solving --recursive fetches
-rw-r--r--src/apk_solver.h1
-rw-r--r--src/fetch.c2
-rw-r--r--src/solver.c31
3 files changed, 25 insertions, 9 deletions
diff --git a/src/apk_solver.h b/src/apk_solver.h
index b6067e2eeeb..b8b072d7df5 100644
--- a/src/apk_solver.h
+++ b/src/apk_solver.h
@@ -34,6 +34,7 @@ struct apk_changeset {
#define APK_SOLVERF_AVAILABLE 0x0002
#define APK_SOLVERF_REINSTALL 0x0004
#define APK_SOLVERF_LATEST 0x0008
+#define APK_SOLVERF_IGNORE_CONFLICT 0x0010
void apk_solver_set_name_flags(struct apk_name *name,
unsigned short solver_flags,
diff --git a/src/fetch.c b/src/fetch.c
index 9707752f416..e745d840e9c 100644
--- a/src/fetch.c
+++ b/src/fetch.c
@@ -240,7 +240,7 @@ static void mark_names_recursive(struct apk_database *db, struct apk_string_arra
struct apk_change *change;
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) {
foreach_array_item(change, changeset.changes)
mark_package(ctx, change->new_pkg);
diff --git a/src/solver.c b/src/solver.c
index d27a7a35f3f..7abc80cc876 100644
--- a/src/solver.c
+++ b/src/solver.c
@@ -39,6 +39,7 @@ struct apk_solver_state {
unsigned int solver_flags_inherit;
unsigned int pinning_inherit;
unsigned int default_repos;
+ unsigned ignore_conflict : 1;
};
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_provider *p;
+ if (dep->conflict && ss->ignore_conflict)
+ return TRUE;
+
if (name->ss.locked)
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),
BLOB_PRINTF(*dep->version));
+ if (dep->conflict && ss->ignore_conflict)
+ return;
+
name->ss.requirers += !dep->conflict;
if (name->ss.requirers == 1 && !dep->conflict)
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_dependency *d;
- if (name == must_provide)
+ if (name == must_provide || ss->ignore_conflict)
return;
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 &&
name->ss.chosen.version == &apk_null_blob)
return;
+ if (ss->ignore_conflict)
+ return;
/* Conflict: providing same name */
mark_error(ss, p.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);
/* disqualify all conflicting packages */
- foreach_array_item(p0, name->providers) {
- if (p0->pkg == p.pkg)
- continue;
- if (p.version == &apk_null_blob &&
- p0->version == &apk_null_blob)
- continue;
- disqualify_package(ss, p0->pkg, "conflicting provides");
+ if (!ss->ignore_conflict) {
+ foreach_array_item(p0, name->providers) {
+ if (p0->pkg == p.pkg)
+ continue;
+ if (p.version == &apk_null_blob &&
+ p0->version == &apk_null_blob)
+ continue;
+ disqualify_package(ss, p0->pkg, "conflicting provides");
+ }
}
reevaluate_reverse_deps(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_package *pkg = name->ss.chosen.pkg;
+ if (dep->conflict && ss->ignore_conflict)
+ return;
+
if (!apk_dep_is_provided(dep, &name->ss.chosen))
mark_error(ss, ppkg, "unfulfilled dependency");
@@ -974,6 +988,7 @@ restart:
ss->db = db;
ss->changeset = changeset;
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->unresolved_head);