Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Finalize the new conflicts logic.
Vsevolod Stakhov committed 12 years ago
commit 1694756d1c2cdc4549412c2222c45e271a95b8c2
parent cf231ae
5 files changed +90 -149
modified libpkg/pkg_conflicts.c
@@ -127,7 +127,7 @@ pkg_conflicts_request_resolve(struct pkg_jobs *j)
void
pkg_conflicts_register(struct pkg *p1, struct pkg *p2)
{
-
	struct pkg_conflict *c1, *c2;
+
	struct pkg_conflict *c1, *c2, *test;
	const char *o1, *o2;

	pkg_get(p1, PKG_ORIGIN, &o1);
@@ -136,11 +136,19 @@ pkg_conflicts_register(struct pkg *p1, struct pkg *p2)
	pkg_conflict_new(&c1);
	pkg_conflict_new(&c2);
	if (c1 != NULL && c2 != NULL) {
-
		sbuf_set(&c1->origin, o2);
-
		sbuf_set(&c2->origin, o1);
-
		pkg_debug(2, "registering conflict between %s and %s", o1, o2);
-
		HASH_ADD_KEYPTR(hh, p1->conflicts, pkg_conflict_origin(c1), sbuf_size(c1->origin), c1);
-
		HASH_ADD_KEYPTR(hh, p2->conflicts, pkg_conflict_origin(c2), sbuf_size(c2->origin), c2);
+
		HASH_FIND_STR(p1->conflicts, o2, test);
+
		if (test == NULL) {
+
			sbuf_set(&c1->origin, o2);
+
			HASH_ADD_KEYPTR(hh, p1->conflicts, pkg_conflict_origin(c1), sbuf_size(c1->origin), c1);
+
			pkg_debug(2, "registering conflict between %s and %s", o1, o2);
+
		}
+

+
		HASH_FIND_STR(p2->conflicts, o1, test);
+
		if (test == NULL) {
+
			sbuf_set(&c2->origin, o1);
+
			HASH_ADD_KEYPTR(hh, p2->conflicts, pkg_conflict_origin(c2), sbuf_size(c2->origin), c2);
+
			pkg_debug(2, "registering conflict between %s and %s", o2, o1);
+
		}
	}
}

modified libpkg/pkg_jobs.c
@@ -67,7 +67,7 @@ pkg_jobs_new(struct pkg_jobs **j, pkg_jobs_t t, struct pkgdb *db)

	(*j)->db = db;
	(*j)->type = t;
-
	(*j)->solved = false;
+
	(*j)->solved = 0;
	(*j)->flags = PKG_FLAG_NONE;

	return (EPKG_OK);
@@ -902,51 +902,54 @@ jobs_solve_install(struct pkg_jobs *j)
	struct pkgdb_it *it;
	const char *origin;

-
	if ((j->flags & PKG_FLAG_PKG_VERSION_TEST) == PKG_FLAG_PKG_VERSION_TEST)
+
	if ((j->flags & PKG_FLAG_PKG_VERSION_TEST) == PKG_FLAG_PKG_VERSION_TEST) {
		if (new_pkg_version(j)) {
			pkg_emit_newpkgversion();
			goto order;
		}
+
	}

