[pacman-dev] [PATCH] Add more information in conflicts question
Sebastian Nowicki
sebnow at gmail.com
Sun Apr 17 05:03:29 EDT 2011
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
More information about the pacman-dev
mailing list