Added support for package conflicts.

This commit is contained in:
Juan RP
2012-06-11 16:14:03 +02:00
parent 81610697df
commit c61ba8dfcc
10 changed files with 151 additions and 16 deletions

View File

@@ -46,7 +46,7 @@ OBJS += package_remove.o package_remove_obsoletes.o package_state.o
OBJS += package_unpack.o package_requiredby.o package_register.o
OBJS += transaction_commit.o transaction_package_replace.o
OBJS += transaction_dictionary.o transaction_sortdeps.o transaction_ops.o
OBJS += download.o initend.o pkgdb.o
OBJS += download.o initend.o pkgdb.o package_conflicts.o
OBJS += plist.o plist_archive_entry.o plist_find.o plist_match.o
OBJS += plist_remove.o plist_fetch.o util.o util_hash.o
OBJS += repository_finddeps.o cb_util.o

82
lib/package_conflicts.c Normal file
View File

@@ -0,0 +1,82 @@
/*-
* Copyright (c) 2012 Juan Romero Pardines.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "xbps_api_impl.h"
void HIDDEN
xbps_pkg_find_conflicts(struct xbps_handle *xhp, prop_dictionary_t pkg_repod)
{
prop_array_t pkg_cflicts, trans_cflicts;
prop_dictionary_t pkgd;
const char *cfpkg, *repopkgver, *pkgver;
char *buf;
size_t i;
pkg_cflicts = prop_dictionary_get(pkg_repod, "conflicts");
if (pkg_cflicts == NULL || prop_array_count(pkg_cflicts) == 0)
return;
trans_cflicts = prop_dictionary_get(xhp->transd, "conflicts");
prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgver", &repopkgver);
for (i = 0; i < prop_array_count(pkg_cflicts); i++) {
prop_array_get_cstring_nocopy(pkg_cflicts, i, &cfpkg);
/*
* Check if current pkg conflicts with an installed package.
*/
if ((pkgd = xbps_pkgdb_get_pkgd(cfpkg, true))) {
prop_dictionary_get_cstring_nocopy(pkgd,
"pkgver", &pkgver);
buf = xbps_xasprintf("%s conflicts with "
"installed pkg %s", repopkgver, pkgver);
assert(buf != NULL);
prop_array_add_cstring(trans_cflicts, buf);
prop_object_release(pkgd);
free(buf);
continue;
}
/*
* Check if current pkg conflicts with any pkg in transaction.
*/
pkgd = xbps_find_pkg_in_dict_by_pattern(xhp->transd,
"unsorted_deps", cfpkg);
if (pkgd != NULL) {
prop_dictionary_get_cstring_nocopy(pkgd,
"pkgver", &pkgver);
buf = xbps_xasprintf("%s conflicts with "
"%s in transaction", repopkgver, pkgver);
assert(buf != NULL);
prop_array_add_cstring(trans_cflicts, buf);
free(buf);
continue;
}
}
}

View File

@@ -359,6 +359,10 @@ find_repo_deps(prop_dictionary_t transd, /* transaction dictionary */
continue;
}
}
/*
* Check if package has matched conflicts.
*/
xbps_pkg_find_conflicts(xhp, curpkgd);
/*
* Package is on repo, add it into the transaction dictionary.
*/

View File

@@ -190,7 +190,7 @@ out:
int HIDDEN
xbps_transaction_init(struct xbps_handle *xhp)
{
prop_array_t unsorted, mdeps;
prop_array_t unsorted, mdeps, conflicts;
if (xhp->transd != NULL)
return 0;
@@ -218,6 +218,16 @@ xbps_transaction_init(struct xbps_handle *xhp)
xhp->transd = NULL;
return EINVAL;
}
if ((conflicts = prop_array_create()) == NULL) {
prop_object_release(xhp->transd);
xhp->transd = NULL;
return ENOMEM;
}
if (!xbps_add_obj_to_dict(xhp->transd, conflicts, "conflicts")) {
prop_object_release(xhp->transd);
xhp->transd = NULL;
return EINVAL;
}
return 0;
}
@@ -225,7 +235,7 @@ xbps_transaction_init(struct xbps_handle *xhp)
int
xbps_transaction_prepare(void)
{
prop_array_t mdeps;
prop_array_t mdeps, conflicts;
struct xbps_handle *xhp = xbps_handle_get();
int rv = 0;
@@ -239,6 +249,13 @@ xbps_transaction_prepare(void)
if (prop_array_count(mdeps) > 0)
return ENODEV;
/*
* If there are package conflicts bail out.
*/
conflicts = prop_dictionary_get(xhp->transd, "conflicts");
if (prop_array_count(conflicts) > 0)
return EAGAIN;
/*
* Check for packages to be replaced.
*/
@@ -266,9 +283,10 @@ xbps_transaction_prepare(void)
return rv;
}
/*
* The missing deps array is not necessary anymore.
* The missing deps and conflicts arrays are not necessary anymore.
*/
prop_dictionary_remove(xhp->transd, "missing_deps");
prop_dictionary_remove(xhp->transd, "conflicts");
prop_dictionary_make_immutable(xhp->transd);
return 0;

View File

@@ -126,16 +126,22 @@ transaction_find_pkg(const char *pkg, bool bypattern, bool best, bool exact,
}
}
/*
* Prepare transaction dictionary and missing deps array.
* Prepare transaction dictionary.
*/
if ((rv = xbps_transaction_init(xhp)) != 0)
goto out;
/*
* Find out if package has matched conflicts.
*/
xbps_pkg_find_conflicts(xhp, pkg_repod);
/*
* Prepare required package dependencies and add them into the
* "unsorted" array in transaction dictionary.
*/
if ((rv = xbps_repository_find_pkg_deps(xhp, pkg_repod)) != 0)
goto out;
goto out;
/*
* Set package state in dictionary with same state than the
* package currently uses, otherwise not-installed.