-
	LL_FOREACH(j->patterns, jp) {
-
		if ((j->flags & PKG_FLAG_RECURSIVE) == PKG_FLAG_RECURSIVE) {
-
			if ((it = pkgdb_query(j->db, jp->pattern, jp->match)) == NULL)
-
				return (EPKG_FATAL);
+
	if (j->solved == 0) {
+
		LL_FOREACH(j->patterns, jp) {
+
			if ((j->flags & PKG_FLAG_RECURSIVE) == PKG_FLAG_RECURSIVE) {
+
				if ((it = pkgdb_query(j->db, jp->pattern, jp->match)) == NULL)
+
					return (EPKG_FATAL);

-
			pkg = NULL;
-
			while (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC|PKG_LOAD_RDEPS) == EPKG_OK) {
-
				pkg_jobs_add_universe(j, pkg, 0, true);
+
				pkg = NULL;
+
				while (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC|PKG_LOAD_RDEPS) == EPKG_OK) {
+
					pkg_jobs_add_universe(j, pkg, 0, true);

-
				if (pkg_is_locked(pkg)) {
-
					/* Keep locked packages to the local version */
-
					pkg_emit_locked(pkg);
-
				}
-
				else {
-
					pkg_get(pkg, PKG_ORIGIN, &origin);
-
					/* TODO: use repository priority here */
-
					if (find_remote_pkg(j, origin, MATCH_EXACT, true, 0) == EPKG_FATAL)
-
						pkg_emit_error("No packages matching '%s', has been found in the repositories", origin);
+
					if (pkg_is_locked(pkg)) {
+
						/* Keep locked packages to the local version */
+
						pkg_emit_locked(pkg);
+
					}
+
					else {
+
						pkg_get(pkg, PKG_ORIGIN, &origin);
+
						/* TODO: use repository priority here */
+
						if (find_remote_pkg(j, origin, MATCH_EXACT, true, 0) == EPKG_FATAL)
+
							pkg_emit_error("No packages matching '%s', has been found in the repositories", origin);
+
					}
+
					pkg = NULL;
				}
-
				pkg = NULL;
-
			}

-
			pkgdb_it_free(it);
-
		} else {
-
			if ((it = pkgdb_query(j->db, jp->pattern, jp->match)) == NULL)
-
				return (EPKG_FATAL);
-
			pkg = NULL;
-
			if (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) == EPKG_OK) {
-
				if (pkg_is_locked(pkg)) {
-
					pkg_emit_locked(pkg);
-
					pkgdb_it_free(it);
-
					return (EPKG_LOCKED);
+
				pkgdb_it_free(it);
+
			} else {
+
				if ((it = pkgdb_query(j->db, jp->pattern, jp->match)) == NULL)
+
					return (EPKG_FATAL);
+
				pkg = NULL;
+
				if (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) == EPKG_OK) {
+
					if (pkg_is_locked(pkg)) {
+
						pkg_emit_locked(pkg);
+
						pkgdb_it_free(it);
+
						return (EPKG_LOCKED);
+
					}
+
					pkg_jobs_add_universe(j, pkg, 0, true);
				}
-
				pkg_jobs_add_universe(j, pkg, 0, true);
+
				pkgdb_it_free(it);
+
				/* TODO: use repository priority here */
+
				if (find_remote_pkg(j, jp->pattern, jp->match, true, 0) == EPKG_FATAL)
+
					pkg_emit_error("No packages matching '%s' has been found in the repositories", jp->pattern);
			}
-
			pkgdb_it_free(it);
-
			/* TODO: use repository priority here */
-
			if (find_remote_pkg(j, jp->pattern, jp->match, true, 0) == EPKG_FATAL)
-
				pkg_emit_error("No packages matching '%s' has been found in the repositories", jp->pattern);
		}
	}

@@ -957,7 +960,7 @@ jobs_solve_install(struct pkg_jobs *j)

order:

-
	j->solved = true;
+
	j->solved ++;

	return (EPKG_OK);
}
@@ -998,7 +1001,7 @@ jobs_solve_fetch(struct pkg_jobs *j)
		}
	}

-
	j->solved = true;
+
	j->solved ++;

	return (EPKG_OK);
}
@@ -1091,7 +1094,7 @@ pkg_jobs_solve(struct pkg_jobs *j)
					if (!pkg_solve_sat_problem(problem)) {
						pkg_emit_error("cannot solve job using SAT solver");
						ret = EPKG_FATAL;
-
						j->solved = false;
+
						j->solved = 0;
					}
					else {
						ret = pkg_solve_sat_to_jobs(problem, j);
@@ -1101,7 +1104,7 @@ pkg_jobs_solve(struct pkg_jobs *j)
			else {
				pkg_emit_error("cannot convert job to SAT problem");
				ret = EPKG_FATAL;
-
				j->solved = false;
+
				j->solved = 0;
			}
		}
	}
@@ -1149,97 +1152,6 @@ pkg_jobs_handle_install(struct pkg_solved *ps, struct pkg_jobs *j, bool handle_r
			PKG_OLD_VERSION, &oldversion, PKG_AUTOMATIC, &automatic);
	an = pkg_annotation_lookup(p, "repository");

-
	/* XXX: remove this legacy */
-
#if 0
-
	struct pkg *pkg_temp = NULL;
-
	struct pkg *pkg = NULL;
-
	struct pkgdb_it *it = NULL;
