diff options
-rw-r--r-- | doc/pacman.conf.5.txt | 6 | ||||
-rw-r--r-- | src/pacman/conf.h | 4 | ||||
-rw-r--r-- | src/pacman/pacman.c | 22 | ||||
-rw-r--r-- | src/pacman/sync.c | 76 | ||||
-rw-r--r-- | test/pacman/tests/clean004.py | 30 | ||||
-rw-r--r-- | test/pacman/tests/clean005.py | 29 |
6 files changed, 117 insertions, 50 deletions
diff --git a/doc/pacman.conf.5.txt b/doc/pacman.conf.5.txt index ae4d7484..cb4c5898 100644 --- a/doc/pacman.conf.5.txt +++ b/doc/pacman.conf.5.txt @@ -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 diff --git a/src/pacman/conf.h b/src/pacman/conf.h index ff7a9c79..92c379fc 100644 --- a/src/pacman/conf.h +++ b/src/pacman/conf.h @@ -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 */ diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index 45500cfb..21d02107 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -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); diff --git a/src/pacman/sync.c b/src/pacman/sync.c index 2e68c8da..26f6f824 100644 --- a/src/pacman/sync.c +++ b/src/pacman/sync.c @@ -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); diff --git a/test/pacman/tests/clean004.py b/test/pacman/tests/clean004.py new file mode 100644 index 00000000..09137f39 --- /dev/null +++ b/test/pacman/tests/clean004.py @@ -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") diff --git a/test/pacman/tests/clean005.py b/test/pacman/tests/clean005.py new file mode 100644 index 00000000..f85248ef --- /dev/null +++ b/test/pacman/tests/clean005.py @@ -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") |