In addition to the names of the conflicting packages, the origin and
versions will be displayed to the user.

This introduces a slight API change in the PM_TRANS_CONV_CONFLICT_PKG
conversation callback. The format of the first two strings has changed
from package names to strings of the format "db/name-version".

Fixes FS#12536
---

I rewrote the patch to pre-format the package information rather than
changing the API completely, as per Dan's suggestion. This still
introduces a bit of an API change as the two string can no longer be
used as package identifiers, e.g. in alpm_db_get_pkg().

$ sudo ./src/pacman/pacman -S qemu-kvm
resolving dependencies...
looking for inter-conflicts...
:: extra/qemu-kvm-0.14.0-1 and local/qemu-0.14.0-1 are in conflict (qemu). 
Remove local/qemu-0.14.0-1? [y/N] n
error: unresolvable package conflicts detected
error: failed to prepare transaction (conflicting dependencies)
:: qemu-kvm and qemu are in conflict

 lib/libalpm/sync.c |   51 ++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
index 5428e40..90eeb5d 100644
--- a/lib/libalpm/sync.c
+++ b/lib/libalpm/sync.c
@@ -299,6 +299,47 @@ static int compute_download_size(pmpkg_t *newpkg)
        return 0;
 }
 
+/** Format package details to "db/name-version".
+ *
+ * If the package's origin is not found, it will be omitted
+ * (i.e. "name-version").
+ *
+ * The returned string must be freed by the caller.
+ *
+ * Sets pm_errno on error.
+ *
+ * @param pkg the package which details are to be formatted.
+ * @return Formatting package string, or NULL on error.
+ */
+static char *format_full_pkgname(pmpkg_t *pkg) {
+       char *full_pkgname;
+       size_t size = 1; /* Reserve for NULL */
+       pmdb_t *origin;
+
+       ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, NULL));
+
+       /* Calulate length and allocate memory */
+       origin = alpm_pkg_get_db(pkg);
+       if(origin != NULL) {
+               size += strlen(alpm_db_get_name(origin)) + 1; /* Additional for 
'/' */
+       }
+       size += strlen(alpm_pkg_get_name(pkg)) + 1; /* Additional for hyphen */
+       size += strlen(alpm_pkg_get_version(pkg));
+       MALLOC(full_pkgname, size, RET_ERR(PM_ERR_MEMORY, NULL));
+
+       if(origin != NULL) {
+               snprintf(full_pkgname, size, "%s/%s-%s",
+                               alpm_db_get_name(origin),
+                               alpm_pkg_get_name(pkg),
+                               alpm_pkg_get_version(pkg));
+       } else {
+               snprintf(full_pkgname, size, "%s-%s",
+                               alpm_pkg_get_name(pkg),
+                               alpm_pkg_get_version(pkg));
+       }
+       return full_pkgname;
+}
+
 int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t 
*dbs_sync, alpm_list_t **data)
 {
        alpm_list_t *deps = NULL;
@@ -485,12 +526,14 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t 
*db_local, alpm_list_t *dbs_sync
 
                        pmpkg_t *sync = _alpm_pkg_find(trans->add, 
conflict->package1);
                        pmpkg_t *local = _alpm_db_get_pkgfromcache(db_local, 
conflict->package2);
+                       char *sync_pkgname = format_full_pkgname(sync);
+                       char *local_pkgname = format_full_pkgname(local);
                        int doremove = 0;
-                       QUESTION(trans, PM_TRANS_CONV_CONFLICT_PKG, 
conflict->package1,
-                                                       conflict->package2, 
conflict->reason, &doremove);
+                       QUESTION(trans, PM_TRANS_CONV_CONFLICT_PKG, 
sync_pkgname, local_pkgname,
+                                                       conflict->reason, 
&doremove);
                        if(doremove) {
                                /* append to the removes list */
-                               _alpm_log(PM_LOG_DEBUG, "electing '%s' for 
removal\n", conflict->package2);
+                               _alpm_log(PM_LOG_DEBUG, "electing '%s' for 
removal\n", local_pkgname);
                                sync->removes = alpm_list_add(sync->removes, 
local);
                        } else { /* abort */
                                _alpm_log(PM_LOG_ERROR, _("unresolvable package 
conflicts detected\n"));
@@ -506,6 +549,8 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, 
alpm_list_t *dbs_sync
                                alpm_list_free(deps);
                                goto cleanup;
                        }
+                       FREE(sync_pkgname);
+                       FREE(local_pkgname);
                }
                EVENT(trans, PM_TRANS_EVT_INTERCONFLICTS_DONE, NULL, NULL);
                alpm_list_free_inner(deps, 
(alpm_list_fn_free)_alpm_conflict_free);
-- 
1.7.4.4


Reply via email to