This implements FS#15581

'-Su foo' should be more or less equivalent do '-Su ; -S foo'

Note : I moved a block of code to a new process_target function

Signed-off-by: Xavier Chantry <[email protected]>
---
 doc/pacman.8.txt         |    4 +-
 pactest/tests/sync150.py |   25 +++++++++
 src/pacman/sync.c        |  135 ++++++++++++++++++++++++----------------------
 3 files changed, 99 insertions(+), 65 deletions(-)
 create mode 100644 pactest/tests/sync150.py

diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt
index a534e05..559b45d 100644
--- a/doc/pacman.8.txt
+++ b/doc/pacman.8.txt
@@ -332,7 +332,9 @@ linkman:pacman.conf[5].
        necessary. Pass this option twice to enable package downgrade; in this
        case pacman will select sync packages whose version does not match with
        the local version. This can be useful when the user switches from a 
testing
-       repo to a stable one.
+       repo to a stable one. Additional targets can also be specified 
manually, so
+       that '-Su foo' will do a system upgrade and install/upgrade the foo 
package in
+       the same operation.
 
 *-w, \--downloadonly*::
        Retrieve all packages from the server, but do not install/upgrade
diff --git a/pactest/tests/sync150.py b/pactest/tests/sync150.py
new file mode 100644
index 0000000..b62bd98
--- /dev/null
+++ b/pactest/tests/sync150.py
@@ -0,0 +1,25 @@
+self.description = "-Su foo"
+
+sp1 = pmpkg("pkg1", "1.0-2")
+sp1.depends = ["pkg2"]
+
+sp2 = pmpkg("pkg2")
+sp2.depends = ["pkg3"]
+
+sp3 = pmpkg("pkg3")
+
+sp4 = pmpkg("pkg4")
+
+for p in sp1, sp2, sp3, sp4:
+       self.addpkg2db("sync", p)
+
+lp1 = pmpkg("pkg1")
+self.addpkg2db("local", lp1)
+
+self.args = "-Su %s" % sp4.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=pkg1|1.0-2")
+for p in sp2, sp3:
+       self.addrule("PKG_REASON=%s|1" % p.name)
+self.addrule("PKG_REASON=%s|0" % sp4.name)
diff --git a/src/pacman/sync.c b/src/pacman/sync.c
index 4f101f9..58f6047 100644
--- a/src/pacman/sync.c
+++ b/src/pacman/sync.c
@@ -548,18 +548,88 @@ static alpm_list_t *syncfirst() {
        return(res);
 }
 
