Add --assume-installed option

This allows to ignore specific dependencies.

Signed-off-by: Florian Pritz <bluewind@xinu.at>
This commit is contained in:
Florian Pritz 2014-07-04 23:12:01 +02:00 committed by Allan McRae
parent 4e263f24c6
commit 04e8048725
12 changed files with 152 additions and 3 deletions

View file

@ -186,6 +186,12 @@ Transaction Options (apply to '-S', '-R' and '-U')
dependencies are installed and there are no package conflicts in the dependencies are installed and there are no package conflicts in the
system. Specify this option twice to skip all dependency checks. system. Specify this option twice to skip all dependency checks.
*\--assume-installed* <package=version>::
Add a virtual package "package" with version "version" to the transaction
to satisfy dependencies. This allows to disable specific dependency checks
without affecting all dependency checks. To disable all dependency
checking, see the '\--nodeps' option.
*\--dbonly*:: *\--dbonly*::
Adds/removes the database entry only, leaving all files in place. Adds/removes the database entry only, leaving all files in place.

View file

@ -851,6 +851,17 @@ int alpm_option_set_ignoregroups(alpm_handle_t *handle, alpm_list_t *ignoregrps)
int alpm_option_remove_ignoregroup(alpm_handle_t *handle, const char *grp); int alpm_option_remove_ignoregroup(alpm_handle_t *handle, const char *grp);
/** @} */ /** @} */
/** @name Accessors to the list of ignored dependencies.
* These functions modify the list of dependencies that
* should be ignored by a sysupgrade.
* @{
*/
alpm_list_t *alpm_option_get_assumeinstalled(alpm_handle_t *handle);
int alpm_option_add_assumeinstalled(alpm_handle_t *handle, const alpm_depend_t *dep);
int alpm_option_set_assumeinstalled(alpm_handle_t *handle, alpm_list_t *deps);
int alpm_option_remove_assumeinstalled(alpm_handle_t *handle, const alpm_depend_t *dep);
/** @} */
/** Returns the targeted architecture. */ /** Returns the targeted architecture. */
const char *alpm_option_get_arch(alpm_handle_t *handle); const char *alpm_option_get_arch(alpm_handle_t *handle);
/** Sets the targeted architecture. */ /** Sets the targeted architecture. */

View file

