Allow both cleanmethod values to be specified at the same time

No reason to disallow this- it allows keeping even more packages around in
the cache. Test cases included for this case and to ensure the default
behavior is preserved.

Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
Dan McGee 2011-01-29 12:10:05 -06:00
parent 986edb8bd4
commit 09f9f24331
6 changed files with 117 additions and 50 deletions

View File

@ -136,14 +136,16 @@ Options
These files refer to files in the package archive, so do not include the
leading slash (the RootDir) when specifying them.
*CleanMethod =* KeepInstalled | KeepCurrent::
*CleanMethod =* KeepInstalled &| KeepCurrent::
If set to `KeepInstalled` (the default), the '-Sc' operation will clean
packages that are no longer installed (not present in the local database).
If set to `KeepCurrent`, '-Sc' will clean outdated packages (not present in
any sync database).
The second behavior is useful when the package cache is shared among
multiple machines, where the local databases are usually different, but the
sync databases in use could be the same.
sync databases in use could be the same. If both values are specified,
packages are only cleaned if not installed locally and not present in any
known sync database.
*UseSyslog*::
Log action messages through syslog(). This will insert log entries into

View File

@ -111,8 +111,8 @@ enum {
/* clean method */
enum {
PM_CLEAN_KEEPINST = 0, /* default */
PM_CLEAN_KEEPCUR
PM_CLEAN_KEEPINST = 1,
PM_CLEAN_KEEPCUR = (1 << 1)
};
/* global config variable */

View File

@ -792,6 +792,18 @@ static void option_add_syncfirst(const char *name) {
config->syncfirst = alpm_list_add(config->syncfirst, strdup(name));
}
/* helper for being used with setrepeatingoption */
static void option_add_cleanmethod(const char *value) {
if (strcmp(value, "KeepInstalled") == 0) {
config->cleanmethod |= PM_CLEAN_KEEPINST;
} else if (strcmp(value, "KeepCurrent") == 0) {
config->cleanmethod |= PM_CLEAN_KEEPCUR;
} else {
pm_printf(PM_LOG_ERROR, _("invalid value for 'CleanMethod' : '%s'\n"),
value);
}
}
/** Add repeating options such as NoExtract, NoUpgrade, etc to libalpm
* settings. Refactored out of the parseconfig code since all of them did
* the exact same thing and duplicated code.
@ -1008,15 +1020,7 @@ static int _parse_options(char *key, char *value)
alpm_option_set_fetchcb(download_with_xfercommand);
pm_printf(PM_LOG_DEBUG, "config: xfercommand: %s\n", value);
} else if (strcmp(key, "CleanMethod") == 0) {
if (strcmp(value, "KeepInstalled") == 0) {
config->cleanmethod = PM_CLEAN_KEEPINST;
} else if (strcmp(value, "KeepCurrent") == 0) {
config->cleanmethod = PM_CLEAN_KEEPCUR;
} else {
pm_printf(PM_LOG_ERROR, _("invalid value for 'CleanMethod' : '%s'\n"), value);
return(1);
}
pm_printf(PM_LOG_DEBUG, "config: cleanmethod: %s\n", value);
setrepeatingoption(value, "CleanMethod", option_add_cleanmethod);
} else {
pm_printf(PM_LOG_ERROR, _("directive '%s' with a value not recognized\n"), key);
return(1);

View File

@ -151,21 +151,21 @@ static int sync_cleancache(int level)
printf(_("Cache directory: %s\n"), (char*)alpm_list_getdata(i));
}
if(!config->cleanmethod) {
/* default to KeepInstalled if user did not specify */
config->cleanmethod = PM_CLEAN_KEEPINST;
}
if(level == 1) {
switch(config->cleanmethod) {
case PM_CLEAN_KEEPINST:
if(!yesno(_("Do you want to remove uninstalled packages from cache?"))) {
return(0);
}
break;
case PM_CLEAN_KEEPCUR:
if(!yesno(_("Do you want to remove outdated packages from cache?"))) {
return(0);
}
break;
default:
/* this should not happen : the config parsing doesn't set any other value */
return(1);
printf(_("Packages to keep:\n"));
if(config->cleanmethod & PM_CLEAN_KEEPINST) {
printf(_(" All locally installed packages\n"));
}
if(config->cleanmethod & PM_CLEAN_KEEPCUR) {
printf(_(" All current sync database packages\n"));
}
if(!yesno(_("Do you want to remove all other packages from cache?"))) {
return(0);
}
printf(_("removing old packages from cache...\n"));
} else {
@ -193,6 +193,7 @@ static int sync_cleancache(int level)
char path[PATH_MAX];
int delete = 1;
pmpkg_t *localpkg = NULL, *pkg = NULL;
const char *local_name, *local_version;
alpm_list_t *j;
if(strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
@ -219,32 +220,33 @@ static int sync_cleancache(int level)
}
continue;
}
switch(config->cleanmethod) {
case PM_CLEAN_KEEPINST:
/* check if this package is in the local DB */
pkg = alpm_db_get_pkg(db_local, alpm_pkg_get_name(localpkg));
if(pkg != NULL && alpm_pkg_vercmp(alpm_pkg_get_version(localpkg),
local_name = alpm_pkg_get_name(localpkg);
local_version = alpm_pkg_get_version(localpkg);
if(config->cleanmethod & PM_CLEAN_KEEPINST) {
/* check if this package is in the local DB */
pkg = alpm_db_get_pkg(db_local, local_name);
if(pkg != NULL && alpm_pkg_vercmp(local_version,
alpm_pkg_get_version(pkg)) == 0) {
/* package was found in local DB and version matches, keep it */
pm_printf(PM_LOG_DEBUG, "pkg %s-%s found in local db\n",
local_name, local_version);
delete = 0;
}
}
if(config->cleanmethod & PM_CLEAN_KEEPCUR) {
/* check if this package is in a sync DB */
for(j = sync_dbs; j && delete; j = alpm_list_next(j)) {
pmdb_t *db = alpm_list_getdata(j);
pkg = alpm_db_get_pkg(db, local_name);
if(pkg != NULL && alpm_pkg_vercmp(local_version,
alpm_pkg_get_version(pkg)) == 0) {
/* package was found in local DB and version matches, keep it */
/* package was found in a sync DB and version matches, keep it */
pm_printf(PM_LOG_DEBUG, "pkg %s-%s found in sync db\n",
local_name, local_version);
delete = 0;
}
break;
case PM_CLEAN_KEEPCUR:
/* check if this package is in a sync DB */
for(j = sync_dbs; j && delete; j = alpm_list_next(j)) {
pmdb_t *db = alpm_list_getdata(j);
pkg = alpm_db_get_pkg(db, alpm_pkg_get_name(localpkg));
if(pkg != NULL && alpm_pkg_vercmp(alpm_pkg_get_version(localpkg),
alpm_pkg_get_version(pkg)) == 0) {
/* package was found in a sync DB and version matches, keep it */
delete = 0;
}
}
break;
default:
/* this should not happen : the config parsing doesn't set any other value */
delete = 0;
break;
}
}
/* free the local file package */
alpm_pkg_free(localpkg);

View File

@ -0,0 +1,30 @@
self.description = "CleanMethod = KeepInstalled KeepCurrent"
sp = pmpkg("dummy", "2.0-1")
self.addpkg2db("sync", sp)
sp = pmpkg("bar", "2.0-1")
self.addpkg2db("sync", sp)
sp = pmpkg("baz", "2.0-1")
self.addpkg2db("sync", sp)
lp = pmpkg("dummy", "1.0-1")
self.addpkg2db("local", lp)
lp = pmpkg("bar", "2.0-1")
self.addpkg2db("local", lp)
op = pmpkg("foo", "2.0-1")
self.addpkg(op)
self.args = "-Sc"
self.option['CleanMethod'] = ['KeepInstalled KeepCurrent']
self.createlocalpkgs = True
self.addrule("PACMAN_RETCODE=0")
self.addrule("CACHE_EXISTS=dummy|2.0-1")
self.addrule("CACHE_EXISTS=dummy|1.0-1")
self.addrule("CACHE_EXISTS=bar|2.0-1")
self.addrule("CACHE_EXISTS=baz|2.0-1")
self.addrule("!CACHE_EXISTS=foo|2.0-1")

View File

@ -0,0 +1,29 @@
self.description = "CleanMethod = unspecified"
sp = pmpkg("dummy", "2.0-1")
self.addpkg2db("sync", sp)
sp = pmpkg("bar", "2.0-1")
self.addpkg2db("sync", sp)
sp = pmpkg("baz", "2.0-1")
self.addpkg2db("sync", sp)
lp = pmpkg("dummy", "1.0-1")
self.addpkg2db("local", lp)
lp = pmpkg("bar", "2.0-1")
self.addpkg2db("local", lp)
op = pmpkg("foo", "2.0-1")
self.addpkg(op)
self.args = "-Sc"
self.createlocalpkgs = True
self.addrule("PACMAN_RETCODE=0")
self.addrule("!CACHE_EXISTS=dummy|2.0-1")
self.addrule("CACHE_EXISTS=dummy|1.0-1")
self.addrule("CACHE_EXISTS=bar|2.0-1")
self.addrule("!CACHE_EXISTS=baz|2.0-1")
self.addrule("!CACHE_EXISTS=foo|2.0-1")