Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/pacman.8.txt4
-rw-r--r--pactest/tests/sync150.py25
-rw-r--r--src/pacman/sync.c135
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 */