-
	int lflags = PKG_LOAD_BASIC | PKG_LOAD_FILES | PKG_LOAD_SCRIPTS |
-
	    PKG_LOAD_DIRS;
-

-
	if (oldversion != NULL) {
-
		pkg = NULL;
-
		it = pkgdb_query(j->db, pkgorigin, MATCH_EXACT);
-
		if (it != NULL) {
-
			if (pkgdb_it_next(it, &pkg, lflags) == EPKG_OK) {
-
				if (pkg_is_locked(pkg)) {
-
					pkg_emit_locked(pkg);
-
					pkgdb_it_free(it);
-
					retcode = EPKG_LOCKED;
-
					pkgdb_transaction_rollback(j->db->sqlite, "upgrade");
-
					goto cleanup; /* Bail out */
-
				}
-

-
				LL_APPEND(pkg_queue, pkg);
-
				if ((j->flags & PKG_FLAG_NOSCRIPT) == 0)
-
					pkg_script_run(pkg,
-
							PKG_SCRIPT_PRE_DEINSTALL);
-
				pkg_get(pkg, PKG_ORIGIN, &origin);
-
				/*
-
				 * stop the different related services
-
				 * if the user wants that and the
-
				 * service is running
-
				 */
-
				if (handle_rc)
-
					pkg_start_stop_rc_scripts(pkg,
-
							PKG_RC_STOP);
-
				pkgdb_unregister_pkg(j->db, origin);
-
				pkg = NULL;
-
			}
-
			pkgdb_it_free(it);
-
		}
-
	}
-

-
	it = pkgdb_integrity_conflict_local(j->db, pkgorigin);
-

-
	if (it != NULL) {
-
		pkg = NULL;
-
		while (pkgdb_it_next(it, &pkg, lflags) == EPKG_OK) {
-

-
			if (pkg_is_locked(pkg)) {
-
				pkg_emit_locked(pkg);
-
				pkgdb_it_free(it);
-
				retcode = EPKG_LOCKED;
-
				pkgdb_transaction_rollback(j->db->sqlite, "upgrade");
-
				goto cleanup; /* Bail out */
-
			}
-

-
			LL_APPEND(pkg_queue, pkg);
-
			if ((j->flags & PKG_FLAG_NOSCRIPT) == 0)
-
				pkg_script_run(pkg,
-
						PKG_SCRIPT_PRE_DEINSTALL);
-
			pkg_get(pkg, PKG_ORIGIN, &origin);
-
			/*
-
			 * stop the different related services if the
-
			 * user wants that and the service is running
-
			 */
-
			if (handle_rc)
-
				pkg_start_stop_rc_scripts(pkg,
-
						PKG_RC_STOP);
-
			pkgdb_unregister_pkg(j->db, origin);
-
			pkg = NULL;
-
		}
-
		pkgdb_it_free(it);
-
	}
-

-
	LL_FOREACH(pkg_queue, pkg) {
-
		pkg_jobs_keep_files_to_del(pkg, newpkg);
-
	}
-

-
	LL_FOREACH_SAFE(pkg_queue, pkg, pkg_temp) {
-
		pkg_get(pkg, PKG_ORIGIN, &origin);
-
		if (strcmp(pkgorigin, origin) == 0) {
-
			LL_DELETE(pkg_queue, pkg);
-
			pkg_delete_files(pkg, 1);
-
			if ((j->flags & PKG_FLAG_NOSCRIPT) == 0)
-
				pkg_script_run(pkg,
-
						PKG_SCRIPT_POST_DEINSTALL);
-
			pkg_delete_dirs(j->db, pkg, 0);
-
			pkg_free(pkg);
-
			break;
-
		}
-
	}
