Allow '-Su foo' operation

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 <shiningxc@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
Xavier Chantry 2009-09-07 20:58:49 +02:00 committed by Dan McGee
parent cd5b029e93
commit f53d9bab0e
3 changed files with 99 additions and 65 deletions

View File

@ -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

25
pactest/tests/sync150.py Normal file
View File

@ -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)

View File

@ -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 */