diff --git a/doc/pacman.8.asciidoc b/doc/pacman.8.asciidoc index dea237cb..3a3ae81c 100644 --- a/doc/pacman.8.asciidoc +++ b/doc/pacman.8.asciidoc @@ -292,6 +292,9 @@ Upgrade Options (apply to '-S' and '-U')[[UO]] exclamation mark. Subsequent matches will override previous ones. A leading literal exclamation mark or backslash needs to be escaped. +*\--preremove :: + Uninstall 'package' before performing the requested installation. Multiple + packages can be specified by separating them with commas. Query Options (apply to '-Q')[[QO]] ----------------------------------- diff --git a/src/pacman/conf.c b/src/pacman/conf.c index a0e0e96a..1141a423 100644 --- a/src/pacman/conf.c +++ b/src/pacman/conf.c @@ -150,6 +150,7 @@ int config_free(config_t *oldconfig) FREELIST(oldconfig->noupgrade); FREELIST(oldconfig->noextract); FREELIST(oldconfig->overwrite_files); + FREELIST(oldconfig->preremove); free(oldconfig->configfile); free(oldconfig->sysroot); free(oldconfig->rootdir); diff --git a/src/pacman/conf.h b/src/pacman/conf.h index 2c4fddf0..d78b6937 100644 --- a/src/pacman/conf.h +++ b/src/pacman/conf.h @@ -134,6 +134,8 @@ typedef struct __config_t { /* our connection to libalpm */ alpm_handle_t *handle; + alpm_list_t *preremove; + alpm_list_t *explicit_adds; alpm_list_t *explicit_removes; @@ -214,7 +216,8 @@ enum { OP_REFRESH, OP_ASSUMEINSTALLED, OP_DISABLEDLTIMEOUT, - OP_DISABLESANDBOX + OP_DISABLESANDBOX, + OP_PREREMOVE, }; /* clean method */ diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index 2866fc98..65691c4b 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -196,6 +196,8 @@ static void usage(int op, const char * const myname) addlist(_(" --ignore ignore a package upgrade (can be used more than once)\n")); addlist(_(" --ignoregroup \n" " ignore a group upgrade (can be used more than once)\n")); + addlist(_(" --preremove \n")); + addlist(_(" uninstall before performing installation\n")); __attribute__((fallthrough)); case PM_OP_REMOVE: addlist(_(" -d, --nodeps skip dependency version checks (-dd to skip all checks)\n")); @@ -770,6 +772,9 @@ static int parsearg_upgrade(int opt) case OP_IGNOREGROUP: parsearg_util_addlist(&(config->ignoregrp)); break; + case OP_PREREMOVE: + parsearg_util_addlist(&(config->preremove)); + break; case OP_DOWNLOADONLY: case 'w': config->op_s_downloadonly = 1; @@ -982,6 +987,7 @@ static int parseargs(int argc, char *argv[]) {"color", required_argument, 0, OP_COLOR}, {"disable-download-timeout", no_argument, 0, OP_DISABLEDLTIMEOUT}, {"disable-sandbox", no_argument, 0, OP_DISABLESANDBOX}, + {"preremove", required_argument, 0, OP_PREREMOVE}, {0, 0, 0, 0} }; diff --git a/src/pacman/sync.c b/src/pacman/sync.c index a3797e85..72a99efb 100644 --- a/src/pacman/sync.c +++ b/src/pacman/sync.c @@ -717,6 +717,21 @@ static int sync_trans(alpm_list_t *targets) } } + for(i = config->preremove; i; i = i->next) { + alpm_pkg_t *pkg; + const char *pname = i->data; + alpm_db_t *db_local = alpm_get_localdb(config->handle); + + if((pkg = alpm_db_get_pkg(db_local, pname)) != NULL) { + if(alpm_remove_pkg(config->handle, pkg) == -1) { + alpm_errno_t err = alpm_errno(config->handle); + pm_printf(ALPM_LOG_ERROR, "'%s': %s\n", pname, alpm_strerror(err)); + retval = 1; + } + config->explicit_removes = alpm_list_add(config->explicit_removes, pkg); + } + } + if(retval) { trans_release(); return retval;