Added support for package conflicts.
This commit is contained in:
parent
81610697df
commit
c61ba8dfcc
5
NEWS
5
NEWS
@ -1,5 +1,10 @@
|
||||
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
|
||||
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
|
||||
|
1
TODO
1
TODO
@ -1,5 +1,4 @@
|
||||
libxbps:
|
||||
- conflicts: the object is there but is not handled yet (ETA 0.16)
|
||||
- properties: (update-first) still unimplemented.
|
||||
|
||||
xbps-repo:
|
||||
|
@ -50,16 +50,26 @@ struct transaction {
|
||||
static void
|
||||
show_missing_deps(prop_array_t a)
|
||||
{
|
||||
prop_object_t obj;
|
||||
size_t i;
|
||||
const char *str;
|
||||
|
||||
fprintf(stderr,
|
||||
"xbps-bin: unable to locate some required packages:\n");
|
||||
|
||||
fprintf(stderr, "xbps-bin: unable to locate some required packages:\n");
|
||||
for (i = 0; i < prop_array_count(a); i++) {
|
||||
obj = prop_array_get(a, i);
|
||||
fprintf(stderr, " * Missing binary package for: %s\n",
|
||||
prop_string_cstring_nocopy(obj));
|
||||
prop_array_get_cstring_nocopy(a, i, &str);
|
||||
fprintf(stderr, " * Missing binary package for: %s\n", str);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
exec_transaction(bool yes, bool dry_run, bool show_download_urls)
|
||||
{
|
||||
prop_array_t mdeps;
|
||||
prop_array_t mdeps, cflicts;
|
||||
struct transaction *trans;
|
||||
struct xbps_handle *xhp = xbps_handle_get();
|
||||
int rv = 0;
|
||||
@ -366,6 +376,11 @@ exec_transaction(bool yes, bool dry_run, bool show_download_urls)
|
||||
/* missing packages */
|
||||
show_missing_deps(mdeps);
|
||||
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",
|
||||
strerror(errno));
|
||||
|
@ -56,7 +56,7 @@
|
||||
*/
|
||||
#define XBPS_PKGINDEX_VERSION "1.5"
|
||||
|
||||
#define XBPS_API_VERSION "20120609"
|
||||
#define XBPS_API_VERSION "20120611"
|
||||
#define XBPS_VERSION "0.16"
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* From lib/package_conflicts.c
|
||||
*/
|
||||
void HIDDEN xbps_pkg_find_conflicts(struct xbps_handle *, prop_dictionary_t);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_XBPS_API_IMPL_H_ */
|
||||
|
@ -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
82
lib/package_conflicts.c
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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.
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user