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

5
NEWS
View File

@ -1,5 +1,10 @@
xbps-0.16 (???): xbps-0.16 (???):
* Added support for package conflicts. If any conflicting pkg has been found
in a transaction, xbps_transaction_prepare() will return EAGAIN and
the array object "conflicts" in transaction dictionary must be inspected
to know what conflicts have been found.
* Always require an underscore at package versions, if any provided * Always require an underscore at package versions, if any provided
pkgver (i.e 'foo-1.0_1') does not contain an underscore the name/version pkgver (i.e 'foo-1.0_1') does not contain an underscore the name/version
won't be detected for a string. That means that now any package can contain won't be detected for a string. That means that now any package can contain

1
TODO
View File

@ -1,5 +1,4 @@
libxbps: libxbps:
- conflicts: the object is there but is not handled yet (ETA 0.16)
- properties: (update-first) still unimplemented. - properties: (update-first) still unimplemented.
xbps-repo: xbps-repo:

View File

@ -50,16 +50,26 @@ struct transaction {
static void static void
show_missing_deps(prop_array_t a) show_missing_deps(prop_array_t a)
{ {
prop_object_t obj;
size_t i; size_t i;
const char *str;
fprintf(stderr, fprintf(stderr, "xbps-bin: unable to locate some required packages:\n");
"xbps-bin: unable to locate some required packages:\n");
for (i = 0; i < prop_array_count(a); i++) { for (i = 0; i < prop_array_count(a); i++) {
obj = prop_array_get(a, i); prop_array_get_cstring_nocopy(a, i, &str);
fprintf(stderr, " * Missing binary package for: %s\n", fprintf(stderr, " * Missing binary package for: %s\n", str);
prop_string_cstring_nocopy(obj)); }
}
static void
show_conflicts(prop_array_t a)
{
size_t i;
const char *str;
fprintf(stderr, "xbps-bin: conflicting packages were found:\n");
for (i = 0; i < prop_array_count(a); i++) {
prop_array_get_cstring_nocopy(a, i, &str);
fprintf(stderr, " %s\n", str);
} }
} }
@ -350,7 +360,7 @@ remove_pkg(const char *pkgname, bool recursive)
int int
exec_transaction(bool yes, bool dry_run, bool show_download_urls) exec_transaction(bool yes, bool dry_run, bool show_download_urls)
{ {
prop_array_t mdeps; prop_array_t mdeps, cflicts;
struct transaction *trans; struct transaction *trans;
struct xbps_handle *xhp = xbps_handle_get(); struct xbps_handle *xhp = xbps_handle_get();
int rv = 0; int rv = 0;
@ -366,6 +376,11 @@ exec_transaction(bool yes, bool dry_run, bool show_download_urls)
/* missing packages */ /* missing packages */
show_missing_deps(mdeps); show_missing_deps(mdeps);
goto out; goto out;
} else if (rv == EAGAIN) {
/* conflicts */
cflicts = prop_dictionary_get(xhp->transd, "conflicts");
show_conflicts(cflicts);
goto out;
} }
xbps_dbg_printf("Empty transaction dictionary: %s\n", xbps_dbg_printf("Empty transaction dictionary: %s\n",
strerror(errno)); strerror(errno));

View File

@ -56,7 +56,7 @@
*/ */
#define XBPS_PKGINDEX_VERSION "1.5" #define XBPS_PKGINDEX_VERSION "1.5"
#define XBPS_API_VERSION "20120609" #define XBPS_API_VERSION "20120611"
#define XBPS_VERSION "0.16" #define XBPS_VERSION "0.16"
/** /**

View File

@ -181,6 +181,12 @@ void HIDDEN xbps_set_cb_state(xbps_state_t, int, const char *,
*/ */
int HIDDEN xbps_unpack_binary_pkg(prop_dictionary_t); int HIDDEN xbps_unpack_binary_pkg(prop_dictionary_t);
/**
* @private
* From lib/package_conflicts.c
*/
void HIDDEN xbps_pkg_find_conflicts(struct xbps_handle *, prop_dictionary_t);
__END_DECLS __END_DECLS
#endif /* !_XBPS_API_IMPL_H_ */ #endif /* !_XBPS_API_IMPL_H_ */

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 += package_unpack.o package_requiredby.o package_register.o
OBJS += transaction_commit.o transaction_package_replace.o OBJS += transaction_commit.o transaction_package_replace.o
OBJS += transaction_dictionary.o transaction_sortdeps.o transaction_ops.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.o plist_archive_entry.o plist_find.o plist_match.o
OBJS += plist_remove.o plist_fetch.o util.o util_hash.o OBJS += plist_remove.o plist_fetch.o util.o util_hash.o
OBJS += repository_finddeps.o cb_util.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; continue;
} }
} }
/*
* Check if package has matched conflicts.
*/
xbps_pkg_find_conflicts(xhp, curpkgd);
/* /*
* Package is on repo, add it into the transaction dictionary. * Package is on repo, add it into the transaction dictionary.
*/ */

View File

@ -190,7 +190,7 @@ out:
int HIDDEN int HIDDEN
xbps_transaction_init(struct xbps_handle *xhp) xbps_transaction_init(struct xbps_handle *xhp)
{ {
prop_array_t unsorted, mdeps; prop_array_t unsorted, mdeps, conflicts;
if (xhp->transd != NULL) if (xhp->transd != NULL)
return 0; return 0;
@ -218,6 +218,16 @@ xbps_transaction_init(struct xbps_handle *xhp)
xhp->transd = NULL; xhp->transd = NULL;
return EINVAL; 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; return 0;
} }
@ -225,7 +235,7 @@ xbps_transaction_init(struct xbps_handle *xhp)
int int
xbps_transaction_prepare(void) xbps_transaction_prepare(void)
{ {
prop_array_t mdeps; prop_array_t mdeps, conflicts;
struct xbps_handle *xhp = xbps_handle_get(); struct xbps_handle *xhp = xbps_handle_get();
int rv = 0; int rv = 0;
@ -239,6 +249,13 @@ xbps_transaction_prepare(void)
if (prop_array_count(mdeps) > 0) if (prop_array_count(mdeps) > 0)
return ENODEV; 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. * Check for packages to be replaced.
*/ */
@ -266,9 +283,10 @@ xbps_transaction_prepare(void)
return rv; 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, "missing_deps");
prop_dictionary_remove(xhp->transd, "conflicts");
prop_dictionary_make_immutable(xhp->transd); prop_dictionary_make_immutable(xhp->transd);
return 0; 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) if ((rv = xbps_transaction_init(xhp)) != 0)
goto out; 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 * Prepare required package dependencies and add them into the
* "unsorted" array in transaction dictionary. * "unsorted" array in transaction dictionary.
*/ */
if ((rv = xbps_repository_find_pkg_deps(xhp, pkg_repod)) != 0) 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 * Set package state in dictionary with same state than the
* package currently uses, otherwise not-installed. * package currently uses, otherwise not-installed.