-
#endif
	pkg_snprintf(path, sizeof(path), "%S/%R", cachedir, p);

	if (pkg_open(&newpkg, path, keys, 0) != EPKG_OK) {
@@ -1375,19 +1287,31 @@ pkg_jobs_apply(struct pkg_jobs *j)

	switch (j->type) {
	case PKG_JOBS_INSTALL:
-
		pkg_plugins_hook_run(PKG_PLUGIN_HOOK_PRE_INSTALL, j, j->db);
		rc = pkg_jobs_fetch(j);
		if (rc == EPKG_OK) {
-
			rc = pkg_jobs_check_conflicts(j);
+
			/* Check local conflicts in the first run */
+
			if (j->solved > 1) {
+
				rc = EPKG_OK;
+
			}
+
			else {
+
				rc = pkg_jobs_check_conflicts(j);
+
			}
			if (rc == EPKG_OK) {
+
				pkg_plugins_hook_run(PKG_PLUGIN_HOOK_PRE_INSTALL, j, j->db);
				rc = pkg_jobs_install(j);
			}
			else if (rc == EPKG_CONFLICT) {
-
				j->solved = false;
+
				/* Cleanup results */
+
				LL_FREE(j->jobs_add, pkg_solved, free);
+
				LL_FREE(j->jobs_delete, pkg_solved, free);
+
				LL_FREE(j->jobs_upgrade, pkg_solved, free);
+
				j->jobs_add = j->jobs_delete = j->jobs_upgrade = NULL;
+

				rc = pkg_jobs_solve(j);
				if (rc == EPKG_OK) {
-
					/* XXX: is it safe to do this recursion */
-
					return (pkg_jobs_apply(j));
+
					pkg_emit_notice("The conflicts with the existing packages have been found.\n"
+
							"We need to run one more solver iteration to resolve them");
+
					return (EPKG_CONFLICT);
				}
			}
		}
modified libpkg/pkgdb.c
@@ -3958,7 +3958,7 @@ pkgdb_integrity_check(struct pkgdb *db, conflict_func_cb cb, void *cbdata)
	sbuf_delete(conflictmsg);
	sbuf_delete(origin);

-
/*	sql_exec(db->sqlite, "DROP TABLE IF EXISTS integritycheck");*/
+
	/* sql_exec(db->sqlite, "DROP TABLE IF EXISTS integritycheck"); */

	return (retcode);
}
modified libpkg/private/pkg.h
@@ -233,7 +233,7 @@ struct pkg_jobs {
	struct pkgdb	*db;
	pkg_jobs_t	 type;
	pkg_flags	 flags;
-
	bool		 solved;
+
	int		 solved;
	int count;
	const char *	 reponame;
	struct job_pattern *patterns;
modified pkg/install.c
@@ -59,15 +59,16 @@ exec_install(int argc, char **argv)
	int retcode;
	int updcode = EPKG_OK;
	int ch;
-
	bool yes;
+
	bool yes, yes_arg;
	bool auto_update;
	match_t match = MATCH_EXACT;
	bool dry_run = false;
	nbactions = nbdone = 0;
	pkg_flags f = PKG_FLAG_NONE | PKG_FLAG_PKG_VERSION_TEST;

-
	pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);
+
	pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes_arg);
	pkg_config_bool(PKG_CONFIG_REPO_AUTOUPDATE, &auto_update);
+
	yes = yes_arg;

	while ((ch = getopt(argc, argv, "AfgIiFnqRr:Uxy")) != -1) {
		switch (ch) {
@@ -109,7 +110,7 @@ exec_install(int argc, char **argv)
			match = MATCH_REGEX;
			break;
		case 'y':
-
			yes = true;
+
			yes_arg = true;
			break;
		default:
			usage_install();
@@ -171,8 +172,9 @@ exec_install(int argc, char **argv)
	if (pkg_jobs_solve(jobs) != EPKG_OK)
		goto cleanup;

-
	if ((nbactions = pkg_jobs_count(jobs)) > 0) {
+
	while ((nbactions = pkg_jobs_count(jobs)) > 0) {
		/* print a summary before applying the jobs */
+
		yes = yes_arg;
		if (!quiet || dry_run) {
			print_jobs_summary(jobs,
			    "The following %d packages will be installed:\n\n",
@@ -185,13 +187,20 @@ exec_install(int argc, char **argv)
				yes = false;
		}

-
		if (yes && pkg_jobs_apply(jobs) != EPKG_OK)
-
			goto cleanup;
+
		if (yes) {
+
			retcode = pkg_jobs_apply(jobs);
+
			if (retcode == EPKG_CONFLICT) {
+
				continue;
+
			}
+
			else if (retcode != EPKG_OK)
+
				goto cleanup;
+
		}

		if (messages != NULL) {
			sbuf_finish(messages);
			printf("%s", sbuf_data(messages));
		}
+
		break;
	}

	retcode = EX_OK;