summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/pacman.conf.5.txt6
-rwxr-xr-xpactest/pmtest.py3
-rw-r--r--pactest/tests/sync301.py4
-rw-r--r--src/pacman/conf.c2
-rw-r--r--src/pacman/conf.h1
-rw-r--r--src/pacman/pacman.c7
-rw-r--r--src/pacman/sync.c77
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);
}
}