diff options
-rw-r--r-- | src/apk_defines.h | 1 | ||||
-rw-r--r-- | src/del.c | 20 | ||||
-rw-r--r-- | src/state.c | 36 |
3 files changed, 46 insertions, 11 deletions
diff --git a/src/apk_defines.h b/src/apk_defines.h index 0dc0c20..27d4ee4 100644 --- a/src/apk_defines.h +++ b/src/apk_defines.h @@ -62,6 +62,7 @@ extern unsigned int apk_flags; #define APK_ALLOW_UNTRUSTED 0x0100 #define APK_PURGE 0x0200 #define APK_INTERACTIVE 0x0400 +#define APK_RECURSIVE_DELETE 0x0800 #define apk_error(args...) do { apk_log("ERROR: ", args); } while (0) #define apk_warning(args...) do { if (apk_verbosity > 0) { apk_log("WARNING: ", args); } } while (0) @@ -14,6 +14,18 @@ #include "apk_state.h" #include "apk_database.h" +static int del_parse(void *ctx, int optch, int optindex, const char *optarg) +{ + switch (optch) { + case 'r': + apk_flags |= APK_RECURSIVE_DELETE; + break; + default: + return -1; + } + return 0; +} + static int del_main(void *ctx, int argc, char **argv) { struct apk_database db; @@ -58,10 +70,18 @@ out: return r; } +static struct apk_option del_options[] = { + { 'r', "rdepends", "Recursively delete all top-level reverse " + "dependencies too." }, +}; + static struct apk_applet apk_del = { .name = "del", .help = "Remove PACKAGEs from the main dependencies and uninstall them.", .arguments = "PACKAGE...", + .num_options = ARRAY_SIZE(del_options), + .options = del_options, + .parse = del_parse, .main = del_main, }; diff --git a/src/state.c b/src/state.c index c539b02..82e3f17 100644 --- a/src/state.c +++ b/src/state.c @@ -406,14 +406,6 @@ int apk_state_lock_name(struct apk_state *state, if (name->id >= state->num_names) return -1; - if (newpkg == NULL && - (name->flags & APK_NAME_TOPLEVEL) && - !(apk_flags & APK_FORCE)) { - apk_error("Not deleting top level dependency '%s'. " - "Use -f to override.", name->name); - return -1; - } - ns_free(state->name[name->id]); state->name[name->id] = ns_from_pkg(newpkg); @@ -651,14 +643,17 @@ int apk_state_commit(struct apk_state *state, { struct progress prog; struct apk_change *change; - int size_diff = 0; - int r; + int r = 0, size_diff = 0, toplevel = FALSE, deleteonly = TRUE; /* Count what needs to be done */ memset(&prog, 0, sizeof(prog)); list_for_each_entry(change, &state->change_list_head, change_list) { - if (change->newpkg == NULL) + if (change->newpkg == NULL) { apk_state_autoclean(state, change->oldpkg); + if (change->oldpkg->name->flags & APK_NAME_TOPLEVEL) + toplevel = TRUE; + } else + deleteonly = FALSE; apk_count_change(change, &prog.total); if (change->newpkg) size_diff += change->newpkg->installed_size; @@ -667,6 +662,17 @@ int apk_state_commit(struct apk_state *state, } size_diff /= 1024; + if (toplevel && + (apk_flags & (APK_INTERACTIVE | APK_RECURSIVE_DELETE)) == 0) { + if (!deleteonly) + return -1; + + dump_packages(state, cmp_remove, + "The top-level dependencies have been updated " + "but the following packages are not removed"); + goto update_state; + } + if (apk_verbosity > 1 || (apk_flags & APK_INTERACTIVE)) { r = dump_packages(state, cmp_remove, "The following packages will be REMOVED"); @@ -704,6 +710,13 @@ int apk_state_commit(struct apk_state *state, &prog); if (r != 0) break; + + if (change->oldpkg != NULL && + change->newpkg == NULL && + change->oldpkg->name->flags & APK_NAME_TOPLEVEL) { + change->oldpkg->name->flags &= ~APK_NAME_TOPLEVEL; + apk_deps_del(&db->world, change->oldpkg->name); + } } apk_count_change(change, &prog.done); @@ -711,6 +724,7 @@ int apk_state_commit(struct apk_state *state, if (apk_flags & APK_PROGRESS) apk_draw_progress(20, 1); +update_state: if (!(apk_flags & APK_SIMULATE)) apk_db_write_config(db); |