diff --git a/src/apk_solver.h b/src/apk_solver.h index b8b072d..0565c26 100644 --- a/src/apk_solver.h +++ b/src/apk_solver.h @@ -35,6 +35,7 @@ struct apk_changeset { #define APK_SOLVERF_REINSTALL 0x0004 #define APK_SOLVERF_LATEST 0x0008 #define APK_SOLVERF_IGNORE_CONFLICT 0x0010 +#define APK_SOLVERF_IGNORE_UPGRADE 0x0020 void apk_solver_set_name_flags(struct apk_name *name, unsigned short solver_flags, diff --git a/src/apk_solver_data.h b/src/apk_solver_data.h index 43b7a1b..34ce812 100644 --- a/src/apk_solver_data.h +++ b/src/apk_solver_data.h @@ -49,8 +49,8 @@ struct apk_solver_package_state { unsigned short max_dep_chain; unsigned short pinning_allowed; unsigned short pinning_preferred; - unsigned solver_flags : 4; - unsigned solver_flags_inheritable : 4; + unsigned solver_flags : 6; + unsigned solver_flags_inheritable : 6; unsigned seen : 1; unsigned pkg_available : 1; unsigned pkg_selectable : 1; diff --git a/src/solver.c b/src/solver.c index 2121dd9..25ea471 100644 --- a/src/solver.c +++ b/src/solver.c @@ -551,7 +551,8 @@ static int compare_providers(struct apk_solver_state *ss, return r; /* Prefer installed on self-upgrade */ - if (db->performing_self_upgrade && !(solver_flags & APK_SOLVERF_UPGRADE)) { + if ((db->performing_self_upgrade && !(solver_flags & APK_SOLVERF_UPGRADE)) || + (solver_flags & APK_SOLVERF_IGNORE_UPGRADE)) { r = (pkgA->ipkg != NULL) - (pkgB->ipkg != NULL); if (r) return r; @@ -580,7 +581,8 @@ static int compare_providers(struct apk_solver_state *ss, return r; /* Prefer installed */ - if (!(solver_flags & APK_SOLVERF_UPGRADE)) { + if (!(solver_flags & APK_SOLVERF_UPGRADE) || + (solver_flags & APK_SOLVERF_IGNORE_UPGRADE)) { r = (pkgA->ipkg != NULL) - (pkgB->ipkg != NULL); if (r) return r; diff --git a/src/upgrade.c b/src/upgrade.c index 6c3eafa..d1ec36c 100644 --- a/src/upgrade.c +++ b/src/upgrade.c @@ -22,6 +22,7 @@ struct upgrade_ctx { unsigned short solver_flags; int no_self_upgrade : 1; int self_upgrade_only : 1; + int ignore : 1; }; static int option_parse_applet(void *ctx, struct apk_db_options *dbopts, int optch, const char *optarg) @@ -35,6 +36,9 @@ static int option_parse_applet(void *ctx, struct apk_db_options *dbopts, int opt case 0x10001: uctx->self_upgrade_only = 1; break; + case 0x10002: + uctx->ignore = 1; + break; case 'a': uctx->solver_flags |= APK_SOLVERF_AVAILABLE; break; @@ -59,6 +63,8 @@ static const struct apk_option options_applet[] = { { 0x10000, "no-self-upgrade", "Do not do early upgrade of 'apk-tools' package" }, { 0x10001, "self-upgrade-only", "Only do self-upgrade" }, + { 0x10002, "ignore", "Ignore the upgrade of PACKAGE. Partial " + "upgrades not supported, this might break your system."}, }; static const struct apk_option_group optgroup_applet = { @@ -158,6 +164,15 @@ static int upgrade_main(void *ctx, struct apk_database *db, struct apk_string_ar if (uctx->self_upgrade_only) return 0; + if (uctx->ignore) { + char **pkg_name; + struct apk_name *name; + foreach_array_item(pkg_name, args) { + name = apk_db_get_name(db, APK_BLOB_STR(*pkg_name)); + apk_solver_set_name_flags(name, solver_flags | APK_SOLVERF_IGNORE_UPGRADE, 0); + } + } + if (solver_flags & APK_SOLVERF_AVAILABLE) { apk_dependency_array_copy(&world, db->world); foreach_array_item(dep, world) { diff --git a/test/upgrade2.test b/test/upgrade2.test new file mode 100644 index 0000000..0bbd262 --- /dev/null +++ b/test/upgrade2.test @@ -0,0 +1,7 @@ +@ARGS +--test-repo upgrade.repo +--test-instdb upgrade.installed +--test-world app +upgrade --ignore app +@EXPECT +OK: 0 MiB in 2 packages