Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Merge pull request #1446 from vstakhov/master
Vsevolod Stakhov committed 9 years ago
commit 87cda8c88d24c687d15e396e104da229523dc19d
parent 9820377
4 files changed +110 -117
modified libpkg/pkg_jobs.c
@@ -732,7 +732,12 @@ new_pkg_version(struct pkg_jobs *j)
			DL_FOREACH(nit, cit) {
				if (pkg_version_change_between (cit->pkg, p) == PKG_UPGRADE) {
					/* We really have newer version which is not installed */
-
					ret = true;
+
					/* Preserve repo pinning logic */
+
					if ((j->reponame && strcmp (cit->pkg->reponame, j->reponame) == 0) ||
+
							(!j->reponame && (!p->reponame ||
+
									strcmp (cit->pkg->reponame, p->reponame) == 0))) {
+
						ret = true;
+
					}
				}
			}
		}
@@ -1586,11 +1591,14 @@ jobs_solve_install_upgrade(struct pkg_jobs *j)
			pkg_emit_progress_start("Processing candidates (%zd candidates)",
				jcount);
			elt_num = 0;
+

			HASH_ITER(hh, j->request_add, req, rtmp) {
				pkg_emit_progress_tick(++elt_num, jcount);
				pkg_jobs_universe_process(j->universe, req->item->pkg);
			}
			pkg_emit_progress_tick(jcount, jcount);
+

