diff options
-rw-r--r-- | doc/pacman.8.txt | 4 | ||||
-rw-r--r-- | pactest/tests/sync150.py | 25 | ||||
-rw-r--r-- | src/pacman/sync.c | 135 |
3 files changed, 99 insertions, 65 deletions
diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt index a534e057..559b45d8 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 00000000..b62bd984 --- /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 4f101f99..58f60476 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 */ |