@ -333,8 +333,10 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_handle_t *handle,
} }
/* 1. we check the upgrade list */ /* 1. we check the upgrade list */
/* 2. we check database for untouched satisfying packages */ /* 2. we check database for untouched satisfying packages */
/* 3. we check the dependency ignore list */
if(!find_dep_satisfier(upgrade, depend) && if(!find_dep_satisfier(upgrade, depend) &&
!find_dep_satisfier(dblist, depend)) { !find_dep_satisfier(dblist, depend) &&
!_alpm_depcmp_provides(depend, handle->assumeinstalled)) {
/* Unsatisfied dependency in the upgrade list */ /* Unsatisfied dependency in the upgrade list */
alpm_depmissing_t *miss; alpm_depmissing_t *miss;
char *missdepstring = alpm_dep_compute_string(depend); char *missdepstring = alpm_dep_compute_string(depend);
@ -363,9 +365,11 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_handle_t *handle,
/* we won't break this depend, if it is already broken, we ignore it */ /* we won't break this depend, if it is already broken, we ignore it */
/* 1. check upgrade list for satisfiers */ /* 1. check upgrade list for satisfiers */
/* 2. check dblist for satisfiers */ /* 2. check dblist for satisfiers */
/* 3. we check the dependency ignore list */
if(causingpkg && if(causingpkg &&
!find_dep_satisfier(upgrade, depend) && !find_dep_satisfier(upgrade, depend) &&
!find_dep_satisfier(dblist, depend)) { !find_dep_satisfier(dblist, depend) &&
!_alpm_depcmp_provides(depend, handle->assumeinstalled)) {
alpm_depmissing_t *miss; alpm_depmissing_t *miss;
char *missdepstring = alpm_dep_compute_string(depend); char *missdepstring = alpm_dep_compute_string(depend);
_alpm_log(handle, ALPM_LOG_DEBUG, "checkdeps: transaction would break '%s' dependency of '%s'\n", _alpm_log(handle, ALPM_LOG_DEBUG, "checkdeps: transaction would break '%s' dependency of '%s'\n",

View file

@ -37,6 +37,7 @@
#include "delta.h" #include "delta.h"
#include "trans.h" #include "trans.h"
#include "alpm.h" #include "alpm.h"
#include "deps.h"
alpm_handle_t *_alpm_handle_new(void) alpm_handle_t *_alpm_handle_new(void)
{ {
@ -85,6 +86,10 @@ void _alpm_handle_free(alpm_handle_t *handle)
FREELIST(handle->noextract); FREELIST(handle->noextract);
FREELIST(handle->ignorepkg); FREELIST(handle->ignorepkg);
FREELIST(handle->ignoregroup); FREELIST(handle->ignoregroup);
alpm_list_free_inner(handle->assumeinstalled, (alpm_list_fn_free)alpm_dep_free);
alpm_list_free(handle->assumeinstalled);
FREE(handle); FREE(handle);
} }
@ -251,6 +256,12 @@ alpm_list_t SYMEXPORT *alpm_option_get_ignoregroups(alpm_handle_t *handle)
return handle->ignoregroup; return handle->ignoregroup;
} }
alpm_list_t SYMEXPORT *alpm_option_get_assumeinstalled(alpm_handle_t *handle)
{
CHECK_HANDLE(handle, return NULL);
return handle->assumeinstalled;
}
const char SYMEXPORT *alpm_option_get_arch(alpm_handle_t *handle) const char SYMEXPORT *alpm_option_get_arch(alpm_handle_t *handle)
{ {
CHECK_HANDLE(handle, return NULL); CHECK_HANDLE(handle, return NULL);
@ -557,6 +568,51 @@ int SYMEXPORT alpm_option_remove_ignoregroup(alpm_handle_t *handle, const char *
return _alpm_option_strlist_rem(handle, &(handle->ignoregroup), grp); return _alpm_option_strlist_rem(handle, &(handle->ignoregroup), grp);
} }
int SYMEXPORT alpm_option_add_assumeinstalled(alpm_handle_t *handle, const alpm_depend_t *dep)
{
CHECK_HANDLE(handle, return -1);
handle->assumeinstalled = alpm_list_add(handle->assumeinstalled, (void *)dep);
return 0;
}
int SYMEXPORT alpm_option_set_assumeinstalled(alpm_handle_t *handle, alpm_list_t *deps)
{
CHECK_HANDLE(handle, return -1);
if(handle->assumeinstalled) {
alpm_list_free_inner(handle->assumeinstalled, (alpm_list_fn_free)alpm_dep_free);
alpm_list_free(handle->assumeinstalled);
}
handle->assumeinstalled = deps;
return 0;
}
static int assumeinstalled_cmp(const void *d1, const void *d2)
{
const alpm_depend_t *dep1 = d1;
const alpm_depend_t *dep2 = d2;
if(strcmp(dep1->name, dep2->name) == 0 && strcmp(dep1->version, dep2->version) == 0) {
return 0;
}
return -1;
}
int SYMEXPORT alpm_option_remove_assumeinstalled(alpm_handle_t *handle, const alpm_depend_t *dep)
{
alpm_depend_t *vdata = NULL;
CHECK_HANDLE(handle, return -1);
handle->assumeinstalled = alpm_list_remove(handle->assumeinstalled, dep, &assumeinstalled_cmp, (void **)&vdata);
if(vdata != NULL) {
alpm_dep_free(vdata);
return 1;
}
return 0;
}
int SYMEXPORT alpm_option_set_arch(alpm_handle_t *handle, const char *arch) int SYMEXPORT alpm_option_set_arch(alpm_handle_t *handle, const char *arch)
{ {
CHECK_HANDLE(handle, return -1); CHECK_HANDLE(handle, return -1);

View file

@ -84,6 +84,7 @@ struct __alpm_handle_t {
alpm_list_t *noextract; /* List of files NOT to extract */ alpm_list_t *noextract; /* List of files NOT to extract */
alpm_list_t *ignorepkg; /* List of packages to ignore */ alpm_list_t *ignorepkg; /* List of packages to ignore */
alpm_list_t *ignoregroup; /* List of groups to ignore */ alpm_list_t *ignoregroup; /* List of groups to ignore */
alpm_list_t *assumeinstalled; /* List of virtual packages used to satisfy dependencies */
/* options */ /* options */
char *arch; /* Architecture of packages we should allow */ char *arch; /* Architecture of packages we should allow */

View file

@ -134,6 +134,7 @@ int config_free(config_t *oldconfig)
FREELIST(oldconfig->holdpkg); FREELIST(oldconfig->holdpkg);
FREELIST(oldconfig->ignorepkg); FREELIST(oldconfig->ignorepkg);
FREELIST(oldconfig->ignoregrp); FREELIST(oldconfig->ignoregrp);
FREELIST(oldconfig->assumeinstalled);
FREELIST(oldconfig->noupgrade); FREELIST(oldconfig->noupgrade);
FREELIST(oldconfig->noextract); FREELIST(oldconfig->noextract);
free(oldconfig->configfile); free(oldconfig->configfile);
@ -650,6 +651,7 @@ static int setup_libalpm(void)
int ret = 0; int ret = 0;
alpm_errno_t err; alpm_errno_t err;
alpm_handle_t *handle; alpm_handle_t *handle;
alpm_list_t *i;
pm_printf(ALPM_LOG_DEBUG, "setup_libalpm called\n"); pm_printf(ALPM_LOG_DEBUG, "setup_libalpm called\n");
@ -742,6 +744,22 @@ static int setup_libalpm(void)
alpm_option_set_noupgrades(handle, config->noupgrade); alpm_option_set_noupgrades(handle, config->noupgrade);
alpm_option_set_noextracts(handle, config->noextract); alpm_option_set_noextracts(handle, config->noextract);
for(i = config->assumeinstalled; i; i = i->next) {
char *entry = i->data;
alpm_depend_t *dep = alpm_dep_from_string(entry);
if(!dep) {
return 1;
}
pm_printf(ALPM_LOG_DEBUG, "parsed assume installed: %s %s\n", dep->name, dep->version);
ret = alpm_option_add_assumeinstalled(handle, dep);
if(ret) {
pm_printf(ALPM_LOG_ERROR, _("Failed to pass assume installed entry to libalpm"));
alpm_dep_free(dep);
return ret;
}
}
return 0; return 0;
} }

View file

@ -101,6 +101,7 @@ typedef struct __config_t {
alpm_list_t *holdpkg; alpm_list_t *holdpkg;
alpm_list_t *ignorepkg; alpm_list_t *ignorepkg;
alpm_list_t *ignoregrp; alpm_list_t *ignoregrp;
alpm_list_t *assumeinstalled;
alpm_list_t *noupgrade; alpm_list_t *noupgrade;
alpm_list_t *noextract; alpm_list_t *noextract;
char *xfercommand; char *xfercommand;
@ -176,7 +177,8 @@ enum {
OP_UNNEEDED, OP_UNNEEDED,
OP_VERBOSE, OP_VERBOSE,
OP_DOWNLOADONLY, OP_DOWNLOADONLY,
OP_REFRESH OP_REFRESH,
OP_ASSUMEINSTALLED
}; };
/* clean method */ /* clean method */

View file

@ -634,6 +634,9 @@ static int parsearg_trans(int opt)
free(config->print_format); free(config->print_format);
config->print_format = strdup(optarg); config->print_format = strdup(optarg);
break; break;
case OP_ASSUMEINSTALLED:
parsearg_util_addlist(&(config->assumeinstalled));
break;
default: default:
return 1; return 1;
} }
@ -857,6 +860,7 @@ static int parseargs(int argc, char *argv[])
{"noconfirm", no_argument, 0, OP_NOCONFIRM}, {"noconfirm", no_argument, 0, OP_NOCONFIRM},
{"config", required_argument, 0, OP_CONFIG}, {"config", required_argument, 0, OP_CONFIG},
{"ignore", required_argument, 0, OP_IGNORE}, {"ignore", required_argument, 0, OP_IGNORE},
{"assume-installed", required_argument, 0, OP_ASSUMEINSTALLED},
{"debug", optional_argument, 0, OP_DEBUG}, {"debug", optional_argument, 0, OP_DEBUG},
{"force", no_argument, 0, OP_FORCE}, {"force", no_argument, 0, OP_FORCE},
{"noprogressbar", no_argument, 0, OP_NOPROGRESSBAR}, {"noprogressbar", no_argument, 0, OP_NOPROGRESSBAR},

View file

@ -92,6 +92,7 @@ TESTS += test/pacman/tests/querycheck001.py
TESTS += test/pacman/tests/querycheck002.py TESTS += test/pacman/tests/querycheck002.py
TESTS += test/pacman/tests/querycheck_fast_file_type.py TESTS += test/pacman/tests/querycheck_fast_file_type.py
TESTS += test/pacman/tests/reason001.py TESTS += test/pacman/tests/reason001.py
TESTS += test/pacman/tests/remove-assumeinstalled.py
TESTS += test/pacman/tests/remove001.py TESTS += test/pacman/tests/remove001.py
TESTS += test/pacman/tests/remove002.py TESTS += test/pacman/tests/remove002.py
TESTS += test/pacman/tests/remove010.py TESTS += test/pacman/tests/remove010.py
@ -135,12 +136,14 @@ TESTS += test/pacman/tests/symlink010.py
TESTS += test/pacman/tests/symlink011.py TESTS += test/pacman/tests/symlink011.py
TESTS += test/pacman/tests/symlink012.py TESTS += test/pacman/tests/symlink012.py
TESTS += test/pacman/tests/symlink020.py TESTS += test/pacman/tests/symlink020.py
TESTS += test/pacman/tests/sync-install-assumeinstalled.py
TESTS += test/pacman/tests/sync-nodepversion01.py TESTS += test/pacman/tests/sync-nodepversion01.py
TESTS += test/pacman/tests/sync-nodepversion02.py TESTS += test/pacman/tests/sync-nodepversion02.py
TESTS += test/pacman/tests/sync-nodepversion03.py TESTS += test/pacman/tests/sync-nodepversion03.py
TESTS += test/pacman/tests/sync-nodepversion04.py TESTS += test/pacman/tests/sync-nodepversion04.py
TESTS += test/pacman/tests/sync-nodepversion05.py TESTS += test/pacman/tests/sync-nodepversion05.py
TESTS += test/pacman/tests/sync-nodepversion06.py TESTS += test/pacman/tests/sync-nodepversion06.py
TESTS += test/pacman/tests/sync-update-assumeinstalled.py
TESTS += test/pacman/tests/sync-update-package-removing-required-provides.py TESTS += test/pacman/tests/sync-update-package-removing-required-provides.py
TESTS += test/pacman/tests/sync001.py TESTS += test/pacman/tests/sync001.py
TESTS += test/pacman/tests/sync002.py TESTS += test/pacman/tests/sync002.py

View file

@ -0,0 +1,14 @@
self.description = "Remove a package using --assume-installed"
lp1 = pmpkg("pkg1", "1.0-1")
lp2 = pmpkg("pkg2", "1.0-1")
lp2.depends = ["pkg1=1.0"]
for p in lp1, lp2:
self.addpkg2db("local", p);
self.args = "-R pkg1 --assume-installed pkg1=1.0"
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=pkg2")
self.addrule("!PKG_EXIST=pkg1")

View file

@ -0,0 +1,11 @@
self.description = "Install a package using --assume-installed"
sp1 = pmpkg("pkg2", "2.0-1")
sp1.depends = ["pkg1"]
self.addpkg2db("sync", sp1);
self.args = "-S pkg2 --assume-installed pkg1"
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=pkg2")

View file

@ -0,0 +1,19 @@
self.description = "Update a package using --assume-installed"
lp1 = pmpkg("pkg1", "1.0-1")
lp2 = pmpkg("pkg2", "1.0-1")
lp2.depends = ["pkg1=1.0"]
sp1 = pmpkg("pkg1", "2.0-1")
for p in lp1, lp2:
self.addpkg2db("local", p);
self.addpkg2db("sync", sp1);
self.args = "-Su --assume-installed pkg1=1.0"
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_VERSION=pkg1|2.0-1")
self.addrule("PKG_EXIST=pkg2")