summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChantry Xavier <shiningxc@gmail.com>2008-01-28 19:49:27 +0100
committerDan McGee <dan@archlinux.org>2008-05-13 15:49:02 -0500
commitd5278ebb3ba94efdc9fffb7924ac66b6747d9011 (patch)
treed83bd99db2b5d93d8b8398c393745b1032159db3
parentf43805d875ad5c672afbbfff48bded2087204773 (diff)
Add SyncFirst option.
This patch offers a way to fix FS#9228. By putting "SyncFirst = pacman" in pacman.conf, the version check will happen before the transaction really starts, and before any replacements is made. Otherwise, no version check is done. The sync301 pactest was updated to use this SyncFirst option. Example session with SyncFirst = pacman, and a newer pacman version available : $ pacman -Su (or pacman -S <any targets>) :: the following packages should be upgraded first : pacman :: Do you want to cancel the current operation :: and upgrade these packages now? [Y/n] resolving dependencies... looking for inter-conflicts... Targets: pacman-x.y.z-t Total Download Size: x.xx MB Total Installed Size: x.xx MB Proceed with installation? [Y/n] n As Nagy previously noted, doing this check on any -S operations might look intrusive, but it can be required. For example, the case where you want to install a package with versioned provisions, using a pacman version which didn't support that feature yet (and there is already a newer pacman in sync db supporting it). Signed-off-by: Chantry Xavier <shiningxc@gmail.com> Signed-off-by: Dan McGee <dan@archlinux.org>
-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);
}
}