solver: add per-name specific flags, and fix the fix applet
parent
b42421722e
commit
c6d9962d81
|
@ -19,7 +19,7 @@ $(error Build dependencies are not met)
|
|||
endif
|
||||
|
||||
progs-y += apk
|
||||
apk-objs := apk.o add.o del.o update.o info.o \
|
||||
apk-objs := apk.o add.o del.o fix.o update.o info.o \
|
||||
search.o upgrade.o cache.o ver.o index.o fetch.o \
|
||||
audit.o verify.o dot.o
|
||||
|
||||
|
|
14
src/add.c
14
src/add.c
|
@ -112,15 +112,19 @@ static int add_main(void *ctx, struct apk_database *db, int argc, char **argv)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (virtpkg)
|
||||
apk_deps_add(&virtpkg->depends, &dep);
|
||||
else
|
||||
if (virtpkg == NULL) {
|
||||
apk_deps_add(&world, &dep);
|
||||
apk_solver_set_name_flags(dep.name, actx->solver_flags);
|
||||
} else {
|
||||
apk_deps_add(&virtpkg->depends, &dep);
|
||||
}
|
||||
}
|
||||
if (virtpkg)
|
||||
if (virtpkg) {
|
||||
apk_deps_add(&world, &virtdep);
|
||||
apk_solver_set_name_flags(virtdep.name, actx->solver_flags);
|
||||
}
|
||||
|
||||
r = apk_solver_commit(db, actx->solver_flags, world);
|
||||
r = apk_solver_commit(db, 0, world);
|
||||
apk_dependency_array_free(&world);
|
||||
|
||||
return r;
|
||||
|
|
|
@ -26,6 +26,8 @@ struct apk_changeset {
|
|||
#define APK_SOLVERF_AVAILABLE 0x0002
|
||||
#define APK_SOLVERF_REINSTALL 0x0004
|
||||
|
||||
void apk_solver_set_name_flags(struct apk_name *name,
|
||||
unsigned short solver_flags);
|
||||
int apk_solver_solve(struct apk_database *db,
|
||||
unsigned short solver_flags,
|
||||
struct apk_dependency_array *world,
|
||||
|
|
38
src/fix.c
38
src/fix.c
|
@ -13,13 +13,13 @@
|
|||
#include <stdio.h>
|
||||
#include "apk_applet.h"
|
||||
#include "apk_database.h"
|
||||
#include "apk_state.h"
|
||||
#include "apk_print.h"
|
||||
#include "apk_solver.h"
|
||||
|
||||
/* FIXME: reimplement fix applet */
|
||||
|
||||
struct fix_ctx {
|
||||
unsigned int reinstall : 1;
|
||||
unsigned short solver_flags;
|
||||
};
|
||||
|
||||
static int fix_parse(void *pctx, struct apk_db_options *dbopts,
|
||||
|
@ -28,10 +28,10 @@ static int fix_parse(void *pctx, struct apk_db_options *dbopts,
|
|||
struct fix_ctx *ctx = (struct fix_ctx *) pctx;
|
||||
switch (optch) {
|
||||
case 'u':
|
||||
apk_flags |= APK_UPGRADE;
|
||||
ctx->solver_flags |= APK_SOLVERF_UPGRADE;
|
||||
break;
|
||||
case 'r':
|
||||
ctx->reinstall = 1;
|
||||
ctx->solver_flags |= APK_SOLVERF_REINSTALL;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
|
@ -42,17 +42,13 @@ static int fix_parse(void *pctx, struct apk_db_options *dbopts,
|
|||
static int fix_main(void *pctx, struct apk_database *db, int argc, char **argv)
|
||||
{
|
||||
struct fix_ctx *ctx = (struct fix_ctx *) pctx;
|
||||
struct apk_state *state = NULL;
|
||||
struct apk_name *name;
|
||||
struct apk_package *pkg;
|
||||
struct apk_dependency *deps;
|
||||
int r = 0, i, j;
|
||||
|
||||
state = apk_state_new(db);
|
||||
if (state == NULL)
|
||||
return -1;
|
||||
if (!ctx->solver_flags)
|
||||
ctx->solver_flags = APK_SOLVERF_REINSTALL;
|
||||
|
||||
deps = alloca(sizeof(struct apk_dependency) * argc);
|
||||
for (i = 0; i < argc; i++) {
|
||||
pkg = NULL;
|
||||
if (strstr(argv[i], ".apk") != NULL) {
|
||||
|
@ -66,12 +62,9 @@ static int fix_main(void *pctx, struct apk_database *db, int argc, char **argv)
|
|||
apk_error("%s: %s", argv[i], apk_error_str(r));
|
||||
goto err;
|
||||
}
|
||||
apk_dep_from_pkg(&deps[i], db, pkg);
|
||||
name = deps[i].name;
|
||||
name = pkg->name;
|
||||
} else {
|
||||
apk_dep_from_blob(&deps[i], db, APK_BLOB_STR(argv[i]));
|
||||
name = deps[i].name;
|
||||
|
||||
name = apk_db_get_name(db, APK_BLOB_STR(argv[i]));
|
||||
for (j = 0; j < name->pkgs->num; j++) {
|
||||
if (name->pkgs->item[j]->ipkg != NULL) {
|
||||
pkg = name->pkgs->item[j];
|
||||
|
@ -83,22 +76,11 @@ static int fix_main(void *pctx, struct apk_database *db, int argc, char **argv)
|
|||
apk_error("%s is not installed", name->name);
|
||||
goto err;
|
||||
}
|
||||
if (ctx->reinstall)
|
||||
name->flags |= APK_NAME_REINSTALL;
|
||||
apk_solver_set_name_flags(name, ctx->solver_flags);
|
||||
}
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
r |= apk_state_lock_dependency(state, &deps[i]);
|
||||
|
||||
if (r == 0 || (apk_flags & APK_FORCE))
|
||||
r = apk_state_commit(state);
|
||||
else
|
||||
apk_state_print_errors(state);
|
||||
r = apk_solver_commit(db, 0, db->world);
|
||||
err:
|
||||
if (r != 0 && i < argc)
|
||||
apk_error("Error while processing '%s'", argv[i]);
|
||||
if (state != NULL)
|
||||
apk_state_unref(state);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
43
src/solver.c
43
src/solver.c
|
@ -215,10 +215,10 @@ static void prepare_name(struct apk_solver_state *ss, struct apk_name *name,
|
|||
|
||||
/* if package is needed for (re-)install */
|
||||
if ((pkg->ipkg == NULL) ||
|
||||
(ns->solver_flags & APK_SOLVERF_REINSTALL)) {
|
||||
((ns->solver_flags | ss->solver_flags) & APK_SOLVERF_REINSTALL)) {
|
||||
/* and it's not available, we can't use it */
|
||||
if (!pkg_available(ss->db, pkg))
|
||||
ps->conflicts++;
|
||||
ps->conflicts = 1024;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -236,6 +236,7 @@ static void foreach_dependency(struct apk_solver_state *ss, struct apk_dependenc
|
|||
static int get_pkg_expansion_flags(struct apk_solver_state *ss, struct apk_package *pkg)
|
||||
{
|
||||
struct apk_name *name = pkg->name;
|
||||
struct apk_name_state *ns = name_to_ns(name);
|
||||
int i, options = 0;
|
||||
|
||||
/* check if the suggested package is the most preferred one of
|
||||
|
@ -250,7 +251,9 @@ static int get_pkg_expansion_flags(struct apk_solver_state *ss, struct apk_packa
|
|||
ps0->conflicts != 0)
|
||||
continue;
|
||||
|
||||
if (ss->solver_flags & APK_SOLVERF_AVAILABLE) {
|
||||
options++;
|
||||
|
||||
if ((ns->solver_flags | ss->solver_flags) & APK_SOLVERF_AVAILABLE) {
|
||||
/* pkg available, pkg0 not */
|
||||
if (pkg->repos != 0 && pkg0->repos == 0)
|
||||
continue;
|
||||
|
@ -259,16 +262,19 @@ static int get_pkg_expansion_flags(struct apk_solver_state *ss, struct apk_packa
|
|||
return APK_PKGSTF_NOINSTALL | APK_PKGSTF_BRANCH;
|
||||
}
|
||||
|
||||
if (!(ss->solver_flags & APK_SOLVERF_UPGRADE)) {
|
||||
/* not upgrading, prefer the installed package */
|
||||
if (pkg->ipkg == NULL && pkg0->ipkg != NULL)
|
||||
if ((ns->solver_flags | ss->solver_flags) & APK_SOLVERF_UPGRADE) {
|
||||
/* upgrading, or neither of the package is installed, so
|
||||
* we just fall back comparing to versions */
|
||||
switch (apk_pkg_version_compare(pkg0, pkg)) {
|
||||
case APK_VERSION_GREATER:
|
||||
return APK_PKGSTF_NOINSTALL | APK_PKGSTF_BRANCH;
|
||||
case APK_VERSION_LESS:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* upgrading, or neither of the package is installed, so
|
||||
* we just fall back comparing to versions */
|
||||
options++;
|
||||
if (apk_pkg_version_compare(pkg0, pkg) == APK_VERSION_GREATER)
|
||||
/* not upgrading, prefer the installed package */
|
||||
if (pkg->ipkg == NULL && pkg0->ipkg != NULL)
|
||||
return APK_PKGSTF_NOINSTALL | APK_PKGSTF_BRANCH;
|
||||
}
|
||||
|
||||
|
@ -670,7 +676,8 @@ static int compare_change(const void *p1, const void *p2)
|
|||
|
||||
static int generate_changeset(struct apk_database *db,
|
||||
struct apk_package_array *solution,
|
||||
struct apk_changeset *changeset)
|
||||
struct apk_changeset *changeset,
|
||||
unsigned short solver_flags)
|
||||
{
|
||||
struct apk_name *name;
|
||||
struct apk_name_state *ns;
|
||||
|
@ -682,7 +689,7 @@ static int generate_changeset(struct apk_database *db,
|
|||
for (i = 0; i < solution->num; i++) {
|
||||
pkg = solution->item[i];
|
||||
if ((pkg->ipkg == NULL) ||
|
||||
(name_to_ns(pkg->name)->solver_flags & APK_SOLVERF_REINSTALL))
|
||||
((solver_flags | name_to_ns(pkg->name)->solver_flags) & APK_SOLVERF_REINSTALL))
|
||||
num_installs++;
|
||||
}
|
||||
list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) {
|
||||
|
@ -707,7 +714,7 @@ static int generate_changeset(struct apk_database *db,
|
|||
name = pkg->name;
|
||||
|
||||
if ((pkg->ipkg == NULL) ||
|
||||
(name_to_ns(name)->solver_flags & APK_SOLVERF_REINSTALL)) {
|
||||
((solver_flags | name_to_ns(name)->solver_flags) & APK_SOLVERF_REINSTALL)) {
|
||||
for (j = 0; j < name->pkgs->num; j++) {
|
||||
pkg0 = name->pkgs->item[j];
|
||||
if (pkg0->ipkg == NULL)
|
||||
|
@ -738,6 +745,13 @@ static int free_state(apk_hash_item item, void *ctx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void apk_solver_set_name_flags(struct apk_name *name,
|
||||
unsigned short solver_flags)
|
||||
{
|
||||
struct apk_name_state *ns = name_to_ns(name);
|
||||
ns->solver_flags = solver_flags;
|
||||
}
|
||||
|
||||
int apk_solver_solve(struct apk_database *db,
|
||||
unsigned short solver_flags,
|
||||
struct apk_dependency_array *world,
|
||||
|
@ -787,7 +801,8 @@ int apk_solver_solve(struct apk_database *db,
|
|||
if (r == 0 && ss->cur_unsatisfiable == 0) {
|
||||
record_solution(ss);
|
||||
if (changeset != NULL)
|
||||
generate_changeset(db, ss->best_solution, changeset);
|
||||
generate_changeset(db, ss->best_solution, changeset,
|
||||
ss->solver_flags);
|
||||
r = 0;
|
||||
} else {
|
||||
qsort(ss->best_solution->item, ss->best_solution->num,
|
||||
|
|
Loading…
Reference in New Issue