diff options
-rw-r--r-- | doc/pacman.conf.5.txt | 6 | ||||
-rwxr-xr-x | pactest/pmtest.py | 3 | ||||
-rw-r--r-- | pactest/tests/sync301.py | 4 | ||||
-rw-r--r-- | src/pacman/conf.c | 2 | ||||
-rw-r--r-- | src/pacman/conf.h | 1 | ||||
-rw-r--r-- | src/pacman/pacman.c | 7 | ||||
-rw-r--r-- | src/pacman/sync.c | 77 |
7 files changed, 62 insertions, 38 deletions
diff --git a/doc/pacman.conf.5.txt b/doc/pacman.conf.5.txt index 5514e2c0..eb9285c3 100644 --- a/doc/pacman.conf.5.txt +++ b/doc/pacman.conf.5.txt @@ -82,6 +82,12 @@ Options Instructs pacman to ignore any upgrades for this package when performing a '\--sysupgrade'. +*SyncFirst =* package ...:: + Instructs pacman to check for newer version of these packages before any + sync operation. The user will have the choice to either cancel the current + operation and upgrade these packages first or go on with the current operation. + This option is typically used with the 'pacman' package. + *IgnoreGroup =* group ...:: Instructs pacman to ignore any upgrades for all packages in this group when performing a '\--sysupgrade'. diff --git a/pactest/pmtest.py b/pactest/pmtest.py index 0c4ba847..267eeb2e 100755 --- a/pactest/pmtest.py +++ b/pactest/pmtest.py @@ -83,7 +83,8 @@ class pmtest: "noupgrade": [], "ignorepkg": [], "ignoregroup": [], - "noextract": [] + "noextract": [], + "syncfirst": [] } # Test rules diff --git a/pactest/tests/sync301.py b/pactest/tests/sync301.py index e8526b93..96402fc3 100644 --- a/pactest/tests/sync301.py +++ b/pactest/tests/sync301.py @@ -16,10 +16,12 @@ self.addpkg2db("local", lp) lp1 = pmpkg("pkg1", "1.0-1") self.addpkg2db("local", lp1) +self.option["SyncFirst"] = ["pacman"] + self.args = "-Su" self.addrule("PACMAN_RETCODE=0") self.addrule("PKG_EXIST=pacman") self.addrule("PKG_VERSION=pacman|1.0-2") +self.addrule("PKG_VERSION=pkg1|1.0-1") self.addrule("PKG_EXIST=dep") -self.addrule("PKG_REQUIREDBY=dep|pacman") diff --git a/src/pacman/conf.c b/src/pacman/conf.c index 27c254b5..48c927bf 100644 --- a/src/pacman/conf.c +++ b/src/pacman/conf.c @@ -47,6 +47,7 @@ config_t *config_new(void) newconfig->rootdir = NULL; newconfig->dbpath = NULL; newconfig->logfile = NULL; + newconfig->syncfirst = NULL; return(newconfig); } @@ -57,6 +58,7 @@ int config_free(config_t *oldconfig) return(-1); } + FREELIST(oldconfig->syncfirst); free(oldconfig->configfile); free(oldconfig->rootdir); free(oldconfig->dbpath); diff --git a/src/pacman/conf.h b/src/pacman/conf.h index 28ac4b96..874ce708 100644 --- a/src/pacman/conf.h +++ b/src/pacman/conf.h @@ -69,6 +69,7 @@ typedef struct __config_t { * downloaded of the total download list */ unsigned short totaldownload; unsigned short cleanmethod; /* select -Sc behavior */ + alpm_list_t *syncfirst; } config_t; /* Operations */ diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index 5cb3c784..7ae023b2 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -515,6 +515,11 @@ static int parseargs(int argc, char *argv[]) return(0); } +/* helper for being used with setrepeatingoption */ +static void option_add_syncfirst(const char *name) { + config->syncfirst = alpm_list_add(config->syncfirst, strdup(name)); +} + /** 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. @@ -666,6 +671,8 @@ static int _parseconfig(const char *file, const char *givensection, setrepeatingoption(ptr, "IgnoreGroup", alpm_option_add_ignoregrp); } else if(strcmp(key, "HoldPkg") == 0) { setrepeatingoption(ptr, "HoldPkg", alpm_option_add_holdpkg); + } else if(strcmp(key, "SyncFirst") == 0) { + setrepeatingoption(ptr, "SyncFirst", option_add_syncfirst); } else if(strcmp(key, "DBPath") == 0) { /* don't overwrite a path specified on the command line */ if(!config->dbpath) { diff --git a/src/pacman/sync.c b/src/pacman/sync.c index 78235c54..134d4db3 100644 --- a/src/pacman/sync.c +++ b/src/pacman/sync.c @@ -527,6 +527,24 @@ static int sync_list(alpm_list_t *syncs, alpm_list_t *targets) return(0); } +static alpm_list_t *syncfirst() { + alpm_list_t *i, *res = NULL; + + for(i = config->syncfirst; i; i = alpm_list_next(i)) { + char *pkgname = alpm_list_getdata(i); + pmpkg_t *pkg = alpm_db_get_pkg(alpm_option_get_localdb(), pkgname); + if(pkg == NULL) { + continue; + } + + if(alpm_sync_newversion(pkg, alpm_option_get_syncdbs())) { + res = alpm_list_add(res, strdup(pkgname)); + } + } + + return(res); +} + static int sync_trans(alpm_list_t *targets) { int retval = 0; @@ -539,7 +557,6 @@ static int sync_trans(alpm_list_t *targets) } if(config->op_s_upgrade) { - alpm_list_t *pkgs, *i; printf(_(":: Starting full system upgrade...\n")); alpm_logaction("starting full system upgrade\n"); if(alpm_trans_sysupgrade() == -1) { @@ -547,40 +564,6 @@ static int sync_trans(alpm_list_t *targets) retval = 1; goto cleanup; } - - if(!(alpm_trans_get_flags() & (PM_TRANS_FLAG_DOWNLOADONLY | PM_TRANS_FLAG_PRINTURIS))) { - /* check if pacman itself is one of the packages to upgrade. - * this can prevent some of the "syntax error" problems users can have - * when sysupgrade'ing with an older version of pacman. - */ - pkgs = alpm_trans_get_pkgs(); - for(i = pkgs; i; i = alpm_list_next(i)) { - pmsyncpkg_t *sync = alpm_list_getdata(i); - pmpkg_t *spkg = alpm_sync_get_pkg(sync); - /* TODO pacman name should probably not be hardcoded. In addition, we - * have problems on an -Syu if pacman has to pull in deps, so recommend - * an '-S pacman' operation */ - if(strcmp("pacman", alpm_pkg_get_name(spkg)) == 0) { - printf("\n"); - printf(_(":: pacman has detected a newer version of itself.\n")); - if(yesno(1, _(":: Do you want to cancel the current operation\n" - ":: and install the new pacman version now?"))) { - if(trans_release() == -1) { - return(1); - } - if(trans_init(PM_TRANS_TYPE_SYNC, 0) == -1) { - return(1); - } - if(alpm_trans_addtarget("pacman") == -1) { - pm_fprintf(stderr, PM_LOG_ERROR, _("pacman: %s\n"), - alpm_strerrorlast()); - return(1); - } - break; - } - } - } - } } else { alpm_list_t *i; @@ -831,7 +814,29 @@ int pacman_sync(alpm_list_t *targets) } if(needs_transaction()) { - if(sync_trans(targets) == 1) { + alpm_list_t *targs = alpm_list_strdup(targets); + if(!(config->flags & (PM_TRANS_FLAG_DOWNLOADONLY | PM_TRANS_FLAG_PRINTURIS))) { + /* check for newer versions of packages to be upgraded first */ + alpm_list_t *packages = syncfirst(); + if(packages) { + printf(_(":: The following packages should be upgraded first :\n")); + list_display(" ", packages); + if(yesno(1, _(":: Do you want to cancel the current operation\n" + ":: and upgrade these packages now?"))) { + FREELIST(targs); + targs = packages; + config->flags = 0; + config->op_s_upgrade = 0; + } else { + FREELIST(packages); + } + printf("\n"); + } + } + + int ret = sync_trans(targs); + FREELIST(targs); + if(ret == 1) { return(1); } } |