+
			pkg_jobs_universe_process_upgrade_chains(j);
		}
		else {
			HASH_ITER(hh, j->patterns, jp, jtmp) {
modified libpkg/pkg_jobs_universe.c
@@ -170,40 +170,18 @@ pkg_jobs_universe_add_pkg(struct pkg_jobs_universe *universe, struct pkg *pkg,
	}

	kh_find(pkg_jobs_seen, universe->seen, pkg->digest, seen);
-
	if (seen != NULL && !force && pkg->type != PKG_INSTALLED) {
-
		/*
-
		 * For remote packages we could have the same digest but different repos
-
		 * therefore we should also compare reponames
-
		 */
-
		bool other_candidate = true;
-

-
		if (pkg->reponame) {
-
			/* Rewind to the first element */
-
			while (seen->prev->next != NULL) {
-
				seen = seen->prev;
-
			}
+
	if (seen) {
+
		bool same_package = false;

-
			LL_FOREACH (seen, tmp) {
-
				if (tmp->pkg->reponame) {
-
					if (strcmp (pkg->reponame, tmp->pkg->reponame) == 0) {
-
						/* Same repo package in the chain, do not add */
-
						other_candidate = false;
-
						break;
-
					}
-
				}
-
				else if (tmp->pkg->type == PKG_INSTALLED &&
-
						strcmp (tmp->pkg->digest, pkg->digest) == 0) {
-
					/* Same as local, skip */
-
					other_candidate = false;
-
					break;
-
				}
+
		DL_FOREACH(seen, tmp) {
+
			if (tmp->pkg == pkg || (tmp->pkg->type == pkg->type &&
+
					strcmp (tmp->pkg->digest, pkg->digest) == 0)) {
+
				same_package = true;
+
				break;
			}
		}
-
		else {
-
			other_candidate = false;
-
		}

-
		if (!other_candidate) {
+
		if (same_package) {
			if (found != NULL) {
				*found = seen;
			}
@@ -211,13 +189,6 @@ pkg_jobs_universe_add_pkg(struct pkg_jobs_universe *universe, struct pkg *pkg,
			return (EPKG_END);
		}
	}
-
	else if (seen && !force) {
-
		if (found != NULL) {
-
			*found = seen;
-
		}
-

-
		return (EPKG_END);
-
	}

	if (pkg_is_locked(pkg)) {
		pkg_emit_locked(pkg);
@@ -403,7 +374,7 @@ pkg_jobs_universe_handle_provide(struct pkg_jobs_universe *universe,
{
	struct pkg_job_universe_item *unit;
	struct pkg_job_provide *pr, *prhead;
-
	struct pkg *npkg, *rpkg, *selected = NULL;
+
	struct pkg *npkg, *rpkg;
	int rc;
	unsigned flags = PKG_LOAD_BASIC|PKG_LOAD_OPTIONS|PKG_LOAD_DEPS|
				PKG_LOAD_REQUIRES|PKG_LOAD_PROVIDES|
@@ -414,39 +385,13 @@ pkg_jobs_universe_handle_provide(struct pkg_jobs_universe *universe,

	HASH_FIND_STR(universe->provides, name, prhead);

-
	/*
-
	 * Here we follow the same logic as for direct deps:
-
	 * - iterate over all provides;
-
	 * - select provides that are from the same repo as the requested package
-
	 * - if there is no such a package, then go through all possible provides
-
	 */
	while (pkgdb_it_next(it, &rpkg, flags) == EPKG_OK) {
-
		if (parent->reponame && rpkg->reponame && strcmp(parent->reponame,
-
				rpkg->reponame) == 0) {
-
			selected = rpkg;
-
			break;
-
		}
-
	}
-

-
	if (!selected) {
-
		pkgdb_it_reset(it);
-
	}
-

-
	while (selected || pkgdb_it_next(it, &rpkg, flags) == EPKG_OK) {
-
		if (selected) {
-
			rpkg = selected;
-
		}
		/* Check for local packages */
		HASH_FIND_STR(universe->items, rpkg->uid, unit);
		if (unit != NULL) {
			/* Remote provide is newer, so we can add it */
			if (pkg_jobs_universe_process_item(universe, rpkg,
					&unit) != EPKG_OK) {
-

-
				if (selected) {
-
					return (EPKG_FATAL);
-
				}
-

				continue;
			}

@@ -462,9 +407,7 @@ pkg_jobs_universe_handle_provide(struct pkg_jobs_universe *universe,
				}
				if (pkg_jobs_universe_process_item(universe, rpkg,
						&unit) != EPKG_OK) {
-
					if (selected) {
-
						return (EPKG_FATAL);
-
					}
+
					continue;
				}
			}
		}
@@ -515,10 +458,6 @@ pkg_jobs_universe_handle_provide(struct pkg_jobs_universe *universe,
					pr->un->pkg->type == PKG_INSTALLED ? "l" : "r",
					pr->provide);
		}
-

-
		if (selected) {
-
			break;
-
		}
	}

	return (EPKG_OK);
@@ -1020,29 +959,31 @@ pkg_jobs_universe_select_max_prio(struct pkg_job_universe_item *chain)

static struct pkg_job_universe_item *
pkg_jobs_universe_select_same_repo(struct pkg_job_universe_item *chain,
-
	struct pkg_job_universe_item *local)
+
	struct pkg_job_universe_item *local, const char *assumed_reponame)
{
	struct pkg_repo *local_repo = NULL, *repo;
	struct pkg_job_universe_item *cur, *res = NULL;

-
	if (local->pkg->reponame) {
-
		local_repo = pkg_repo_find(local->pkg->reponame);
+
	if (!local) {
+

+
		if (assumed_reponame) {
+
			local_repo = pkg_repo_find(assumed_reponame);
+
		}
	}
	else {
-
		const char *lrepo = pkg_kv_get(&local->pkg->annotations, "repository");
-
		if (lrepo) {
-
			local_repo = pkg_repo_find(lrepo);
+
		if (local->pkg->reponame) {
+
			local_repo = pkg_repo_find(local->pkg->reponame);
+
		}
+
		else {
+
			const char *lrepo = pkg_kv_get(&local->pkg->annotations, "repository");
+
			if (lrepo) {
+
				local_repo = pkg_repo_find(lrepo);
+
			}
		}
	}

	if (local_repo == NULL) {
-
		/* Return any package */
-
		LL_FOREACH(chain, cur) {
-
			if (cur->pkg->type == PKG_INSTALLED)
-
				continue;
-
			else
-
				return (cur);
-
		}
+
		return (NULL);
	}
	else {
		LL_FOREACH(chain, cur) {
@@ -1064,31 +1005,44 @@ pkg_jobs_universe_select_same_repo(struct pkg_job_universe_item *chain,

struct pkg_job_universe_item *
pkg_jobs_universe_select_candidate(struct pkg_job_universe_item *chain,
-
	struct pkg_job_universe_item *local, bool conservative)
+
	struct pkg_job_universe_item *local, bool conservative, const char *reponame)
{
-
	struct pkg_job_universe_item *res;
+
	struct pkg_job_universe_item *res = NULL;

	if (local == NULL) {
		/* New package selection */
		if (conservative) {
-
			/* Priority -> version */
-
			res = pkg_jobs_universe_select_max_prio(chain);
+
			/* Check same repo */
+
			if (reponame) {
+
				res =  pkg_jobs_universe_select_same_repo(chain, NULL, reponame);
+
			}
+

			if (res == NULL) {
-
				res = pkg_jobs_universe_select_max_ver(chain);
+
				/* Priority -> version */
+
				res = pkg_jobs_universe_select_max_prio(chain);
+
				if (res == NULL) {
+
					res = pkg_jobs_universe_select_max_ver(chain);
+
				}
			}
		}
		else {
-
			/* Version -> priority */
-
			res = pkg_jobs_universe_select_max_ver(chain);
+
			if (reponame) {
+
				res =  pkg_jobs_universe_select_same_repo(chain, NULL, reponame);
+
			}
+

			if (res == NULL) {
-
				res = pkg_jobs_universe_select_max_prio(chain);
+
				/* Version -> priority */
+
				res = pkg_jobs_universe_select_max_ver(chain);
+
				if (res == NULL) {
+
					res = pkg_jobs_universe_select_max_prio(chain);
+
				}
			}
		}
	}
	else {
		if (conservative) {
			/* same -> prio -> version */
-
			res = pkg_jobs_universe_select_same_repo(chain, local);
+
			res = pkg_jobs_universe_select_same_repo(chain, local, reponame);
			if (res == NULL) {
				res = pkg_jobs_universe_select_max_prio(chain);
			}
@@ -1097,13 +1051,13 @@ pkg_jobs_universe_select_candidate(struct pkg_job_universe_item *chain,
			}
		}
		else {
-
			/* version -> prio -> same */
-
			res = pkg_jobs_universe_select_max_ver(chain);
+
			/* same -> version -> prio */
+
			res = pkg_jobs_universe_select_same_repo(chain, local, reponame);
			if (res == NULL) {
-
				res = pkg_jobs_universe_select_max_prio(chain);
+
				res = pkg_jobs_universe_select_max_ver(chain);
			}
			if (res == NULL) {
-
				res = pkg_jobs_universe_select_same_repo(chain, local);
+
				res = pkg_jobs_universe_select_max_prio(chain);
			}
		}
	}
@@ -1157,7 +1111,7 @@ pkg_jobs_universe_process_upgrade_chains(struct pkg_jobs *j)
			struct pkg_job_universe_item *selected;

			selected = pkg_jobs_universe_select_candidate(unit, local,
-
				j->conservative);
+
				j->conservative, NULL);
			/*
			 * Now remove all requests but selected from the requested
			 * candidates
modified libpkg/pkg_solve.c
@@ -79,6 +79,7 @@ struct pkg_solve_variable {
	int order;
	const char *digest;
	const char *uid;
+
	const char *assumed_reponame;
	UT_hash_handle hh;
	struct pkg_solve_variable *next, *prev;
};
@@ -296,7 +297,7 @@ pkg_debug_print_rule(struct pkg_solve_rule *rule)
static int
pkg_solve_handle_provide (struct pkg_solve_problem *problem,
		struct pkg_job_provide *pr, struct pkg_solve_rule *rule,
-
		struct pkg *orig, int *cnt)
+
		struct pkg *orig, const char *reponame, int *cnt)
{
	struct pkg_solve_item *it = NULL;
	struct pkg_solve_variable *var, *curvar;
@@ -341,6 +342,11 @@ pkg_solve_handle_provide (struct pkg_solve_problem *problem,
							'l' : 'r');
			continue;
		}
+

+
		if (curvar->assumed_reponame == NULL) {
+
			curvar->assumed_reponame = reponame;
+
		}
+

		pkg_debug(4, "solver: %s provide is satisfied by %s-%s(%c)", pr->provide,
				pkg->name, pkg->version, pkg->type == PKG_INSTALLED ?
				'l' : 'r');
@@ -360,7 +366,8 @@ pkg_solve_handle_provide (struct pkg_solve_problem *problem,
static int
pkg_solve_add_depend_rule(struct pkg_solve_problem *problem,
		struct pkg_solve_variable *var,
-
		struct pkg_dep *dep)
+
		struct pkg_dep *dep,
+
		const char *reponame)
{
	const char *uid;
	struct pkg_solve_variable *depvar, *curvar;
@@ -390,6 +397,11 @@ pkg_solve_add_depend_rule(struct pkg_solve_problem *problem,
	/* B1 | B2 | ... */
	cnt = 1;
	LL_FOREACH(depvar, curvar) {
+
		/* Propagate reponame */
+
		if (curvar->assumed_reponame == NULL) {
+
			curvar->assumed_reponame = reponame;
+
		}
+

		it = pkg_solve_item_new(curvar);
		if (it == NULL) {
			pkg_solve_rule_free(rule);
@@ -487,7 +499,8 @@ pkg_solve_add_conflict_rule(struct pkg_solve_problem *problem,
static int
pkg_solve_add_require_rule(struct pkg_solve_problem *problem,
		struct pkg_solve_variable *var,
-
		const char *requirement)
+
		const char *requirement,
+
		const char *reponame)
{
	struct pkg_solve_rule *rule;
	struct pkg_solve_item *it = NULL;
@@ -518,7 +531,8 @@ pkg_solve_add_require_rule(struct pkg_solve_problem *problem,
		/* B1 | B2 | ... */
		cnt = 1;
		LL_FOREACH(prhead, pr) {
-
			if (pkg_solve_handle_provide(problem, pr, rule, pkg, &cnt) != EPKG_OK) {
+
			if (pkg_solve_handle_provide(problem, pr, rule, pkg, reponame, &cnt)
+
					!= EPKG_OK) {
				free(it);
				free(rule);
				return (EPKG_FATAL);
@@ -732,10 +746,26 @@ pkg_solve_process_universe_variable(struct pkg_solve_problem *problem,
	LL_FOREACH(var, cur_var) {
		pkg = cur_var->unit->pkg;

+
		/* Request */
+
		if (!(cur_var->flags & PKG_VAR_TOP)) {
+
			HASH_FIND_STR(j->request_add, cur_var->uid, jreq);
+
			if (jreq != NULL)
+
				pkg_solve_add_request_rule(problem, cur_var, jreq, 1);
+
			HASH_FIND_STR(j->request_delete, cur_var->uid, jreq);
+
			if (jreq != NULL)
+
				pkg_solve_add_request_rule(problem, cur_var, jreq, -1);
+
		}
+

+
		if (jreq) {
+
			cur_var->assumed_reponame = pkg->reponame;
+
		}
+

		/* Depends */
		kh_each_value(pkg->deps, dep, {
-
			if (pkg_solve_add_depend_rule(problem, cur_var, dep) != EPKG_OK)
+
			if (pkg_solve_add_depend_rule(problem, cur_var, dep,
+
					cur_var->assumed_reponame) != EPKG_OK) {
				continue;
+
			}
		});

		/* Conflicts */
@@ -749,25 +779,18 @@ pkg_solve_process_universe_variable(struct pkg_solve_problem *problem,
		buf = NULL;
		while (pkg_shlibs_required(pkg, &buf) == EPKG_OK) {
			if (pkg_solve_add_require_rule(problem, cur_var,
-
					buf) != EPKG_OK)
+
					buf, cur_var->assumed_reponame) != EPKG_OK) {
				continue;
+
			}
		}
		buf = NULL;
		while (pkg_requires(pkg, &buf) == EPKG_OK) {
			if (pkg_solve_add_require_rule(problem, cur_var,
-
					buf) != EPKG_OK)
+
					buf, cur_var->assumed_reponame) != EPKG_OK) {
				continue;
+
			}
		}

-
		/* Request */
-
		if (!(cur_var->flags & PKG_VAR_TOP)) {
-
			HASH_FIND_STR(j->request_add, cur_var->uid, jreq);
-
			if (jreq != NULL)
-
				pkg_solve_add_request_rule(problem, cur_var, jreq, 1);
-
			HASH_FIND_STR(j->request_delete, cur_var->uid, jreq);
-
			if (jreq != NULL)
-
				pkg_solve_add_request_rule(problem, cur_var, jreq, -1);
-
		}

		/*
		 * If this var chain contains mutually conflicting vars
@@ -943,6 +966,7 @@ pkg_solve_set_initial_assumption(struct pkg_solve_problem *problem,
	struct pkg_solve_item *item;
	struct pkg_solve_variable *var, *cvar;
	bool conservative = false, prefer_local = false;
+
	const char *assumed_reponame = NULL;

	if (problem->j->type == PKG_JOBS_INSTALL) {
		/* Avoid upgrades on INSTALL job */
@@ -963,6 +987,7 @@ pkg_solve_set_initial_assumption(struct pkg_solve_problem *problem,
		assert (rule->items != NULL);
		item = rule->items;
		var = item->var;
+
		assumed_reponame = var->assumed_reponame;

		/* Check what we are depending on */
		if (!(var->flags & (PKG_VAR_TOP|PKG_VAR_ASSUMED_TRUE))) {
@@ -992,6 +1017,7 @@ pkg_solve_set_initial_assumption(struct pkg_solve_problem *problem,
		while (var->prev->next != NULL) {
			var = var->prev;
		}
+

		LL_FOREACH(var, cvar) {
			if (cvar->flags & PKG_VAR_ASSUMED) {
				/* Do not reassume packages */
@@ -1013,7 +1039,11 @@ pkg_solve_set_initial_assumption(struct pkg_solve_problem *problem,
		}
		else {
			selected = pkg_jobs_universe_select_candidate(first, local,
-
					conservative);
+
					conservative, assumed_reponame);
+

+
			if (local && strcmp (selected->pkg->digest, local->pkg->digest) == 0) {
+
				selected = local;
+
			}
		}

		/* Now we can find the according var */
modified libpkg/private/pkg_jobs.h
@@ -246,7 +246,8 @@ pkg_jobs_universe_get_upgrade_candidates(struct pkg_jobs_universe *universe,
 */
struct pkg_job_universe_item *
pkg_jobs_universe_select_candidate(struct pkg_job_universe_item *chain,
-
	struct pkg_job_universe_item *local, bool conservative);
+
	struct pkg_job_universe_item *local, bool conservative,
+
	const char *reponame);

/*
 * Free job request (with all candidates)