+static int process_target(char *targ, alpm_list_t *targets)
+{
+       alpm_list_t *sync_dbs = alpm_option_get_syncdbs();
+
+       if(alpm_trans_addtarget(targ) == -1) {
+               pmgrp_t *grp = NULL;
+               int found = 0;
+               alpm_list_t *j;
+
+               if(pm_errno == PM_ERR_TRANS_DUP_TARGET || pm_errno == 
PM_ERR_PKG_IGNORED) {
+                       /* just skip duplicate or ignored targets */
+                       pm_printf(PM_LOG_WARNING, _("skipping target: %s\n"), 
targ);
+                       return(0);
+               }
+               if(pm_errno != PM_ERR_PKG_NOT_FOUND) {
+                       pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n",
+                                       targ, alpm_strerrorlast());
+                       return(1);
+               }
+               /* target not found: check if it's a group */
+               printf(_("%s package not found, searching for group...\n"), 
targ);
+               for(j = sync_dbs; j; j = alpm_list_next(j)) {
+                       pmdb_t *db = alpm_list_getdata(j);
+                       grp = alpm_db_readgrp(db, targ);
+                       if(grp) {
+                               alpm_list_t *k, *pkgnames = NULL;
+
+                               found++;
+                               printf(_(":: group %s (including ignored 
packages):\n"), targ);
+                               /* remove dupe entries in case a package exists 
in multiple repos */
+                               alpm_list_t *grppkgs = alpm_grp_get_pkgs(grp);
+                               alpm_list_t *pkgs = 
alpm_list_remove_dupes(grppkgs);
+                               for(k = pkgs; k; k = alpm_list_next(k)) {
+                                       pkgnames = alpm_list_add(pkgnames,
+                                                       
(char*)alpm_pkg_get_name(k->data));
+                               }
+                               list_display("   ", pkgnames);
+                               if(yesno(_(":: Install whole content?"))) {
+                                       for(k = pkgnames; k; k = 
alpm_list_next(k)) {
+                                               targets = 
alpm_list_add(targets, strdup(alpm_list_getdata(k)));
+                                       }
+                               } else {
+                                       for(k = pkgnames; k; k = 
alpm_list_next(k)) {
+                                               char *pkgname = 
alpm_list_getdata(k);
+                                               if(yesno(_(":: Install %s from 
group %s?"), pkgname, targ)) {
+                                                       targets = 
alpm_list_add(targets, strdup(pkgname));
+                                               }
+                                       }
+                               }
+                               alpm_list_free(pkgnames);
+                               alpm_list_free(pkgs);
+                       }
+               }
+               if(!found) {
+                       pm_fprintf(stderr, PM_LOG_ERROR, _("'%s': not found in 
sync db\n"), targ);
+                       return(1);
+               }
+       }
+       return(0);
+}
+
 static int sync_trans(alpm_list_t *targets)
 {
        int retval = 0;
        alpm_list_t *data = NULL;
-       alpm_list_t *sync_dbs = alpm_option_get_syncdbs();
        alpm_list_t *packages = NULL;
+       alpm_list_t *i;
 
        /* Step 1: create a new transaction... */
        if(trans_init(PM_TRANS_TYPE_SYNC, config->flags) == -1) {
                return(1);
        }
 
+       /* process targets */
+       for(i = targets; i; i = alpm_list_next(i)) {
+               char *targ = alpm_list_getdata(i);
+               if(process_target(targ, targets) == 1) {
+                       retval = 1;
+                       goto cleanup;
+               }
+       }
+
        if(config->op_s_upgrade) {
                printf(_(":: Starting full system upgrade...\n"));
                alpm_logaction("starting full system upgrade\n");
@@ -568,69 +638,6 @@ static int sync_trans(alpm_list_t *targets)
                        retval = 1;
                        goto cleanup;
                }
-       } else {
-               alpm_list_t *i;
-
-               /* process targets */
-               for(i = targets; i; i = alpm_list_next(i)) {
-                       char *targ = alpm_list_getdata(i);
-                       if(alpm_trans_addtarget(targ) == -1) {
-                               pmgrp_t *grp = NULL;
-                               int found = 0;
-                               alpm_list_t *j;
-
-                               if(pm_errno == PM_ERR_TRANS_DUP_TARGET || 
pm_errno == PM_ERR_PKG_IGNORED) {
-                                       /* just skip duplicate or ignored 
targets */
-                                       pm_printf(PM_LOG_WARNING, _("skipping 
target: %s\n"), targ);
-                                       continue;
-                               }
-                               if(pm_errno != PM_ERR_PKG_NOT_FOUND) {
-                                       pm_fprintf(stderr, PM_LOG_ERROR, "'%s': 
%s\n",
-                                                       targ, 
alpm_strerrorlast());
-                                       retval = 1;
-                                       goto cleanup;
-                               }
-                               /* target not found: check if it's a group */
-                               printf(_("%s package not found, searching for 
group...\n"), targ);
-                               for(j = sync_dbs; j; j = alpm_list_next(j)) {
-                                       pmdb_t *db = alpm_list_getdata(j);
-                                       grp = alpm_db_readgrp(db, targ);
-                                       if(grp) {
-                                               alpm_list_t *k, *pkgnames = 
NULL;
-
-                                               found++;
-                                               printf(_(":: group %s 
(including ignored packages):\n"), targ);
-                                               /* remove dupe entries in case 
a package exists in multiple repos */
-                                               alpm_list_t *grppkgs = 
alpm_grp_get_pkgs(grp);
-                                               alpm_list_t *pkgs = 
alpm_list_remove_dupes(grppkgs);
-                                               for(k = pkgs; k; k = 
alpm_list_next(k)) {
-                                                       pkgnames = 
alpm_list_add(pkgnames,
-                                                                       
(char*)alpm_pkg_get_name(k->data));
-                                               }
-                                               list_display("   ", pkgnames);
-                                               if(yesno(_(":: Install whole 
content?"))) {
-                                                       for(k = pkgnames; k; k 
= alpm_list_next(k)) {
-                                                               targets = 
alpm_list_add(targets, strdup(alpm_list_getdata(k)));
-                                                       }
-                                               } else {
-                                                       for(k = pkgnames; k; k 
= alpm_list_next(k)) {
-                                                               char *pkgname = 
alpm_list_getdata(k);
-                                                               if(yesno(_(":: 
Install %s from group %s?"), pkgname, targ)) {
-                                                                       targets 
= alpm_list_add(targets, strdup(pkgname));
-                                                               }
-                                                       }
-                                               }
-                                               alpm_list_free(pkgnames);
-                                               alpm_list_free(pkgs);
-                                       }
-                               }
-                               if(!found) {
-                                       pm_fprintf(stderr, PM_LOG_ERROR, 
_("'%s': not found in sync db\n"), targ);
-                                       retval = 1;
-                                       goto cleanup;
-                               }
-                       }
-               }
        }
 
        /* Step 2: "compute" the transaction based on targets and flags */
-- 
1.6.4.2


Reply via email to