From: Michael Schroeder Date: Thu, 14 Nov 2019 13:16:59 +0000 (+0100) Subject: Add support for conda constrains X-Git-Tag: 0.7.9~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6adcbee1d74de31b7af8666b2c3521e8e98370d8;p=thirdparty%2Flibsolv.git Add support for conda constrains --- diff --git a/ext/repo_conda.c b/ext/repo_conda.c index 0828aff6..9352b71e 100644 --- a/ext/repo_conda.c +++ b/ext/repo_conda.c @@ -42,6 +42,24 @@ parse_deps(struct parsedata *pd, struct solv_jsonparser *jp, Offset *depp) return type; } +static int +parse_otherdeps(struct parsedata *pd, struct solv_jsonparser *jp, Id handle, Id keyname) +{ + int type = JP_ARRAY; + while (type > 0 && (type = jsonparser_parse(jp)) > 0 && type != JP_ARRAY_END) + { + if (type == JP_STRING) + { + Id id = pool_conda_matchspec(pd->pool, jp->value); + if (id) + repodata_add_idarray(pd->data, handle, keyname, id); + } + else + type = jsonparser_skip(jp, type); + } + return type; +} + static int parse_package(struct parsedata *pd, struct solv_jsonparser *jp, char *kfn) { @@ -64,6 +82,8 @@ parse_package(struct parsedata *pd, struct solv_jsonparser *jp, char *kfn) type = parse_deps(pd, jp, &s->requires); else if (type == JP_ARRAY && !strcmp(jp->key, "requires")) type = parse_deps(pd, jp, &s->requires); + else if (type == JP_ARRAY && !strcmp(jp->key, "constrains")) + type = parse_otherdeps(pd, jp, handle, SOLVABLE_CONSTRAINS); else if (type == JP_STRING && !strcmp(jp->key, "license")) repodata_add_poolstr_array(data, handle, SOLVABLE_LICENSE, jp->value); else if (type == JP_STRING && !strcmp(jp->key, "md5")) diff --git a/ext/repo_testcase.c b/ext/repo_testcase.c index 48d8a0ed..5cc03271 100644 --- a/ext/repo_testcase.c +++ b/ext/repo_testcase.c @@ -461,6 +461,14 @@ testcase_write_testtags(Repo *repo, FILE *fp) fprintf(fp, "%s\n", testcase_dep2str(pool, q.elements[i])); fprintf(fp, "-Ipr:\n"); } + if (solvable_lookup_idarray(s, SOLVABLE_CONSTRAINS, &q)) + { + int i; + fprintf(fp, "+Cns:\n"); + for (i = 0; i < q.count; i++) + fprintf(fp, "%s\n", testcase_dep2str(pool, q.elements[i])); + fprintf(fp, "-Cns:\n"); + } if (s->vendor) fprintf(fp, "=Vnd: %s\n", pool_id2str(pool, s->vendor)); if (solvable_lookup_idarray(s, SOLVABLE_BUILDFLAVOR, &q)) @@ -690,6 +698,9 @@ testcase_add_testtags(Repo *repo, FILE *fp, int flags) repodata_add_idarray(data, s - pool->solvables, SOLVABLE_PREREQ_IGNOREINST, id); break; } + case 'C' << 16 | 'n' << 8 | 's': + repodata_add_idarray(data, s - pool->solvables, SOLVABLE_CONSTRAINS, testcase_str2dep(pool, line + 6)); + break; case 'F' << 16 | 'l' << 8 | 'v': repodata_add_poolstr_array(data, s - pool->solvables, SOLVABLE_BUILDFLAVOR, line + 6); break; diff --git a/src/knownid.h b/src/knownid.h index 3a88ee26..96c9adf0 100644 --- a/src/knownid.h +++ b/src/knownid.h @@ -265,6 +265,8 @@ KNOWNID(UPDATE_STATUS, "update:status"), /* "stable", "testing", ...*/ KNOWNID(LIBSOLV_SELF_DESTRUCT_PKG, "libsolv-self-destruct-pkg()"), /* this package will self-destruct on installation */ +KNOWNID(SOLVABLE_CONSTRAINS, "solvable:constrains"), /* conda */ + KNOWNID(ID_NUM_INTERNAL, 0) #ifdef KNOWNID_INITIALIZE diff --git a/src/problems.c b/src/problems.c index b46d6249..bcce038d 100644 --- a/src/problems.c +++ b/src/problems.c @@ -1341,6 +1341,10 @@ solver_problemruleinfo2str(Solver *solv, SolverRuleinfo type, Id source, Id targ return pool_tmpappend(pool, s, pool_dep2str(pool, dep), 0); case SOLVER_RULE_BLACK: return pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), " can only be installed by a direct request"); + case SOLVER_RULE_PKG_CONSTRAINS: + s = pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), 0); + s = pool_tmpappend(pool, s, " has a constraint ", pool_dep2str(pool, dep)); + return pool_tmpappend(pool, s, " conflicting with ", pool_solvid2str(pool, target)); default: return "bad problem rule type"; } diff --git a/src/rules.c b/src/rules.c index cb8d17dd..dc4b4137 100644 --- a/src/rules.c +++ b/src/rules.c @@ -665,6 +665,30 @@ add_complex_deprules(Solver *solv, Id p, Id dep, int type, int dontfix, Queue *w #endif +#ifdef ENABLE_CONDA +void +add_conda_constrains_rule(Solver *solv, Id n, Id dep) +{ + Pool *pool = solv->pool; + Reldep *rd; + Id p, pp, pdep; + if (!ISRELDEP(dep)) + return; + rd = GETRELDEP(pool, dep); + pdep = pool_whatprovides(pool, dep); + FOR_PROVIDES(p, pp, rd->name) + { + Id p2; + while ((p2 = pool->whatprovidesdata[pdep]) != 0 && p2 < p) + pdep++; + if (p == p2) + pdep++; + else + addpkgrule(solv, -n, -p, 0, SOLVER_RULE_PKG_CONSTRAINS, dep); + } +} +#endif + /*------------------------------------------------------------------- * * add dependency rules for solvable @@ -896,6 +920,17 @@ solver_addpkgrulesforsolvable(Solver *solv, Solvable *s, Map *m) } } +#ifdef ENABLE_CONDA + if (pool->disttype == DISTTYPE_CONDA) + { + if (prereqq.count) /* reuse the prereq queue */ + queue_empty(&prereqq); + solvable_lookup_idarray(s, SOLVABLE_CONSTRAINS, &prereqq); + for (i = 0; i < prereqq.count; i++) + add_conda_constrains_rule(solv, n, prereqq.elements[i]); + } +#endif + /* that's all we check for src packages */ if (s->arch == ARCH_SRC || s->arch == ARCH_NOSRC) continue; diff --git a/src/rules.h b/src/rules.h index 92860908..3fcede07 100644 --- a/src/rules.h +++ b/src/rules.h @@ -59,6 +59,7 @@ typedef enum { SOLVER_RULE_PKG_IMPLICIT_OBSOLETES, SOLVER_RULE_PKG_INSTALLED_OBSOLETES, SOLVER_RULE_PKG_RECOMMENDS, + SOLVER_RULE_PKG_CONSTRAINS, SOLVER_RULE_UPDATE = 0x200, SOLVER_RULE_FEATURE = 0x300, SOLVER_RULE_JOB = 0x400,